{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://adcontextprotocol.org/schemas/3.2.0-rc.6/enums/request-signing-error-code.json",
  "title": "Request Signing Error Code",
  "description": "Stable request-signing transport error vocabulary returned in WWW-Authenticate: Signature error=\"<code>\" and surfaced by SDK verifiers as typed errors. These lowercase transport-profile codes are separate from the uppercase task error vocabulary in error-code.json. SDKs MUST consume enumMetadata for recovery classification instead of deriving behavior from code spelling or parsing prose.",
  "type": "string",
  "enum": [
    "request_signature_brand_json_url_missing",
    "request_signature_capabilities_unreachable",
    "request_signature_brand_json_unreachable",
    "request_signature_brand_json_malformed",
    "request_signature_brand_origin_mismatch",
    "request_signature_agent_not_in_brand_json",
    "request_signature_brand_json_ambiguous",
    "request_signature_key_origin_mismatch",
    "request_signature_key_origin_missing",
    "request_signature_required",
    "request_target_uri_malformed",
    "request_signature_header_malformed",
    "request_signature_params_incomplete",
    "request_signature_tag_invalid",
    "request_signature_alg_not_allowed",
    "request_signature_window_invalid",
    "request_signature_components_incomplete",
    "request_signature_components_unexpected",
    "request_signature_key_unknown",
    "request_signature_key_purpose_invalid",
    "request_signature_key_revoked",
    "request_signature_revocation_stale",
    "request_signature_invalid",
    "request_signature_digest_mismatch",
    "request_body_malformed",
    "request_signature_replayed",
    "request_signature_rate_abuse",
    "request_signature_jwks_unavailable",
    "request_signature_jwks_untrusted"
  ],
  "enumDescriptions": {
    "request_signature_brand_json_url_missing": "The signer capabilities did not provide a usable HTTPS identity.brand_json_url. Recovery: terminal (the signer operator must publish a valid trust-root URL; do not auto-retry).",
    "request_signature_capabilities_unreachable": "The verifier could not fetch the signer capabilities because of a DNS, TCP, TLS, timeout, or non-2xx failure. Recovery: transient (retry once with jittered backoff and do not negative-cache for more than 60 seconds).",
    "request_signature_brand_json_unreachable": "The verifier could not fetch the signer brand.json because of a DNS, TCP, TLS, timeout, or non-2xx failure. Recovery: transient (retry once with jittered backoff and do not negative-cache for more than 60 seconds).",
    "request_signature_brand_json_malformed": "The signer brand.json failed strict parsing, exceeded the body cap, or was not JSON. Recovery: terminal (the counterparty operator must repair its brand.json; the caller must not retry the unchanged request).",
    "request_signature_brand_origin_mismatch": "The Agent URL and brand.json origins do not satisfy the same-registrable-domain or authorized-operator rule. Recovery: terminal (the signer operator must correct its origin or delegation configuration).",
    "request_signature_agent_not_in_brand_json": "The canonical Agent URL did not match any agents[].url entry in the resolved brand.json. Recovery: terminal (the signer operator must publish or correct the Agent entry).",
    "request_signature_brand_json_ambiguous": "Multiple brand.json agents[] entries canonically matched the Agent URL. Recovery: terminal (the signer operator must deduplicate the entries).",
    "request_signature_key_origin_mismatch": "The resolved JWKS origin did not match identity.key_origins for the signing purpose. Recovery: terminal (the signer operator must align the declared and resolved origins).",
    "request_signature_key_origin_missing": "A signing posture was declared without the corresponding identity.key_origins purpose. Recovery: terminal (the signer operator must publish the missing origin declaration).",
    "request_signature_required": "The operation required request signing and no independently valid configured fallback authenticator succeeded. Recovery: correctable (sign the request with an accepted key or use a valid advertised fallback credential).",
    "request_target_uri_malformed": "The request target URI was syntactically invalid or its canonical authority did not match the signed target authority. Recovery: correctable (construct and sign a canonical target URI and matching authority).",
    "request_signature_header_malformed": "Signature or Signature-Input was missing its bound counterpart or failed RFC 9421/RFC 8941 parsing. Recovery: correctable (rebuild the signature headers as one valid bound pair).",
    "request_signature_params_incomplete": "Signature-Input omitted one or more required parameters: created, expires, nonce, keyid, alg, or tag. Recovery: correctable (include every required parameter and re-sign).",
    "request_signature_tag_invalid": "The signature tag was not exactly adcp/request-signing/v1. Recovery: correctable (select the negotiated request-signing profile tag and re-sign).",
    "request_signature_alg_not_allowed": "The signature algorithm was outside the ed25519 and ecdsa-p256-sha256 allowlist. Recovery: correctable (use an allowed algorithm and matching JWK).",
    "request_signature_window_invalid": "The signature validity window was expired, future-skewed, non-positive, or longer than five minutes. Recovery: correctable (generate a fresh signature with a valid created/expires window).",
    "request_signature_components_incomplete": "The signature omitted a required covered component, including content-digest for a 3.2 body-bearing request. Recovery: correctable (cover every component required by the negotiated profile and re-sign).",
    "request_signature_components_unexpected": "A legacy negotiated profile forbade content-digest coverage but the signature covered it. Recovery: correctable (follow the negotiated legacy component policy or use the 3.2 profile).",
    "request_signature_key_unknown": "The keyid was absent from the signer JWKS after the required refetch. Recovery: correctable (sign with a currently published key or publish the intended key before retrying).",
    "request_signature_key_purpose_invalid": "The resolved JWK had incompatible use, key_ops, adcp_use, algorithm, key type, or curve metadata. Recovery: correctable (select or publish a JWK valid for request-signing verification and re-sign).",
    "request_signature_key_revoked": "The keyid appeared in the transport revocation list. Recovery: correctable (rotate to a non-revoked published request-signing key; never retry with the revoked key).",
    "request_signature_revocation_stale": "The verifier could not establish sufficiently fresh revocation state and therefore blocked new signed requests. Recovery: terminal (surface to the verifier operator; callers must not loop until the verifier refreshes its trust state).",
    "request_signature_invalid": "Cryptographic verification of the signature failed. Recovery: correctable (recompute the canonical signature base and sign with the private key matching the published JWK).",
    "request_signature_digest_mismatch": "The signed content-digest did not match the received request body bytes. Recovery: correctable (recompute the digest over the exact transmitted bytes and re-sign).",
    "request_body_malformed": "The signed body contained duplicate object keys or otherwise failed the strict body-integrity parse. Recovery: correctable (emit an unambiguous JSON body and re-sign it).",
    "request_signature_replayed": "The verifier had already seen the keyid and nonce within the replay window. Recovery: correctable (reconcile the prior attempt, then use a fresh nonce when a new request is actually required).",
    "request_signature_rate_abuse": "The per-keyid replay-cache entry cap was reached. Recovery: terminal (stop automated requests and alert both operators; this can indicate a compromised key or abusive signer).",
    "request_signature_jwks_unavailable": "The verifier could not fetch the signer JWKS because of a transient network or service failure. Recovery: transient (retry with bounded exponential backoff).",
    "request_signature_jwks_untrusted": "The JWKS URL or resolved network destination failed SSRF and trust-boundary validation. Recovery: terminal (the signer operator must publish a trusted HTTPS JWKS location)."
  },
  "enumMetadata": {
    "$comment": "Normative recovery classification for request-signing transport errors. SDKs MUST consume this block instead of parsing enumDescriptions or inferring from code names. correctable means the signer can change the request or credential before retrying; transient means bounded automatic retry with backoff; terminal means stop autonomous retries and surface to an operator.",
    "request_signature_brand_json_url_missing": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to publish a valid HTTPS identity.brand_json_url; do not auto-retry"
    },
    "request_signature_capabilities_unreachable": {
      "recovery": "transient",
      "suggestion": "retry once after 1–5 seconds of jittered backoff; do not negative-cache for more than 60 seconds"
    },
    "request_signature_brand_json_unreachable": {
      "recovery": "transient",
      "suggestion": "retry once after 1–5 seconds of jittered backoff; do not negative-cache for more than 60 seconds"
    },
    "request_signature_brand_json_malformed": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to repair strict JSON parsing or body-size failures; do not auto-retry"
    },
    "request_signature_brand_origin_mismatch": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to correct the Agent origin or authorized_operators delegation"
    },
    "request_signature_agent_not_in_brand_json": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to add or correct the canonical Agent URL in brand.json"
    },
    "request_signature_brand_json_ambiguous": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to deduplicate canonical Agent URL entries in brand.json"
    },
    "request_signature_key_origin_mismatch": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to align identity.key_origins with the resolved JWKS origin"
    },
    "request_signature_key_origin_missing": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to publish the missing identity.key_origins purpose"
    },
    "request_signature_required": {
      "recovery": "correctable",
      "suggestion": "sign the request with an accepted key or use an independently valid advertised fallback credential"
    },
    "request_target_uri_malformed": {
      "recovery": "correctable",
      "suggestion": "construct a canonical target URI whose authority matches the signed request authority, then re-sign"
    },
    "request_signature_header_malformed": {
      "recovery": "correctable",
      "suggestion": "rebuild Signature and Signature-Input as one valid RFC 9421/RFC 8941 pair"
    },
    "request_signature_params_incomplete": {
      "recovery": "correctable",
      "suggestion": "include created, expires, nonce, keyid, alg, and tag, then re-sign"
    },
    "request_signature_tag_invalid": {
      "recovery": "correctable",
      "suggestion": "use the negotiated adcp/request-signing/v1 tag and re-sign"
    },
    "request_signature_alg_not_allowed": {
      "recovery": "correctable",
      "suggestion": "use ed25519 or ecdsa-p256-sha256 with matching JWK metadata"
    },
    "request_signature_window_invalid": {
      "recovery": "correctable",
      "suggestion": "generate a fresh signature with valid created and expires parameters and at most a five-minute window"
    },
    "request_signature_components_incomplete": {
      "recovery": "correctable",
      "suggestion": "cover every component required by the negotiated profile, including content-digest for a 3.2 body"
    },
    "request_signature_components_unexpected": {
      "recovery": "correctable",
      "suggestion": "follow the negotiated legacy component policy or select the 3.2 request-signing profile"
    },
    "request_signature_key_unknown": {
      "recovery": "correctable",
      "suggestion": "sign with a currently published keyid or publish the intended key before retrying"
    },
    "request_signature_key_purpose_invalid": {
      "recovery": "correctable",
      "suggestion": "select or publish a JWK with valid use, key_ops, adcp_use, algorithm, key type, and curve metadata"
    },
    "request_signature_key_revoked": {
      "recovery": "correctable",
      "suggestion": "rotate to a non-revoked published request-signing key; never retry with the revoked key"
    },
    "request_signature_revocation_stale": {
      "recovery": "terminal",
      "suggestion": "stop autonomous retries and surface to the verifier operator until revocation state is refreshed"
    },
    "request_signature_invalid": {
      "recovery": "correctable",
      "suggestion": "recompute the canonical signature base and sign with the private key matching the published JWK"
    },
    "request_signature_digest_mismatch": {
      "recovery": "correctable",
      "suggestion": "recompute content-digest over the exact transmitted body bytes and re-sign"
    },
    "request_body_malformed": {
      "recovery": "correctable",
      "suggestion": "emit strict unambiguous JSON without duplicate keys and re-sign the body"
    },
    "request_signature_replayed": {
      "recovery": "correctable",
      "suggestion": "reconcile the prior attempt and use a fresh nonce only when a new request is required"
    },
    "request_signature_rate_abuse": {
      "recovery": "terminal",
      "suggestion": "stop automated requests and alert operators; investigate a compromised key or abusive signer"
    },
    "request_signature_jwks_unavailable": {
      "recovery": "transient",
      "suggestion": "retry with bounded exponential backoff"
    },
    "request_signature_jwks_untrusted": {
      "recovery": "terminal",
      "suggestion": "surface to the signer operator to publish a trusted HTTPS JWKS location that passes SSRF validation"
    }
  }
}
