Signals and Revocation
CAE signals for real-time token revocation — 7 signal types (session_revoked, identity_compromised, tool_abuse_detected, etc.), client.signals.ingest(), and how signals interact with tokens.session().
Tokens have a finite lifetime, but trust can be lost before a token expires. Continuous Access Evaluation (CAE) signals give you a way to communicate that something has changed — immediately — without waiting for the next token refresh cycle.
The Problem with Relying on TTL Alone
Short TTLs reduce the blast radius of a compromised credential. But they do not eliminate it. A 15-minute token can still cause damage for 15 minutes after you discover a problem. In a multi-agent system, that window multiplies across every active session.
CAE signals close that window. When you ingest a signal against an identity, ZeroID marks its sessions as inactive. Any downstream service that verifies the token via introspection will immediately see active: false instead of the cached valid state, regardless of when the token expires.
This lets you move from "wait for expiry" to "revoke now, enforce everywhere."
Signal Types
Each signal type describes a specific kind of event. Use the most specific type that matches your situation.
session_revoked
You want to explicitly end an active session immediately. Use for emergency shutdowns, forced logouts, or after detecting a breach.
credential_change
A key has been rotated, a secret has been updated, or credentials associated with the identity have changed. Signals that existing tokens may no longer reflect the current credential state.
ip_change
The identity is operating from an unexpected IP address or network. Use to flag out-of-policy network behavior.
anomalous_behavior
The identity is behaving in a way that deviates from its baseline — unusual request volume, unexpected scope usage, or timing anomalies.
policy_violation
The identity attempted or performed something that violates its defined operating policy. Use after a policy enforcement event.
retirement
The identity is being decommissioned. Signals that no new sessions should be accepted and existing ones should be wound down.
owner_change
The human or system entity responsible for this identity has changed. Use when an agent changes hands or its controlling principal is updated.
Severity Levels
Every signal carries a severity that downstream consumers can use to calibrate their response.
low
Informational. Something changed, but no immediate action is required.
medium
Warrants investigation or monitoring. Active sessions may continue under watch.
high
Warrants immediate review. Consider suspending or restricting the identity.
critical
Treat as a breach or emergency. Revoke immediately.
ZeroID does not automatically take different actions based on severity — it records the signal and marks sessions appropriately. Severity is a signal to your system and operators.
Ingesting a Signal
Python
TypeScript
What Happens After a Signal Is Ingested
When ZeroID receives a signal:
The signal is recorded against the identity.
Active sessions for that identity are marked inactive.
Token introspection for any token belonging to that identity returns
active: false.The signal is available in the identity's event history for audit purposes.
Propagation is immediate within ZeroID. There is no polling delay between signal ingestion and the change in introspection behavior. The gap is whatever latency exists between your downstream service calling introspection and ZeroID processing the signal — typically sub-second.
Tokens themselves are not modified or deleted. They are not invalidated at the JWT level. What changes is the state that introspection reflects. Downstream services that rely on local JWT signature verification only (without calling introspection) will not see the revocation. See the section on common mistakes below.
How Downstream Services Should Respond
The correct pattern for a downstream service receiving a token from an agent:
Verify the JWT signature using the JWKS endpoint.
Check the standard JWT claims (expiry, issuer, audience).
For sensitive operations, call token introspection and check that
active: true.On any
401 Unauthorizedresponse from a resource server, re-verify via introspection before retrying.
When introspection returns active: false, the downstream service should:
reject the request
return
401 Unauthorizedto the callernot cache the valid result from a previous introspection call
The session.active field on a retrieved session object reflects the same state. If you are building an orchestrator that holds references to sub-agent sessions, check session.active before dispatching work to a sub-agent. Do not assume a session you opened earlier is still valid.
REST Example
Practical Patterns
Emergency Shutdown
Use when you need an identity stopped immediately — breach suspected, runaway agent, or unexpected behavior at production scale.
Deactivating the identity prevents new token issuance. The signal terminates existing sessions. Both steps are needed for a complete shutdown.
Suspicious Behavior — Monitor Mode
Use when you want to flag an identity for closer inspection without immediately terminating it. Ingest a signal at medium or high severity, but do not revoke the session. This leaves the identity running while giving your monitoring systems a signal to increase scrutiny.
Your downstream services or monitoring layer can read this signal from the event history and apply stricter rate limiting or logging without forcing a re-auth cycle.
Key Rotation Event
Use when a credential backing an identity has been rotated. Existing tokens were issued under the old key. Ingesting a credential_change signal tells downstream systems to re-verify those tokens rather than trust cached state.
After this signal, any downstream service calling introspection on a token issued before the rotation will get active: false. The agent will need to re-authenticate to receive a token issued under the new key.
Agent Retirement
Use when decommissioning an identity permanently. The retirement signal communicates intent to other services and audit consumers. Pair it with deactivate to enforce it.
Signal before deactivating so that downstream systems that consume the event history have a record of the intent, not just the state change.
Common Mistakes
Avoid:
Relying only on token expiry for revocation. A 15-minute TTL is not a revocation mechanism. If you discover a problem at minute zero, you still have a 15-minute exposure window. Ingest a signal immediately.
Verifying tokens only via local JWT signature checks. Local verification confirms the signature is valid. It does not check whether the session is still active. For any sensitive operation, call introspection.
Caching introspection results for too long. If you cache a
active: trueresult for several minutes, you have recreated the TTL problem at a different layer. Keep introspection cache TTLs short, or skip caching entirely for high-value operations.Not checking
session.activebefore dispatching to sub-agents. In orchestrator patterns, sessions you opened for sub-agents can be revoked while your orchestrator is still running. Always checksession.activebefore dispatching new work.Ingesting signals without a meaningful
source. Thesourcefield is part of the audit record. A value like"my-service"is more useful than"unknown"when you are tracing an incident after the fact.Skipping the
retirementsignal and deactivating directly. Deactivation changes state without explanation. Theretirementsignal provides context to audit consumers and downstream systems that may be reading the event history.
What's Next?
Continue to Downstream Authorization to understand how services should enforce policy once they have verified a token.
Revisit Credential Policies to constrain what tokens can be issued in the first place.
Last updated