Skip to main content
Glama

verify_receipt

Read-only

Verify a CodeRifts signed chain-receipt you ALREADY HOLD: cryptographic authenticity (signature + key id), body binding, and — when lifecycle indices are available — whether it is currently valid authorization (not expired, superseded, or revoked) for a stated operation/target.

Use this when:

  • You already obtained a chain_receipt / receipt token from a prior preflight (or CI artifact) and are about to act (merge/deploy) under that receipt.

  • A contract-gate or policy requires offline/online proof that the receipt is authentic for this change before proceeding.

  • You must distinguish "signature ok" from "currently authorized" (stale or superseded receipts must not be treated as live approval).

Do not use when:

  • You do not have a receipt yet — call coderifts.preflight_change_set first.

  • You need a NEW decision for a changed base→head set — preflight again; verify_receipt does not re-diff specs.

  • The receipt you hold binds a different operation or target than the one you are about to perform — call coderifts.preflight_change_set with context.operation set to that operation (a merge receipt does not authorize a deploy); verify_receipt cannot re-scope or re-issue a decision.

  • You only need human-readable history of an old decision_id without a receipt token — use coderifts.get_decision_details.

  • The change set itself is unknown or incomplete — fix the change set and preflight; do not "verify" a placeholder.

Inputs: receipt token (required); optional intended context (operation, environment, fingerprint, target_id, audience, repository/branch/pull_request, base/head) and the body_hash-bound decision_result envelope. 30s clock-skew leeway on expiry. A 0s grace for declared destructive production operations is defined in the policy but is unreachable today: the intended-context schema has no destructive field, so nothing can declare one and the 30s leeway always applies. Returns { valid, status, currently_authorized (bool|null), reason, payload, authz_* }. Branch on currently_authorized; null = not evaluated.

When a decision envelope is also in hand (e.g. from a prior preflight), its control_envelope.next_agent_step (if present) is structured remediation guidance the agent MAY follow after a non-CONTINUE decision — still branch on execution_action; next_agent_step is suggestion, not permission.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
baseNoIntended base commit/ref SHA the receipt must match (signed-wins vs envelope.base)
headNoIntended head commit/ref SHA the receipt must match (signed-wins vs envelope.head)
tokenYesThe chain receipt token (base64url(body).base64url(signature))
branchNoIntended branch the receipt must bind (place binding; optional)
audienceNoIntended audience — must match the receipt
operationNoIntended operation the receipt must authorize (conventional: merge|deploy|tool_call|publish). Triggers authorization evaluation when non-empty; supply decision_result for full scope binding.
target_idNoIntended apply-site target the receipt must bind
repositoryNoIntended repository the receipt must bind (place binding; optional)
environmentNoIntended environment (e.g. production) — must match the receipt
fingerprintNoIntended change fingerprint — must equal the receipt fp
pull_requestNoIntended pull-request id the receipt must bind (place binding; optional)
decision_resultNoThe body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent. Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
validYestrue iff status is VERIFIED_CURRENT or RETIRED_KEY_VALID_AT_ISSUE
reasonNo
statusYes
payloadNo
authz_noteNoPresent when no intended context supplied: status reflects signature+expiry only
authz_stateNoLifecycle state from isCurrentlyAuthorized when authorization is evaluated (optional; omitted when currently_authorized is null)
authz_reasonNoWhen currently_authorized=false: the deny reason (operation_mismatch, decision_not_allow, superseded, expired, target_mismatch, environment_mismatch, …)
authz_statusNoAuthorization-level status (VERIFIED_WRONG_ENVIRONMENT / VERIFIED_SUPERSEDED / VERIFIED_SCOPE_MISMATCH / …)
caller_valueNoCaller claim that differed from the signed envelope
signed_valueNoSigned envelope slot when signed-wins fail-closed (source_binding_mismatch)
binding_levelNoplace_and_content | content_only — forensic, not a second verdict
correlation_idNoRoute-owned trace id, set by the route itself rather than by correlation middleware; always a non-empty string on 200
currently_authorizedYesWhether the receipt currently authorizes the intended operation/target/fp (§106). null means authorization could not be evaluated (e.g. no intended context) — not unauthorized and not authorized.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / decision_result / properties / blast_radius / description
      Previous value: -"ID27 additive COUNTS (not a score). Not permission."New value: +"Additive COUNTS (not a score). Not permission."
  2. Changed1 schema field changed
    • changedOutput schema / properties / correlation_id / description
      Previous value: -"Route-owned trace id (ID828); always a non-empty string on 200"New value: +"Route-owned trace id, set by the route itself rather than by correlation middleware; always a non-empty string on 200"
  3. Changed2 schema fields changed
    • changedInput schema / properties / decision_result / properties / authority / description
      Previous value: -"ID963 additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL."New value: +"Additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL."
    • changedInput schema / properties / decision_result / properties / derivation / description
      Previous value: -"ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint."New value: +"Additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint."
  4. Changed1 schema field changed
    • changedOutput schema / properties / status / enum
      Previous value: -[
      -  "VERIFIED_CURRENT",
      -  "VERIFIED_EXPIRED",
      -  "VERIFIED_WRONG_AUDIENCE",
      -  "VERIFIED_WRONG_ENVIRONMENT",
      -  "VERIFIED_SUPERSEDED",
      -  "VERIFIED_SCOPE_MISMATCH",
      -  "UNKNOWN_KEY",
      -  "RETIRED_KEY_VALID_AT_ISSUE",
      -  "INVALID_SIGNATURE",
      -  "MALFORMED",
      -  "UNSUPPORTED_VERSION",
      -  "REGISTRY_UNREACHABLE"
      -]New value: +[
      +  "VERIFIED_CURRENT",
      +  "VERIFIED_EXPIRED",
      +  "VERIFIED_WRONG_AUDIENCE",
      +  "VERIFIED_WRONG_ENVIRONMENT",
      +  "VERIFIED_SUPERSEDED",
      +  "VERIFIED_SCOPE_MISMATCH",
      +  "VERIFIED_UNBOUND_OPERATION",
      +  "VERIFIED_UNBOUND_TARGET",
      +  "VERIFIED_UNBOUND_REPOSITORY",
      +  "VERIFIED_UNBOUND_BRANCH",
      +  "VERIFIED_UNBOUND_PULL_REQUEST",
      +  "UNKNOWN_KEY",
      +  "UNKNOWN_KEY_STATUS",
      +  "RETIRED_KEY_VALID_AT_ISSUE",
      +  "KEY_RETIRED_AFTER_SIGNING",
      +  "REVOKED_KEY",
      +  "REVOKED_KEY_UNDECIDABLE",
      +  "KEY_REVOKED",
      +  "REVOCATION_UNDECIDABLE",
      +  "AUTHORIZATION_UNDECIDABLE",
      +  "INVALID_SIGNATURE",
      +  "MALFORMED",
      +  "UNSUPPORTED_VERSION",
      +  "REGISTRY_UNREACHABLE"
      +]
  5. Changed1 schema field changed
    • changedInput schema / properties / decision_result / properties / derivation / description
      Previous value: -"ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source: github_compare, base_sha, head_sha }. Covered by body_hash; not fingerprint."New value: +"ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint."
  6. Changed1 schema field changed
    • addedInput schema / properties / decision_result / properties / derivation
      Added value: +{
      +  "description": "ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source: github_compare, base_sha, head_sha }. Covered by body_hash; not fingerprint.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  7. Changed2 schema fields changed
    • addedInput schema / properties / decision_result / properties / audience
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / decision_result / properties / authority
      Added value: +{
      +  "description": "ID963 additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  8. Changed1 schema field changed
    • addedInput schema / properties / decision_result / properties / blast_radius
      Added value: +{
      +  "description": "ID27 additive COUNTS (not a score). Not permission.",
      +  "properties": {
      +    "consumers_declared": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "consumers_observed": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "endpoints": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "fields": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "graph_source": {
      +      "type": "string"
      +    },
      +    "params": {
      +      "minimum": 0,
      +      "type": "integer"
      +    }
      +  },
      +  "type": "object"
      +}
  9. Changed4 schema fields changed
    • changedInput schema / description
      Previous value: -"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."New value: +"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, repository/branch/pull_request, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."
    • addedInput schema / properties / branch
      Added value: +{
      +  "description": "Intended branch the receipt must bind (place binding; optional)",
      +  "type": "string"
      +}
    • addedInput schema / properties / pull_request
      Added value: +{
      +  "description": "Intended pull-request id the receipt must bind (place binding; optional)",
      +  "oneOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "number"
      +    }
      +  ]
      +}
    • addedInput schema / properties / repository
      Added value: +{
      +  "description": "Intended repository the receipt must bind (place binding; optional)",
      +  "type": "string"
      +}
  10. Changed2 schema fields changed
    • changedInput schema / properties / decision_result / description
      Previous value: -"The body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent."New value: +"The body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent. Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json."
    • addedInput schema / properties / decision_result / properties
      Added value: +{
      +  "base": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "decision": {
      +    "enum": [
      +      "ALLOW",
      +      "WARN",
      +      "REQUIRE_APPROVAL",
      +      "BLOCK"
      +    ],
      +    "type": "string"
      +  },
      +  "decision_body_hash": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "decision_id": {
      +    "type": "string"
      +  },
      +  "environment": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "execution_action": {
      +    "enum": [
      +      "CONTINUE",
      +      "CONTINUE_WITH_MONITORING",
      +      "REQUEST_APPROVAL",
      +      "STOP"
      +    ],
      +    "type": "string"
      +  },
      +  "expires_at": {
      +    "type": "string"
      +  },
      +  "fingerprint": {
      +    "type": "string"
      +  },
      +  "head": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "input_fingerprint": {
      +    "type": "string"
      +  },
      +  "operation": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "receipt": {
      +    "type": "object"
      +  },
      +  "repository": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "safe_for_agent": {
      +    "type": "boolean"
      +  },
      +  "spec_version": {
      +    "pattern": "^decision-result\\.v1(\\.[0-9]+)?$",
      +    "type": "string"
      +  }
      +}
  11. Changed3 schema fields changed
    • changedInput schema / description
      Previous value: -"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, and/or audience) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."New value: +"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."
    • addedInput schema / properties / base
      Added value: +{
      +  "description": "Intended base commit/ref SHA the receipt must match (signed-wins vs envelope.base)",
      +  "type": "string"
      +}
    • addedInput schema / properties / head
      Added value: +{
      +  "description": "Intended head commit/ref SHA the receipt must match (signed-wins vs envelope.head)",
      +  "type": "string"
      +}
  12. Changed4 schema fields changed
    • addedOutput schema / properties / binding_level
      Added value: +{
      +  "description": "place_and_content | content_only — forensic, not a second verdict",
      +  "type": "string"
      +}
    • addedOutput schema / properties / caller_value
      Added value: +{
      +  "description": "Caller claim that differed from the signed envelope",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / correlation_id
      Added value: +{
      +  "description": "Route-owned trace id (ID828); always a non-empty string on 200",
      +  "type": "string"
      +}
    • addedOutput schema / properties / signed_value
      Added value: +{
      +  "description": "Signed envelope slot when signed-wins fail-closed (source_binding_mismatch)",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  13. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give readOnlyHint/openWorldHint; the description adds substantial non-obvious behavior: 30s clock-skew leeway, a 0s destructive-op grace that is unreachable today, fail-closed authorization when the envelope is absent, branching guidance ('branch on currently_authorized; null = not evaluated'), and the warning that next_agent_step is suggestion not permission. This goes well beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is long but front-loaded with the purpose sentence, then cleanly partitioned into when/when-not/inputs/returns/warnings with no filler. The paragraph on the unreachable 0s destructive grace is arguably over-detailed, keeping it just below a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter tool with nested objects, two evaluation modes, and an output schema, the description covers mode semantics, required-vs-optional inputs, return fields, and interpretation guidance. Nothing an agent needs to call it correctly appears missing, and the return explanation is a bonus beyond the existing output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3; the description adds meaning beyond the schema by explaining mode selection (token-only = SIGNATURE, context+envelope = AUTHORIZATION), the fail-closed failure mode, and that operation 'triggers authorization evaluation when non-empty'. It stops short of describing individual context fields, which is acceptable given the rich schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Verify) and clearly bounded resource (a CodeRifts signed chain-receipt you ALREADY HOLD), with the crucial scope qualifier 'already hold' that separates it from preflight. It explicitly names the sibling alternatives (preflight_change_set, get_decision_details) and the conditions under which they, not this tool, apply.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit 'Use this when' and 'Do not use when' blocks with concrete routing: no receipt yet -> preflight_change_set; changed base→head -> preflight again; different operation/target -> re-scope via preflight; history only -> get_decision_details. This is exactly the when/when-not/alternatives structure that earns a top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources