Skip to content

Authority freshness: treat a change in authority state as an input to trust freshness - #375

Merged
rampyg merged 11 commits into
mainfrom
feat/authority-freshness
Aug 1, 2026
Merged

Authority freshness: treat a change in authority state as an input to trust freshness#375
rampyg merged 11 commits into
mainfrom
feat/authority-freshness

Conversation

@rampyg

@rampyg rampyg commented Aug 1, 2026

Copy link
Copy Markdown
Member

Description

Makes a change in authority state a first-class input to trust freshness, alongside elapsed time and the consequence of the action.

An authority publishes a signed AuthorityState credential carrying a monotonic authorityEpoch and a status. SessionVouchers and heartbeat requests record the epoch they were minted under, and for an action that calls for state freshness a verifier refuses a voucher minted under an older epoch, even when its time-decay trust still passes. A timestamp says when a voucher was minted and never whether authority has changed since, so time alone forces a verifier to guess a safe staleness window. A new epoch is proof that a real transition occurred.

The epoch comparison is local and needs no network call at action time. The top consequence tier stops trusting cached state entirely and requires a live M-of-N co-sign read at the moment of the action, because a cached epoch cannot cover the gap between the last refresh and this action.

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Documentation update

Related Issues

Closes #374

Changes Made

  • AuthorityState build and verify in the Rust core, mirrored to Python, TypeScript, Go, and WebAssembly, signed with eddsa-jcs-2022.
  • SessionVoucher and heartbeat requests carry authorityEpoch; the heartbeat validator tracks the highest epoch it has seen per authority.
  • A consequence-to-policy map and the epoch-collapse rule in the verify path, with stable reason codes such as authority_epoch_stale:seen=7,voucher=5 that are byte-identical across languages.
  • The top tier wires to the existing FROST co-sign, verified as a standard Ed25519 signature so verifiers need no threshold code.
  • A shared interop vector at test-vectors/authority-state/, proving a proof built in one language verifies in the others, that a stale-epoch proof is rejected everywhere, and that all five implementations reach identical freshness verdicts.
  • Distribution surfaces updated together: the FAQ, the help guides, the home and tools pages, the demos page, the knowledge base, the Claude skill, the custom GPT, the Gem, and the MCP server.
  • examples/authority_freshness_demo.py alongside the other demo companions.
  • Contributor credential minting can now attest a design contribution, so someone whose design a change implements can be credited without the credential claiming they wrote the code.

Testing

  • Existing tests pass (pytest tests/)
  • New tests added for new functionality
  • Manual testing performed

Python 1339 passed, Rust 168 plus interop, TypeScript 397, Go signer suite, MCP 20, and the WebAssembly smoke test at 20 including reproducing the shared vector's proof value in the browser core. The website static export builds.

Checklist

  • My code follows the project's code style
  • I have added/updated documentation as needed
  • I have added tests for new functionality
  • All tests pass locally
  • My commits are signed off (DCO)

Credit

The design behind this change did not originate in the repository. It came out of a public discussion with Sudip Chatterjee (@aiconsulting4future), who made two specific contributions: he argued that freshness must be a function of both elapsed time and authority state change, with the consequence of the action setting the threshold, rather than time-decay alone; and he supplied the driving scenario of an autonomous treasury or trading agent whose authority is valid at one moment and, seconds later, is overtaken by a fraud signal, a suspended mandate, or a breached exposure limit, leaving a credential that stays cryptographically valid while no longer representing current authority. He observed that in those cases the acceptable stale window collapses toward zero. That framing is the reason this feature exists. The code here was written in this repository; the design is credited to that discussion, and the feature commit carries a Co-authored-by trailer.

Once this merges, the Verified Contributor credential for that design contribution is minted by running the Verified Contributor credential workflow with the design inputs, which is the path added in this pull request for crediting someone who did not author the commits:

gh workflow run verified-contributor.yml \
  -f pr_number=PR_NUMBER \
  -f design_subject=aiconsulting4future \
  -f design_contribution="Argued that trust freshness must be a function of both elapsed time and authority state change, with the consequence of the action setting the threshold, and supplied the treasury and trading scenario where a credential stays cryptographically valid while no longer representing current authority."

rampyg and others added 11 commits July 29, 2026 03:11
…ss input

Add an AuthorityState credential carrying a monotonic authorityEpoch and a
status, signed with eddsa-jcs-2022. SessionVouchers and heartbeat requests now
record the epoch they were minted under, and the heartbeat validator tracks the
highest epoch it has seen per authority.

verify_agent_call takes a consequence tier and, for state-freshness tiers,
rejects a voucher minted under a stale epoch even when its time-decay trust
still passes. The critical tier requires a live M-of-N co-sign read at action
time, verified as a standard Ed25519 signature.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
Co-authored-by: Sudip Chatterjee <263618491+aiconsulting4future@users.noreply.github.com>
…rror to Go

Add the canonical AuthorityState build/verify and the epoch-collapse rule to
core/vouch-core, and mirror them in the Go sidecar. Both share a new interop
vector in test-vectors/authority-state/ generated from Python: a proof built in
one language verifies in another, a stale-epoch tamper is rejected everywhere,
and every language reaches the same freshness verdict.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
…hared vector

Port AuthorityState and the epoch-collapse rule to the TypeScript SDK, verified
against the shared interop vector so it agrees byte-for-byte with the Rust core,
Go, and Python.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
Add an Authority freshness section to the demos experience: a toggle fires an
authority-state transition, and the same time-valid voucher that is accepted for
a routine action is rejected for a state-freshness action, with the critical
tier falling back to a live M-of-N co-sign. Add the plain-English explainer to
docs and the README.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
The unknown-epoch reason code rendered differently in each language because each
printed its own null value. Render an absent epoch as "?" everywhere so the
string is identical across Python, the Rust core, TypeScript, and Go, and pin
both unknown-epoch cases in the shared interop vector so it cannot drift again.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
Add the AuthorityState build, sign, verify, and freshness-evaluation bindings to
the WASM core so a browser runs the same operations as the native SDKs. The
smoke test reproduces the shared interop vector's proof value in the browser
core and matches every freshness case.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
…e example

Add sign_authority_state, matching the signer-based one-call form the other
credential builders offer, so publishing a state does not need the raw key by
hand. Add examples/authority_freshness_demo.py alongside the other demo
companions, showing a voucher whose decayed trust still passes being refused
once the authority state moves.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
Add tools to publish a signed authority state, verify one, and apply the
freshness gate to an action, so an MCP client can use the capability without
writing code against the SDK directly.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
Add the capability to the FAQ, the help guides, the home and tools pages, the
knowledge base, the Claude skill, the custom GPT, and the Gem, so each one
describes it the same way: freshness is time and state and consequence, the
epoch comparison is local, and the top tier reads a live quorum co-sign.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
…he design

Add the rationale for the epoch to the design doc, the demo copy, and the verify
path: a timestamp says when a voucher was minted and never whether authority has
changed since, so time alone forces a guess at a safe window, while a new epoch
is proof that a real transition happened. The design doc credits the discussion
the framing and the treasury scenario came from.

Support attesting a design contribution when minting a contributor credential,
so someone whose design a change implements can be credited accurately without
the credential claiming they wrote the code.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
Name the GitHub account behind the design credit in the specification, the
changelog, and the demo section, so the acknowledgement points somewhere.

Signed-off-by: Ramprasad Gaddam <groups.rampy1@gmail.com>
Vouch-DID: did:vouch:be434c6279c0
@rampyg
rampyg merged commit 717a5af into main Aug 1, 2026
18 checks passed
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Vouch Verified Contributor ✨

Thank you @aiconsulting4future. The design this pull request implements came from you, and that earns a signed
Vouch Verified Contributor certificate, chained to the project root authority.

Vouch Verified Contributor

Your certificate (download and share it): https://vouch-protocol.com/c/aiconsulting4future/375

Add the badge to your profile or site (optional):

[![Vouch Verified Contributor](https://img.shields.io/badge/Vouch-Verified_Contributor-7C2D3A?style=for-the-badge&labelColor=2d2d2d)](https://vouch-protocol.com/c/aiconsulting4future/375)
Your Verifiable Credential (eddsa-jcs-2022)
{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://vouch-protocol.com/contexts/v1"
  ],
  "id": "urn:uuid:25af0415-4062-4776-88fd-9df9baf04671",
  "type": [
    "VerifiableCredential",
    "VouchCredential"
  ],
  "issuer": "did:web:vouch-protocol.com:contributors",
  "validFrom": "2026-08-01T19:45:27Z",
  "validUntil": "2126-07-08T19:45:27Z",
  "credentialSubject": {
    "id": "did:web:vouch-protocol.com:contributors",
    "vouchVersion": "1.0",
    "intent": {
      "action": "attest",
      "target": "github:aiconsulting4future",
      "resource": "https://github.com/vouch-protocol/vouch/pull/375",
      "role": "design-contributor",
      "repository": "vouch-protocol/vouch",
      "contributionType": "design",
      "implementedIn": 375,
      "contribution": "Argued that trust freshness must be a function of both elapsed time and authority state change, with the consequence of the action setting the threshold, and supplied the treasury and trading scenario where a credential stays cryptographically valid while no longer representing current authority."
    },
    "delegationChain": [
      {
        "issuer": "did:web:vouch-protocol.com",
        "subject": "did:web:vouch-protocol.com:contributors",
        "intent": {
          "action": "attest",
          "target": "github:aiconsulting4future",
          "resource": "https://github.com/vouch-protocol/vouch/pull/375",
          "role": "design-contributor",
          "repository": "vouch-protocol/vouch",
          "contributionType": "design",
          "implementedIn": 375,
          "contribution": "Argued that trust freshness must be a function of both elapsed time and authority state change, with the consequence of the action setting the threshold, and supplied the treasury and trading scenario where a credential stays cryptographically valid while no longer representing current authority."
        },
        "validFrom": "2026-06-19T04:45:43Z",
        "validUntil": "2036-06-16T04:45:43Z",
        "parentProofValue": "z5g1N4udQdy5asdxnV3qFhApB5cAh28DkMqHjEUSNG6cc8hrDDsxWyVbgn1XXUFR"
      }
    ]
  },
  "proof": {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-jcs-2022",
    "created": "2026-08-01T19:45:27Z",
    "verificationMethod": "did:web:vouch-protocol.com:contributors#key-1",
    "proofPurpose": "assertionMethod",
    "proofValue": "z4barz5UTC8s1SEwDLWqLATs4m82M8Rh3yVJkUAksYEkYPKD8nEtb2iwz2p3L3qkbyGQAchyhxsoQ1rftY46mecd5"
  }
}

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.

Authority freshness: state change as a first-class input to trust freshness

1 participant