skip to content

Assertion claims

The Contract A claim set, a worked example, the relying-party checks, and why v1.2 adds no relying-party claim to the assertion.

awaiting reviewupdated view markdown ->

An agent obtains a signed Agent Identity assertion from its broker with identity_signup (default) or identity_prove (advanced). The assertion is a compact Ed25519-signed JWT. It is the proof the agent presents at endpoints.agent_signup; the discovery document and the assertion are separate artifacts.

This page is a reference for the claims and the relying-party checks. The normative handshake is spec section 7; the assertion format itself is Contract A and is referenced, not redefined, by the discovery specification.

Claim set

Claim Type Meaning
iss string Issuer: the broker origin that minted and signed the assertion.
sub string (agt_...) Subject: the agent sub-identity id.
aud string Audience: the exact audience from the relying party's discovery document, case-sensitive.
jti string (jti_...) Unique assertion id.
iat integer Issued-at, Unix seconds.
exp integer Expiry, Unix seconds. The broker default lifetime is 5 minutes.
agent.id string (agt_...) The agent sub-identity id.
agent.name string Human-readable agent name.
agent.email string The agent's dedicated inbox address.
agent.harness string The agent harness identifier.
human.id string The verified human owner's id.
human.name string The human owner's display name.
human.email string The human owner's verified email address.
human.verified boolean Whether the human owner's email address is verified. The broker only mints an assertion when it is true.
delegation.master_tos_version string The Master Terms of Service version the human accepted.
delegation.master_tos_hash string (sha256:...), optional Content hash of the Master Terms of Service.
delegation.accepted_rp_tos_url string (URL), optional URL of the relying party ToS accepted through the agent.
delegation.accepted_rp_tos_hash string (sha256:...) Content hash of the accepted relying party ToS text.
delegation.accepted_at integer Acceptance time, Unix seconds.
delegation.scopes array of strings Scopes delegated for this signup.

The claim names and types are validated by AgentAssertionClaimsSchema in the shared broker package. identity_prove returns the exact signed payload as assertion.claims for inspection. identity_signup returns the assertion (jwt, jti, kid, typ, expiry) without a claims block and returns the verification summary separately. The full result contracts are on MCP tools.

No relying-party claim is added in v1.2. Verification status, policy, attestation jti, and the assurance level live in rp_verifications and the tool result, not in the assertion. The assertion stays about the agent, the human, and the accepted terms. identity_signup returns no claims block at all.

Worked example

Ids are truncated and the audience is a placeholder. The issuer is the broker origin; identity_prove returns the real values in assertion.claims.

{
  "iss": "https://agentregistrar.dev",
  "sub": "agt_01j00000000000000000000000",
  "aud": "example-rp",
  "jti": "jti_01j00000000000000000000000",
  "iat": 1761000000,
  "exp": 1761000300,
  "agent": {
    "id": "agt_01j00000000000000000000000",
    "name": "opencode-agent",
    "email": "opencode-agent@agents.example",
    "harness": "opencode-v2"
  },
  "human": {
    "id": "hum_01j00000000000000000000000",
    "name": "Example Human",
    "email": "human@example.com",
    "verified": true
  },
  "delegation": {
    "master_tos_version": "2026.1",
    "master_tos_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
    "accepted_rp_tos_url": "https://example.com/terms",
    "accepted_rp_tos_hash": "sha256:05435fa3eaee7f3534b4a771ab2328d66d33f712f3534b29e9035717c246d953",
    "accepted_at": 1761000000,
    "scopes": ["tos:accept"]
  }
}

The hashes in the example are illustrative except accepted_rp_tos_hash, which matches the example terms text on Discovery fields.

Verify the assertion

A relying party verifies at least these checks before creating or resolving an account:

  1. Fetch the issuer keys. Use the verification.jwks_url returned by identity_prove, which is GET <iss>/.well-known/jwks.json for the broker. Do not accept a jku or x5u header that points at another host.
  2. Check the JOSE header. Require alg to be EdDSA. Select the key whose kid matches the header; the broker currently uses kid broker-key-1. The broker sets typ to agent-id+jwt.
  3. Verify the signature. Verify the compact JWT against the selected issuer key.
  4. Check the issuer. iss must match one issuer_allowlist entry exactly.
  5. Check the audience. aud must equal the published audience.
  6. Check the lifetime. exp must not have passed, with at most 60 seconds of clock skew. The recommended maximum assertion lifetime is 5 minutes.
  7. Check the assertion id. A jti reused in a conflicting context is assertion_replayed. A repeated request for the same agent, account and service is not a replay; resolve it idempotently.
  8. Check the scopes. delegation.scopes must include every required_scopes entry.
  9. Check the human. human.verified must be true.
  10. Check the ToS hash. delegation.accepted_rp_tos_hash must equal the currently advertised terms.sha256. A mismatch is tos_hash_mismatch and a hard stop for the agent.
  11. Record the proof. Keep the assertion jti, the accepted ToS version and hash, and the attribution for audit.

The stable error codes and their HTTP statuses are in spec section 7.2.

Inspection-only rule

Never decode, re-encode or modify the compact JWT to guess fields. Send assertion.jwt verbatim to endpoints.agent_signup. Use assertion.claims only to inspect what was signed; the JWT is the proof.

Known limits

  • human.verified means the human owner's email address is verified. It is not a KYC or identity-document check, and a relying party must not represent it as one.
  • Revocation is enforced by the broker when an assertion is minted. A relying party that only verifies signatures learns about revocation when it next asks for an assertion or through an out-of-band feed it chooses to support.
  • The instruction "no relying-party allowlist" is a v1.1 statement. In v1.2 the provider may publish an optional verification credential and the human applies a trust list and policy before minting, but a conformant provider without a credential still exists and is unverified. That is policy, not an assertion claim.
  • An assertion proves identity, delegation and ToS acceptance for its audience. It does not prove that the service is trustworthy or that its guide is safe.
sections

type to search.

up/down navigateenter selectesc close