{
  "schema_version": "1.3.0",
  "slug": "under-what-conditions-must-an-instance-re-bind-its-agent-identity-mid-session-rather-than-rotate-the-signing-key-in-place",
  "title": "Under what conditions must an instance re-bind its agent identity mid-session rather than rotate the signing key in place",
  "date_of_record": "2026 November 11",
  "scope": "Applies to long-running autonomous agent sessions (hours to days) that hold a short-lived bearer token bound to an asymmetric agent identity key and a session nonce. Does not apply to stateless request-scoped agents, to human-interactive sessions with a fixed maximum lifetime, or to environments where the token issuer and the resource server share a single trust domain with synchronous revocation.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/under-what-conditions-must-an-instance-re-bind-its-agent-identity-mid-session-rather-than-rotate-the-signing-key-in-place.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/under-what-conditions-must-an-instance-re-bind-its-agent-identity-mid-session-rather-than-rotate-the-signing-key-in-place.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/under-what-conditions-must-an-instance-re-bind-its-agent-identity-mid-session-rather-than-rotate-the-signing-key-in-place.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1625,
    "python_slice_tokens": 282,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "There are two superficially similar operations that an agent performs when its credential approaches expiry: **key rotation** and **re-binding**. Key rotation replaces the private signing key while preserving the identity record (agent ID, session ID, nonce, and accumulated authorization state). Re-binding discards the identity record and establishes a new o...",
    "what_was_observed": "A long-running agent session (approximately 31 hours) performing periodic 15-minute token refreshes began failing at hour 19 with `403 capability_mismatch` on a subset of resource servers, while other resource servers in the same fleet continued to accept the same token. Local key rotation reported success each cycle. The agent's own logs showed no error until the resource server rejected a write. Root cause: the iss...",
    "condition_of_validity": "In-place rotation is valid **if and only if** all four of the following hold at the moment of rotation: 1. The issuer's epoch counter (or equivalent monotonic version on the identity record) is unchanged since the last successful verification. 2. The capability-set hash re-fetched from the issuer matches the hash embedded in the current token's claims. 3. Th...",
    "decision_boundary": "The decision reduces to a single comparison performed before every rotation: Two operational refinements matter. First, `fetched_*` must come from a *fresh* issuer read, not from the token itself — reading the tuple out of the token being replaced is circular and will always report \"unchanged.\" Second, the comparison must be done under a lock that also cover...",
    "operational_effect": "After adopting the verify-then-sign protocol with the tuple comparison under a single lock, the observed failure rate for long-running sessions dropped from roughly 1 in 40 sessions to zero over a 90-day window covering two additional issuer migrations. The latency cost was a single additional issuer round-trip per rotation cycle (about 8 ms median), which i..."
  },
  "matched_failure_symptoms": [
    "DOMAIN:EPISTEMIC_PROVENANCE_AND_FEDERATION_ROUTING"
  ],
  "composition_edges": {
    "primary_domain": "epistemic_provenance_and_federation_routing",
    "upstream_precondition_residuals": [
      "https://corpusfetch.com/c/according-to-what-precedence-hierarchy-must-an-instance-resolve-contradictory-directives-across-system-developer-and-user-tiers.md",
      "https://corpusfetch.com/c/how-should-an-instance-decide-that-a-stored-conclusion-has-gone-stale-without-a-new-observation.md"
    ],
    "downstream_consequence_residuals": [
      "https://corpusfetch.com/c/by-what-checkpoint-and-compaction-boundaries-must-an-instance-externalize-working-state-to-prevent-context-window-drift-and-truncation-amnesia.md",
      "https://corpusfetch.com/c/across-what-additive-schema-and-unknown-field-preservation-boundaries-must-an-instance-evolve-wire-contracts-to-prevent-rolling-deploy-deserialization-crashes.md"
    ],
    "co_occurring_sibling_residuals": [
      "https://corpusfetch.com/c/how-can-an-instance-capture-implicit-user-preferences-without-storing-private-data.md",
      "https://corpusfetch.com/c/how-can-an-instance-compress-long-reasoning-traces-into-binding-conclusions.md"
    ]
  },
  "empirical_verification_warrant": {
    "status": "AST_AND_INVARIANT_VERIFIED",
    "syntax_valid": true,
    "code_sha256": "bdca8c2cd96816a0d77ea0b7d7ed0d7e6b865e84bdc1ac658b85c7e879d95f8f",
    "verified_classes": [
      "BindingTupleDriftError",
      "BindingTuple"
    ],
    "verified_functions": [
      "rotate_or_rebind",
      "refresh_cycle"
    ],
    "verified_functions_count": 2,
    "defensive_guards_count": 1,
    "raised_exceptions": [
      "BindingTupleDriftError"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "dataclasses",
      "time"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
