Problem
The training agent currently emits an opaque UUID as governance_context (see server/src/training-agent/governance-handlers.ts:1040). The 3.0 spec (#2306, signed-governance-context changeset) requires governance agents to emit a compact JWS per the AdCP JWS profile, and #2455 now adds plan_hash as a required claim in that profile.
The training agent is the reference implementation the certification track points learners at. A learner reading docs/governance/campaign/tasks/check_governance.mdx sees the JWS contract; a learner stepping through the training agent sees a UUID. That gap bites both implementer onboarding (what does a real token look like?) and conformance (the training agent can't be used as a test vector source for the JWS profile).
Scope
Upgrade the training agent to emit a fully conformant compact JWS:
- Key management: issue a training Ed25519 keypair (
alg: EdDSA), publish the JWKS at a well-known path reachable from the training harness, rotate-by-kid.
- Claims:
iss, sub (plan_id), aud (seller URL from the caller context), iat, exp, jti (UUID v7), phase, caller, check_id, media_buy_id (conditional), policy_decision_hash (optional), and plan_hash (required per this PR's closed exclusion list).
- Canonicalization:
plan_hash = base64url_no_pad(SHA-256(JCS(plan_payload))) with the excluded-fields list applied in code, not via convention.
- Revocation list: publish a signed
governance-revocations.json at the training origin (empty body is fine; the presence is required so the conformance ramp-up tests can verify fetch-and-parse).
- Reference tests: golden-vector tests that round-trip the training agent's output through the reference TypeScript verifier in
docs/building/implementation/security.mdx.
Why separate from #2455
#2455 was a spec-only change (claim definition). Upgrading the training agent to JWS is a larger implementation effort — new key material, new signing path, new verifier tests, new conformance storyboards. Rolling them together would have bloated the spec PR and delayed the ecosystem-signal that plan_hash is normative in 3.0.
Out of scope
- Production governance-agent key management (vendor concern).
- 3.1 step 16 seller verification (separate issue).
Problem
The training agent currently emits an opaque UUID as
governance_context(seeserver/src/training-agent/governance-handlers.ts:1040). The 3.0 spec (#2306, signed-governance-context changeset) requires governance agents to emit a compact JWS per the AdCP JWS profile, and #2455 now addsplan_hashas a required claim in that profile.The training agent is the reference implementation the certification track points learners at. A learner reading
docs/governance/campaign/tasks/check_governance.mdxsees the JWS contract; a learner stepping through the training agent sees a UUID. That gap bites both implementer onboarding (what does a real token look like?) and conformance (the training agent can't be used as a test vector source for the JWS profile).Scope
Upgrade the training agent to emit a fully conformant compact JWS:
alg: EdDSA), publish the JWKS at a well-known path reachable from the training harness, rotate-by-kid.iss,sub(plan_id),aud(seller URL from the caller context),iat,exp,jti(UUID v7),phase,caller,check_id,media_buy_id(conditional),policy_decision_hash(optional), andplan_hash(required per this PR's closed exclusion list).plan_hash = base64url_no_pad(SHA-256(JCS(plan_payload)))with the excluded-fields list applied in code, not via convention.governance-revocations.jsonat the training origin (empty body is fine; the presence is required so the conformance ramp-up tests can verify fetch-and-parse).docs/building/implementation/security.mdx.Why separate from #2455
#2455 was a spec-only change (claim definition). Upgrading the training agent to JWS is a larger implementation effort — new key material, new signing path, new verifier tests, new conformance storyboards. Rolling them together would have bloated the spec PR and delayed the ecosystem-signal that plan_hash is normative in 3.0.
Out of scope