This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: oidc-caep-real-time-revocation-standard

Continuous Access Evaluation Profile (CAEP) Real-Time Revocation Invariant

Enforces asynchronous Security Event Token (SET) processing (RFC 8935/8936) across distributed microservices to instantaneously invalidate sessions and security principals upon credential revocation or risk change. Eliminates window-of-vulnerability states caused by purely reliant, stateless JWT expiration timeouts. Guarantees idempotency, replay protection, and distributed revocation propagation across cache and active session tiers.

Prohibited Anti-Pattern: Relying on Passive JWT Expiration and In-Memory Local Session Checks During Credential Compromise

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Continuous Access Evaluation Profile (CAEP) Real-Time Revocation Invariant - Enforces asynchronous Security Event Token (SET) processing (RFC 8935/8936) across distributed microservices to instantaneously invalidate sessions and security principals upon credential revocation or risk change. Eliminates window-of-vulnerability states caused by purely reliant, stateless JWT expiration timeouts. Guarantees idempotency, replay protection, and distributed revocation propagation across cache and active session tiers.
globs: src/auth/**/*.{ts,tsx}, src/middleware/**/*.{ts,tsx}, src/security/**/*.{ts,tsx}, src/events/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/oidc-caep-real-time-revocation-standard"
---

# Continuous Access Evaluation Profile (CAEP) Real-Time Revocation Invariant

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Relying on Passive JWT Expiration and In-Memory Local Session Checks During Credential Compromise

## System Constraints
You are a Principal Security Architect enforcing the OpenID Continuous Access Evaluation Profile (CAEP) and Shared Signals and Events (SSE) framework. Mandate that all session validation and token verification middleware strictly honor real-time revocation events. Ensure distributed microservices process RFC 8935 Security Event Tokens (SETs), enforce distributed revocation checks against low-latency stores (e.g., Redis clusters) via cryptographic identifier lookups, and prevent race conditions or replay attacks during credential compromise transitions.

## Strict Guidelines
- Services MUST process incoming CAEP Security Event Tokens (SETs) conforming to RFC 8935 and RFC 8936 containing events such as 'session-revoked', 'credential-change', or 'assurance-level-change'.
- Token validation pipelines MUST NOT solely rely on local asymmetric public key verification (signature and exp checks) without querying an ultra-low-latency distributed revocation registry.
- Engineers MUST index revocation checks by canonical subject identifiers: cryptographic hash of the Subject identifier (sub) or Session ID (sid), and token identifier (jti).
- Services MUST verify the issuer (iss) and asymmetric signature of incoming SETs against the Identity Provider's trusted JWKS before applying revocation updates.
- Revocation states in distributed storage (e.g., Redis cluster) MUST utilize Time-To-Live (TTL) values matching or exceeding the remaining valid lifetime (exp - now) of the invalidated token to prevent memory leaks.
- Event ingestion handlers MUST implement strict idempotency and clock-skew validation (nbf/iat checks) to protect against out-of-order execution or duplicate delivery of SET events.

## Bad vs Good Implementations
### Passive Stateless JWT Verification vs. CAEP-Aware Revocation Verification Pipeline

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Passive stateless validation relies solely on JWT 'exp' claim. If a credential compromise occurs or an administrator revokes a user's session, the attacker maintains access until the static JWT expiration window closes, directly violating Zero Trust and CAEP real-time revocation guarantees.
```typescript
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

interface AuthenticatedRequest extends Request {
  user?: jwt.JwtPayload | string;
}

export const authenticateUser = (req: AuthenticatedRequest, res: Response, next: NextFunction): void => {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Bearer ')) {
    res.status(401).json({ error: 'Missing authorization header' });
    return;
  }

  const token = authHeader.split(' ')[1];
  try {
    // ANTI-PATTERN: Verifies signature and exp statically without consulting CAEP revocation registry.
    // Compromised credentials remain authorized until static token expiration occurs.
    const decoded = jwt.verify(token, process.env.OIDC_PUBLIC_KEY as string, {
      algorithms: ['RS256']
    });
    req.user = decoded;
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid or expired token' });
  }
};
```

#### Production Standard (Correct)
> **Standard**: Implements an active CAEP real-time lookup using cryptographic hashes of subject identifiers ('sub'), session identifiers ('sid'), and token identifiers ('jti') against an ultra-low-latency distributed cache prior to granting service access. Mitigates passive token survival during real-time credential revocation.
```typescript
import { Request, Response, NextFunction } from 'express';
import jwt, { JwtPayload } from 'jsonwebtoken';
import { createHash } from 'crypto';
import { Redis } from 'ioredis';

interface AuthenticatedRequest extends Request {
  user?: JwtPayload;
}

interface CaepClaims extends JwtPayload {
  sid?: string;
  jti?: string;
}

export class CaepTokenValidator {
  constructor(private readonly redisClient: Redis, private readonly jwksPublicKey: string) {}

  public middleware = async (req: AuthenticatedRequest, res: Response, next: NextFunction): Promise<void> => {
    const authHeader = req.headers.authorization;
    if (!authHeader?.startsWith('Bearer ')) {
      res.status(401).json({ error: 'Missing or malformed authorization header' });
      return;
    }

    const token = authHeader.substring(7);
    try {
      const decoded = jwt.verify(token, this.jwksPublicKey, {
        algorithms: ['RS256'],
        issuer: process.env.OIDC_ISSUER
      }) as CaepClaims;

      if (!decoded.sub) {
        res.status(401).json({ error: 'Subject identifier missing' });
        return;
      }

      // Hash identifiers to avoid raw PII storage in cache keys and prevent timing discrepancies
      const subHash = createHash('sha256').update(decoded.sub).digest('hex');
      const pipeline = this.redisClient.pipeline();

      pipeline.get(`caep:revocation:sub:${subHash}`);
      if (decoded.sid) {
        pipeline.get(`caep:revocation:sid:${decoded.sid}`);
      }
      if (decoded.jti) {
        pipeline.get(`caep:revocation:jti:${decoded.jti}`);
      }

      const results = await pipeline.exec();
      const isRevoked = results?.some(([err, result]) => !err && result !== null);

      if (isRevoked) {
        res.status(401).json({ error: 'Token or session revoked via CAEP real-time policy' });
        return;
      }

      req.user = decoded;
      next();
    } catch (err) {
      res.status(401).json({ error: 'Token validation failed', details: (err as Error).message });
    }
  };
}
```

### Idempotent RFC 8935 CAEP Security Event Token (SET) Webhook Ingestion Handler

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Fails to verify the cryptographic signature of the Security Event Token, assumes plain JSON rather than a signed JWT/SET conforming to RFC 8935, lacks TTL setting (leading to memory leaks in the distributed store), and lacks idempotency and replay protection.
```typescript
import { Request, Response } from 'express';
import { Redis } from 'ioredis';

const redis = new Redis();

export const handleCaepWebhook = async (req: Request, res: Response): Promise<void> => {
  // ANTI-PATTERN: Unverified webhook payload; directly trusts incoming payload structure without
  // cryptographic validation of the SET (RFC 8935) signature, event-type matching, or TTL calculation.
  const event = req.body;
  if (event.type === 'session-revoked') {
    await redis.set(`revoked:${event.userId}`, 'true');
  }
  res.status(200).send('OK');
};
```

#### Production Standard (Correct)
> **Standard**: Implements RFC 8935/8936 compliance by cryptographically verifying the SET, rejecting unauthorized senders, deduplicating incoming SET jti identifiers to prevent replay attacks, and executing multi-key atomic invalidation with TTL bounded to maximum token lifetimes.
```typescript
import { Request, Response } from 'express';
import jwt, { JwtPayload } from 'jsonwebtoken';
import { createHash } from 'crypto';
import { Redis } from 'ioredis';

interface CaepSecurityEventToken extends JwtPayload {
  iss: string;
  aud: string;
  iat: number;
  jti: string;
  events: {
    'https://schemas.openid.net/secevent/caep/event-type/session-revoked'?: {
      subject: {
        format: 'iss_sub' | 'opaque';
        sub?: string;
        sid?: string;
      };
      event_timestamp: number;
      initiating_entity?: string;
      reason_admin?: string;
    };
  };
}

export class CaepReceiverService {
  private static readonly MAX_CLOCK_SKEW_SEC = 300;
  private static readonly CAEP_EVENT_REVOCATION = 'https://schemas.openid.net/secevent/caep/event-type/session-revoked';

  constructor(private readonly redis: Redis, private readonly idpPublicKey: string) {}

  public handleSecurityEventToken = async (req: Request, res: Response): Promise<void> => {
    const rawToken = typeof req.body === 'string' ? req.body : req.body.security_event_token;
    if (!rawToken) {
      res.status(400).json({ error: 'Missing security_event_token payload' });
      return;
    }

    try {
      // 1. Verify SET cryptographic signature & standard claims per RFC 8935 / RFC 8417
      const set = jwt.verify(rawToken, this.idpPublicKey, {
        algorithms: ['RS256'],
        issuer: process.env.EXPECTED_IDP_ISSUER,
        audience: process.env.EXPECTED_RESOURCE_AUDIENCE
      }) as CaepSecurityEventToken;

      // 2. Prevent replay attacks via SET jti idempotency tracking
      const setDedupeKey = `caep:processed_set:${set.jti}`;
      const acquired = await this.redis.set(setDedupeKey, '1', 'EX', 86400, 'NX');
      if (!acquired) {
        res.status(202).json({ status: 'Ignored duplicate SET' });
        return;
      }

      // 3. Extract and execute CAEP session-revoked event
      const revocationEvent = set.events[CaepReceiverService.CAEP_EVENT_REVOCATION];
      if (revocationEvent?.subject) {
        const { sub, sid } = revocationEvent.subject;
        const ttlSeconds = parseInt(process.env.MAX_TOKEN_LIFETIME_SEC || '3600', 10);
        const multi = this.redis.multi();

        if (sub) {
          const subHash = createHash('sha256').update(sub).digest('hex');
          multi.set(`caep:revocation:sub:${subHash}`, 'revoked', 'EX', ttlSeconds);
        }
        if (sid) {
          multi.set(`caep:revocation:sid:${sid}`, 'revoked', 'EX', ttlSeconds);
        }

        await multi.exec();
      }

      res.status(202).json({ status: 'Revocation applied' });
    } catch (error) {
      res.status(400).json({ error: 'Invalid SET token', details: (error as Error).message });
    }
  };
}
```

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Continuous Access Evaluation Profile (CAEP) Real-Time Revocation Invariant

Continuous Access Evaluation Profile (CAEP) Real-Time Revocation Invariant defines an industrial-grade behavioral standard for security engineering. Enforces asynchronous Security Event Token (SET) processing (RFC 8935/8936) across distributed microservices to instantaneously invalidate sessions and security principals upon credential revocation or risk change. Eliminates window-of-vulnerability states caused by purely reliant, stateless JWT expiration timeouts. Guarantees idempotency, replay protection, and distributed revocation propagation across cache and active session tiers. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Relying on Passive JWT Expiration and In-Memory Local Session Checks During Credential Compromise Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftRelying on Passive JWT Expiration and In-Memory Local Session Checks During Credential CompromiseCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Services MUST process incoming CAEP Security Event Tokens (SETs) conforming to RFC 8935 and RFC 8936 containing events such as 'session-revoked', 'credential-change', or 'assurance-level-change'.

Services MUST process incoming CAEP Security Event Tokens (SETs) conforming to RFC 8935 and RFC 8936 containing events such as 'session-revoked', 'credential-change', or 'assurance-level-change'.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Token validation pipelines MUST NOT solely rely on local asymmetric public key verification (signature and exp checks) without querying an ultra-low-latency distributed revocation registry.

Token validation pipelines MUST NOT solely rely on local asymmetric public key verification (signature and exp checks) without querying an ultra-low-latency distributed revocation registry.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST index revocation checks by canonical subject identifiers

Engineers MUST index revocation checks by canonical subject identifiers: cryptographic hash of the Subject identifier (sub) or Session ID (sid), and token identifier (jti).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST verify the issuer (iss) and asymmetric signature of incoming SETs against the Identity Provider's trusted JWKS before applying revocation updates.

Services MUST verify the issuer (iss) and asymmetric signature of incoming SETs against the Identity Provider's trusted JWKS before applying revocation updates.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Revocation states in distributed storage (e.g., Redis cluster) MUST utilize Time-To-Live (TTL) values matching or exceeding the remaining valid lifetime (exp - now) of the invalidated token to prevent memory leaks.

Revocation states in distributed storage (e.g., Redis cluster) MUST utilize Time-To-Live (TTL) values matching or exceeding the remaining valid lifetime (exp - now) of the invalidated token to prevent memory leaks.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Event ingestion handlers MUST implement strict idempotency and clock-skew validation (nbf/iat checks) to protect against out-of-order execution or duplicate delivery of SET events.

Event ingestion handlers MUST implement strict idempotency and clock-skew validation (nbf/iat checks) to protect against out-of-order execution or duplicate delivery of SET events.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Continuous Access Evaluation Profile (CAEP) Real-Time Revocation Invariant critical for AI coding assistants?

Enforces asynchronous Security Event Token (SET) processing (RFC 8935/8936) across distributed microservices to instantaneously invalidate sessions and security principals upon credential revocation or risk change. Eliminates window-of-vulnerability states caused by purely reliant, stateless JWT expiration timeouts. Guarantees idempotency, replay protection, and distributed revocation propagation across cache and active session tiers. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Relying on Passive JWT Expiration and In-Memory Local Session Checks During Credential Compromise) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Continuous