1-SEC contributors · Reviewed · Module: auth_fortress
Agent Token Reuse: Revocation Signals and Observed Token Activity
Auth Fortress remembers identifiers from reported logout/revocation events and revocation-signaled authentication failures.
What 1-SEC checks
Auth Fortress remembers identifiers from reported logout/revocation events and revocation-signaled authentication failures. A later token-usage or JWT-validation event with the same identifier produces a revoked-token-reuse alert. For token_usage and api_key_usage events that do not match a remembered revocation, the module also tracks reported token IDs, source IPs and action history to surface multi-IP or unusual-action signals.
Required telemetry and context
Relevant input events: logout, token_revocation, token_usage, api_key_usage, jwt_validation, token_event, auth_failure. Use a trusted producer at the real application boundary.
jti / token_idclaims (JSON string containing jti) / token (JWT with jti)usernameactionreason / status (revocation context)source_ip (event envelope)
Field names above describe relevant context, not a complete API request. Consult the current event contract for envelope and detail requirements. Preserve booleans, numbers, and strings as the receiving handler expects them. Agent-provided text cannot independently verify identity or authorization.
Deployment, prevention, and response
Emit verified logout/revocation and validation context from the actual authentication service and use a stable non-secret identifier consistently. Enforce expiry, signature, issuer, audience and revocation in that service or gateway. Reproduce a revocation event followed by an inert validation event in a lab, then confirm the real resource server independently refuses a revoked credential. Correlate agent, principal and connection from trusted application context rather than model-provided labels.
Record the source event, affected agent/host, actual target, policy decision, and response result. Review enforcement configuration separately from detection. A recommendation, selected action, dry-run record, and completed action are different outcomes.
Reproduce the source fixtures
From a checkout of the linked 1-SEC source revision, run the selected fixtures with the repository's Go toolchain. These commands run tests; they do not execute a real attack against your systems.
go test ./internal/modules/auth -run '^(TestFortress_HandleEvent_RevokedJWTReuse|TestFortress_HandleEvent_AuthFailureRevokesToken|TestOAuthMonitor_TrackTokenUsage_MultiIP|TestOAuthMonitor_TrackTokenUsage_AnomalousAction)$' -count=1Synthetic handler fixtures establish remembered-revocation alerting, including identifiers extracted from claims. Activity helper fixtures cover multi-IP and new-action signals. They are not a live OAuth resource-server revocation or enforcement test.
TestFortress_HandleEvent_RevokedJWTReuse
Full fixture and assertions — run in its original package with its helpers.
func TestFortress_HandleEvent_RevokedJWTReuse(t *testing.T) {
cp := makeCapturingPipeline()
f := startedModuleWithPipeline(t, cp)
defer f.Stop()
logout := core.NewSecurityEvent("test", "logout", core.SeverityInfo, "logout")
logout.Details["jti"] = "revoked-jti-1"
logout.Details["username"] = "alice"
f.HandleEvent(logout)
reuse := core.NewSecurityEvent("test", "jwt_validation", core.SeverityInfo, "jwt validation")
reuse.Details["jti"] = "revoked-jti-1"
reuse.Details["username"] = "alice"
reuse.SourceIP = "10.0.0.1"
f.HandleEvent(reuse)
if !cp.hasAlertType("token_reuse_post_logout") {
t.Error("expected token_reuse_post_logout alert for reused revoked JWT")
}
}TestFortress_HandleEvent_AuthFailureRevokesToken
Full fixture and assertions — run in its original package with its helpers.
func TestFortress_HandleEvent_AuthFailureRevokesToken(t *testing.T) {
cp := makeCapturingPipeline()
f := startedModuleWithPipeline(t, cp)
defer f.Stop()
fail := core.NewSecurityEvent("test", "auth_failure", core.SeverityInfo, "token revoked")
fail.Details["reason"] = "session revoked after logout"
fail.Details["claims"] = `{"sub":"alice","jti":"claims-jti-7"}`
f.HandleEvent(fail)
reuse := core.NewSecurityEvent("test", "token_usage", core.SeverityInfo, "token replay")
reuse.Details["claims"] = `{"sub":"alice","jti":"claims-jti-7"}`
reuse.SourceIP = "10.0.0.8"
f.HandleEvent(reuse)
if !cp.hasAlertType("token_reuse_post_logout") {
t.Error("expected token_reuse_post_logout alert after revocation-signaled auth failure")
}
}TestOAuthMonitor_TrackTokenUsage_MultiIP
Full fixture and assertions — run in its original package with its helpers.
func TestOAuthMonitor_TrackTokenUsage_MultiIP(t *testing.T) {
om := NewOAuthMonitor()
om.TrackTokenUsage("token-1", "10.0.0.1", "alice", "read")
om.TrackTokenUsage("token-1", "10.0.0.2", "alice", "read")
result := om.TrackTokenUsage("token-1", "10.0.0.3", "alice", "read")
if !result.MultiIPUsage {
t.Error("expected MultiIPUsage with 3+ IPs")
}
if result.IPCount < 3 {
t.Errorf("IPCount = %d, want >= 3", result.IPCount)
}
if result.OriginalIP != "10.0.0.1" {
t.Errorf("OriginalIP = %q, want %q", result.OriginalIP, "10.0.0.1")
}
}TestOAuthMonitor_TrackTokenUsage_AnomalousAction
Full fixture and assertions — run in its original package with its helpers.
func TestOAuthMonitor_TrackTokenUsage_AnomalousAction(t *testing.T) {
om := NewOAuthMonitor()
// Build up 6 known actions
actions := []string{"read", "list", "search", "view", "download", "export"}
for _, a := range actions {
om.TrackTokenUsage("token-2", "10.0.0.1", "alice", a)
}
// New action after 5+ known actions
result := om.TrackTokenUsage("token-2", "10.0.0.1", "alice", "delete_all")
if !result.AnomalousAction {
t.Error("expected AnomalousAction for new action after 5+ known actions")
}
}Tuning, evaluation, and coverage limits
Monitoring an identifier is not cryptographic JWT verification, provider-side token revocation or inline denial. No matching identifier means no revocation match; process restarts, bounded state and missed events limit history. Shared egress, proxies and legitimate new actions affect activity heuristics. Arbitrary token reuse before revocation is not automatically malicious, and this module does not bind token audiences or make an opaque bearer token safe.
Evaluate this behavior with representative authorized activity and a controlled known-positive case. Investigate the exact rule, inputs, and state before suppressing an alert. Do not assume a hard-coded heuristic is a configurable setting. Measure your own deployment; the source fixtures do not establish a benchmark, detection rate, compliance certification, or incident-prevention claim.
Protocol and format references
These references describe the underlying format or protocol. The implementation and fixtures above define the subset 1-SEC actually checks.
Related implemented controls
- Agent Output Secrets: API-Key Patterns, JWT Shapes and Leak Limits
- Agent Delegation Records: Verified Claims, Expiry and Scope Limits
- Connected Accounts: Link, Delegated Usage and Revocation Signals
- Agent Token Exchange: Audit Counters, Failure Signals and Scope Changes
- Agent OAuth Consent: Scope Accumulation and Grant-Rate Signals
- Service Account Misuse: Activity Volume and Baseline Limits