Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .changeset/gcp-kms-request-signing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
---

feat(addie): GCP KMS-backed Ed25519 signing for outbound AdCP requests

Addie's outbound AdCP calls (`AdCPClient.executeTask`) now attach an RFC 9421
request-signing block backed by a GCP KMS Ed25519 key when `GCP_SA_JSON` and
`GCP_KMS_KEY_VERSION` are set. Private key material never enters process
memory; signing routes through the `SigningProvider` interface added in
`@adcp/client@5.20.0`.

Verifiers fetch the public key from `${BASE_URL}/.well-known/jwks.json`
(kid: `aao-signing-2026-04`). The committed `expected-public-key.ts` is the
single source of truth for both the published JWKS and the boot-time
tripwire that asserts the KMS-returned public key matches the repo —
silent key swaps in GCP fail loudly rather than producing signatures
verifiers reject.

Webhook signing in the training agent still uses an in-process JWK; lifting
that to KMS is a follow-up that needs a `SigningProvider` integration in
`@adcp/client`'s `createWebhookEmitter`.
17 changes: 17 additions & 0 deletions .changeset/revert-kms-eager-init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
---

fix(boot): drop GCP KMS eager-init at boot

The eager-init added in #3283 took down the prod deploy: when KMS auth is
misconfigured, the gRPC client retries forever inside `getPublicKey`, the app
never binds port 8080, and Fly's health-check times out without surfacing the
underlying KMS error.

Lazy init in `getGcpKmsSigningProvider()` is the safer default — a broken
signing path fails per-call (logged + generic message to LLM via the
call-site try/catch in `adcp-tools.ts`) while the rest of the server boots
normally so operators can SSH in and inspect.

Re-enabling eager init needs either a hard timeout on the `getPublicKey`
round-trip or a deploy-time probe outside the boot critical path.
Loading
Loading