Skip to content

v0.2: CyclesEvidence envelope signer-key resolution (signature authenticity, did:cycles / JWKS, key rotation) #103

@amavashev

Description

@amavashev

Tracking issue for the CyclesEvidence envelope signer-key resolution work — the v0.2 deliverable that aeoess/agent-passport-system#43 (envelope-authenticity verification) is implicitly waiting on, and which is not currently enumerated in the v0.2 follow-up tracker (#94).

Why this is its own issue

drafts/cycles-evidence-v0.1.yaml (#90) already specifies envelope signing (Ed25519 over JCS bytes, evidence_id populated / signature empty — schema description "Signature derivation", normative) and a signer_did field. But it explicitly defers signer-key resolution to v0.2:

Out of scope (v0.1): Signing-key rotation, JWKS publication, did:cycles method registration. These will land alongside or after the normative move to cycles-evidence-v0.2.yaml. (cycles-evidence-v0.1.yaml, lines 71–73)

signer_did … v0.1 does not pin a method; an Ed25519 hex pubkey is the simplest valid form. A future spec revision will likely standardize on did:cycles:<server_id_hash> or similar once signing-key rotation and JWKS publication are in scope. (lines 188–196)

#94 tracks three v0.2 follow-ups (system_attributes population, replay_class promotion, normative-spec promotion) — none of which is signer-key resolution. So the dependency APS#43 needs has had no Cycles-side home. This issue is that home.

The distinction that scopes the work

There are two separable guarantees, with very different cost:

  • (a) Signature validity — the envelope's Ed25519 signature verifies against the key named in signer_did. The v0.1 draft already fully specifies this (derivation + verification, "Verification" section). It needs no new Cycles infrastructuresigner_did is self-describing (a hex pubkey today).
  • (b) Signer authority / trust anchoring — proof that signer_did is genuinely the legitimate Cycles signer, not an attacker's key embedded in a forged self-consistent envelope. (a) without (b) is not authenticity — a forger embeds their own key and self-signs. This is the half that needs did:cycles / JWKS.

APS#43's interim guidance ("pin expected_signer") is exactly the manual form of (b): pinning supplies the trust anchor, so (a) + expected_signer = full authenticity for the pinned-issuer case, shippable today without any of the infra below. The work in this issue automates (b) for the unpinned / multi-issuer / long-horizon-archival cases.

v0.2 deliverables

  1. Signer-key publication mechanism. Decide and spec one of:
    • JWKS endpoint on the Cycles server (server_id-relative, e.g. /.well-known/cycles-jwks.json), Ed25519 keys (OKP/Ed25519); and/or
    • a did:cycles:<server_id_hash> method whose DID document carries the verification key(s).
  2. signer_did method pinning. Promote signer_did from "hex pubkey or anything" to a resolvable form, while keeping the raw-hex form valid for pinned/offline consumers.
  3. Key rotation + history. server_id is deliberately distinct from signer_did precisely so a server can rotate keys without losing identity continuity (v0.1 lines 180–184). Resolution must therefore expose retired keys, keyed so a verifier can select the key that was valid at issued_at_ms — "resolve the current key" breaks verification of any envelope signed before a rotation. This is load-bearing for the long-horizon archival use case the v0.1 draft already cites (EU AI Act Art. 12 retention, lines 36–37).
  4. Normative verification text updating the v0.1 "Verification" steps so authenticity = (a) signature-valid against the resolved key and (b) that key is authorized for server_id at issued_at_ms.

Interim guidance (until v0.2 lands)

Matches APS#43: payment-class consumers pin expected_signer for receipt-issuer trust and treat a passing join check (#42) as binding evidence, not authenticity.

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions