@@ -324,6 +324,26 @@ between minor releases. |
| 324 | transcript with `##[group]`/`##[endgroup]` step markers). | 324 | transcript with `##[group]`/`##[endgroup]` step markers). |
| 325 | - **Capabilities:** `actions-artifacts`, `actions-job-logs` added to | 325 | - **Capabilities:** `actions-artifacts`, `actions-job-logs` added to |
| 326 | `/api/v1/meta`. | 326 | `/api/v1/meta`. |
| | 327 | +- **REST: actions secrets + variables (S50 §13 part 3).** |
| | 328 | + New `internal/auth/sealbox` package owns the server's X25519 |
| | 329 | + keypair and exposes NaCl `SealedBox` decode. Clients fetch the |
| | 330 | + public key via |
| | 331 | + `GET /api/v1/repos/{o}/{r}/actions/secrets/public-key` (and the |
| | 332 | + org analog), encrypt the secret value with `crypto_box_seal`, and |
| | 333 | + PUT the base64 ciphertext + key_id. Server validates key_id, |
| | 334 | + decrypts in memory, then re-encrypts with the shared storage |
| | 335 | + AEAD for at-rest persistence — plaintext never reaches postgres. |
| | 336 | + Secrets CRUD: `GET .../secrets`, `GET .../secrets/{name}`, |
| | 337 | + `PUT .../secrets/{name}`, `DELETE .../secrets/{name}`. Variables |
| | 338 | + CRUD (plaintext, `${{ vars.NAME }}` namespace): `GET/POST |
| | 339 | + .../variables`, `GET/PATCH/DELETE .../variables/{name}`. Both |
| | 340 | + surfaces have repo- and org-scoped variants. Operator setup: |
| | 341 | + `SHITHUB_ACTIONS__SECRETS__BOX_PRIVATE_KEY_B64` carries the |
| | 342 | + X25519 private key (32 bytes base64); unset means |
| | 343 | + auto-generated-per-process with a loud warning at startup, which |
| | 344 | + is dev-only behavior. |
| | 345 | +- **Capabilities:** `actions-secrets`, `actions-variables` added to |
| | 346 | + `/api/v1/meta`. |
| 327 | | 347 | |
| 328 | ### Added (internal) | 348 | ### Added (internal) |
| 329 | | 349 | |