Skip to content

spec(evidence): add getEvidenceJwks endpoint + JWK Set schemas (v0.1.25.6)#113

Merged
amavashev merged 1 commit into
mainfrom
feat/evidence-jwks-endpoint
Jun 15, 2026
Merged

spec(evidence): add getEvidenceJwks endpoint + JWK Set schemas (v0.1.25.6)#113
amavashev merged 1 commit into
mainfrom
feat/evidence-jwks-endpoint

Conversation

@amavashev

Copy link
Copy Markdown
Contributor

What

Spec-first step for the v0.2 signer-key-resolution reference implementation (cycles-server impl follows in a separate PR). Adds the JWK Set publication endpoint to the authoritative runtime spec so the implementation has spec authority, per the spec-first rule.

This is the publication half of the additive signer-key-resolution layer whose design was signed off by APS on aeoess#43 and folded into the draft in #112.

Changes — cycles-protocol-v0.yaml (0.1.25.50.1.25.6)

  • New endpoint GET /v1/.well-known/cycles-jwks.json (getEvidenceJwks, security: []). Returns the signer's JWK Set so a consumer can resolve a did:cycles signer_did (or confirm a raw-hex one) to a public key and establish signer authority, not just signature validity.
    • API-base-relative path (server_id already carries /v1), deliberately not origin-rooted — keeps key authority anchored to the base the did:cycles hash commits to (the authority-scope rationale APS endorsed).
    • OPTIONAL to publish — 404 when a server doesn't do signer-key resolution; consumers fall back to raw-hex signer_did + expected_signer pinning (the binding_only posture). Described as optional in prose, marked x-conformance: normative per the convention getBalances already uses (normative surface, optionality in prose).
    • PUBLIC because a JWK Set is public keys only; the private signing key is never served by any endpoint.
  • New schemas CyclesEvidenceJwks / CyclesEvidenceJwk — mirror the draft's required shape, with the normative resolution algorithm deferred to drafts/cycles-evidence-v0.1.yaml (same split CyclesEvidenceEnvelope already uses for getEvidence).
  • Updated the AUTH note (two public endpoints now) and the spec-index wire-surface note.
  • Changelog prepended; merged/cycles-openapi-protocol-merged.yaml regenerated.

Validation

  • spectral: 0 errors (pre-existing warnings only); merged artifact lints clean
  • changelog pointers valid; YAML parses; merged regenerated and committed (no drift)

Review note — file placement

I co-located this with the rest of the evidence wire surface in the runtime base (getEvidence / CyclesEvidenceEnvelope / CyclesEvidenceRef all live there) as a 4th-segment patch bump, consistent with the publication-model's "base changes only via patch bumps." If you'd rather feature endpoints land in cycles-protocol-extensions-v0.1.26.yaml, easy to move — flag it.

Refs: #112, #103, aeoess#43. cycles-server implementation PR to follow against this contract.

…25.6)

Spec-first step for the v0.2 signer-key-resolution reference implementation:
publish the signer's JWK Set so a consumer can resolve a did:cycles signer_did
(or confirm a raw-hex one) to a public key and establish signer AUTHORITY.

cycles-protocol-v0.yaml (0.1.25.5 -> 0.1.25.6, additive 4th-segment bump):
- New public endpoint GET /v1/.well-known/cycles-jwks.json (operationId
  getEvidenceJwks, security: []). API-base-relative path (server_id already
  carries /v1), deliberately NOT origin-rooted — authority stays anchored to the
  base the did:cycles hash commits to. OPTIONAL to publish (404 when a server
  doesn't do signer-key resolution; consumers fall back to raw-hex + expected_signer
  pin). PUBLIC because a JWK Set is public keys only; the private key is never served.
- New CyclesEvidenceJwks / CyclesEvidenceJwk schemas mirroring the draft's required
  shape (same "shape here, normative semantics in drafts/cycles-evidence-v0.1.yaml"
  split that CyclesEvidenceEnvelope already uses for getEvidence).
- Updated the AUTH note (two public endpoints now) + the spec-index wire-surface note.

Changelog prepended; merged/cycles-openapi-protocol-merged.yaml regenerated.
Spectral 0 errors; changelog pointers valid.

Note for review: co-located with the rest of the evidence wire surface in the
runtime base (getEvidence/CyclesEvidenceEnvelope/CyclesEvidenceRef all live here)
as a 4th-segment patch bump, consistent with "base changes only via patch bumps".
Happy to move it to cycles-protocol-extensions-v0.1.26.yaml if you'd prefer
feature endpoints there.
@amavashev amavashev merged commit 34d60da into main Jun 15, 2026
5 checks passed
@amavashev amavashev deleted the feat/evidence-jwks-endpoint branch June 15, 2026 12:42
amavashev added a commit to runcycles/cycles-server that referenced this pull request Jun 15, 2026
…2) (#194)

Publication half of the v0.2 signer-key-resolution layer (design on #103 /
aeoess#43; contract added to cycles-protocol-v0.yaml v0.1.25.6 in
runcycles/cycles-protocol#113).

- JwksController: public GET /v1/.well-known/cycles-jwks.json. Reads the shared
  cycles.evidence.signing.signer-did + new kid / nbf-ms via @value (no injected
  bean, so it loads in every @WebMvcTest without extra wiring). Cache-Control:
  public, max-age=300 — NOT immutable (a key set rotates). 404 via the standard
  NOT_FOUND ErrorResponse when no raw-hex key is configured.
- JwksDocuments: pure builder. Raw 64-hex signer-did -> one active Ed25519 OKP
  JWK {kty,crv,alg,x=base64url(hex-decode(signer_did)),kid (default first-16-hex),
  cycles_nbf_ms (default 0), status:active}; cycles_exp_ms omitted = open-ended.
  The x is the SAME 32 bytes EnvelopeSigner signs with, so a verifier resolving
  the set authenticates the emitted signatures. did:cycles / blank / malformed ->
  empty (404): a did:cycles signer_did carries no key bytes (that + retired-key
  rotation history are the v0.2-store follow-up).
- SecurityConfig: /v1/.well-known/** public (public keys only; private key never
  served; API-base-relative per the authority-scope rule). SecurityConfigTest
  updated for the new entry.
- application.properties: cycles.evidence.signing.kid / nbf-ms. pom .31 -> .32.

Tests: JwksDocumentsTest (10), JwksControllerTest (4, contract-validated against
#113's spec). Both new classes 100% line-covered; full mvn verify 906 green;
jacoco 95% gate met. codex review: no findings. No change to existing endpoints.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant