encryptWithPublicKey encrypts plaintext using NaCl's sealed box construction (Curve25519 + XSalsa20 + Poly1305) as required by GitHub's Actions Secrets API. The encrypted output can only be decrypted by the holder of the private key corresponding to the provided public key. Parameters: - publicKeyB
(publicKeyB64, plaintext string)
| 251 | // |
| 252 | // Returns base64-encoded ciphertext or error. |
| 253 | func encryptWithPublicKey(publicKeyB64, plaintext string) (string, error) { |
| 254 | raw, err := base64.StdEncoding.DecodeString(publicKeyB64) |
| 255 | if err != nil { |
| 256 | return "", fmt.Errorf("decode public key: %w", err) |
| 257 | } |
| 258 | if len(raw) != publicKeySize { |
| 259 | return "", fmt.Errorf("unexpected public key length: %d, expected %d", len(raw), publicKeySize) |
| 260 | } |
| 261 | |
| 262 | pk := (*[publicKeySize]byte)(raw[:publicKeySize]) |
| 263 | ciphertext, err := box.SealAnonymous(nil, []byte(plaintext), pk, rand.Reader) |
| 264 | if err != nil { |
| 265 | return "", fmt.Errorf("nacl encryption failed: %w", err) |
| 266 | } |
| 267 | |
| 268 | return base64.StdEncoding.EncodeToString(ciphertext), nil |
| 269 | } |
| 270 | |
| 271 | func putRepoSecret(client *api.RESTClient, owner, repo, name, keyID, encryptedValue string) error { |
| 272 | path := fmt.Sprintf("repos/%s/%s/actions/secrets/%s", owner, repo, name) |