Architecting Continuous Access Evaluation
Closing the token TTL blast radius with CAEP and SSF event streams, plus PDP/PEP design choices for fail-open vs fail-closed enforcement.

In this guide
Table of Contents
Table of contents
An OAuth2 access token minted at 09:00 with a 60-minute TTL is still cryptographically valid at 09:59, even if the device it was issued to was flagged as compromised at 09:05. This is the core failure of static token-based authorisation in a zero-trust estate: authentication and authorisation are evaluated once, at issuance, and then trusted blindly until expiry. For an enterprise identity provider fronting tens of thousands of sessions, that window is an unacceptable blast radius. Continuous access evaluation closes this gap by converting authorisation from a point-in-time decision into a streaming, event-driven state machine that can revoke trust mid-session, not just at renewal.
This article covers the architecture required to implement continuous access evaluation using the OpenID Shared Signals Framework (SSF) and the Continuous Access Evaluation Protocol (CAEP), the failure modes that emerge when event delivery lags behind policy state, and the trade-offs between fail-open and fail-closed enforcement at scale.
#The Bottleneck: Stateless Tokens vs Stateful Risk
Standard OIDC/OAuth2 deployments treat the access token as a bearer credential. The resource server’s Policy Enforcement Point (PEP) validates the signature and expiry claims and nothing else. Risk signals — impossible travel, device posture drift, credential compromise, IP reputation changes — are detected asynchronously by a SIEM or a Conditional Access engine, but there is no mechanism to push that signal into an already-issued token. Shortening token TTLs to 5 minutes reduces the exposure window but multiplies token refresh traffic against the IdP by an order of magnitude, and it still leaves a non-zero gap.
Continuous access evaluation solves this by decoupling token validity from session trust. The token becomes a lightweight, short-lived artefact; the actual authorisation decision is re-evaluated against a live trust state held outside the token, on every request or on every signal event, whichever fires first.
#Architectural Breakdown
A production continuous access evaluation architecture has four components, mirroring the standard Zero Trust Architecture (per NIST SP 800-207) split between decision and enforcement:
- Identity Provider (IdP) / Transmitter — Issues tokens and emits Security Event Tokens (SETs, RFC 8417) whenever a risk-relevant event occurs (credential change, session revocation, device non-compliance).
- Shared Signals Framework (SSF) Stream — The transport layer. Either a push delivery (HTTPS POST to a receiver endpoint) or poll delivery (receiver pulls from a queue). This is the backbone of the OpenID CAEP specification.
- Policy Decision Point (PDP) — A stateful microservice that ingests SETs, mutates a trust registry (typically Redis or a distributed cache), and exposes a low-latency decision API.
- Policy Enforcement Point (PEP) — Sits at the API gateway or service meshsidecar (Envoy ext_authz, or an API Gateway Lambda authoriser) and calls the PDP synchronously on every inbound request before proxying to the resource server.The KBY LexiconService MeshA dedicated, infrastructure-layer abstraction that manages service-to-service communication via out-of-process proxies, decoupling network logic (retries, mTLS, observability, routing) from application code. It exists to provide uniform L4/L7 traffic control and zero-trust security across a distributed system without requiring per-language client libraries.
The critical architectural decision is where continuous access evaluation state lives. Embedding risk state inside the JWT (via a caep_events claim, for instance) reintroduces staleness because the token is immutable post-issuance. The trust registry must live external to the token, queried at request time.

#Event Flow
The following flow illustrates a session-revoked event propagating from the IdP through to enforcement at the gateway:
Rendering diagram...
#Implementation Logic
Rolling out continuous access evaluation across an existing OIDC estate follows a defined sequence rather than a big-bang cutover:
- Step 1 — Register the SSF receiver. The resource-side PDP registers with the IdP’s SSF configuration endpoint, negotiating supported event types (
session-revoked,token-claims-change,device-compliance-change,credential-change) and delivery method. - Step 2 — Shorten token TTL to a bounded ceiling. Access tokens drop to a 5–10 minute TTL. This is not the primary revocation mechanism, but a backstop for receivers that miss events entirely.
- Step 3 — Deploy the PDP as a sidecar-adjacent service. Co-locate the PDP decision cache with the gateway to keep the ext_authz round trip under 5ms at p99.
- Step 4 — Wire the PEP into the mesh. Every ingress path — API gateway, service mesh sidecar, SPA backend-for-frontend — must call the PDP, not just the initial login flow.
- Step 5 — Instrument event lag. Track the delta between event emission timestamp and cache mutation timestamp; this delta is your continuous access evaluation exposure window and must be reported as an SLO.
#Code & Configurations
SSF stream configuration registered by the receiver against the IdP’s transmitter configuration endpoint:
1{
2 "delivery": {
3 "delivery_method": "https://schemas.openid.net/secevent/risc/delivery-method/push",
4 "endpoint_url": "https://pdp.internal.kby.io/ssf/receiver"
5 },
6 "events_requested": [
7 "https://schemas.openid.net/secevent/caep/event-type/session-revoked",
8 "https://schemas.openid.net/secevent/caep/event-type/token-claims-change",
9 "https://schemas.openid.net/secevent/caep/event-type/device-compliance-change"
10 ],
11 "format": "iss_sub"
12}A decoded Security Event Token (SET) payload for a session-revoked signal, per RFC 8417:
1{
2 "iss": "https://idp.kby.io",
3 "iat": 1719840000,
4 "jti": "c4f1-9a3e-71bb",
5 "aud": "https://pdp.internal.kby.io",
6 "events": {
7 "https://schemas.openid.net/secevent/caep/event-type/session-revoked": {
8 "subject": {
9 "format": "iss_sub",
10 "iss": "https://idp.kby.io",
11 "sub": "user-4471"
12 },
13 "reason": "device_noncompliant",
14 "initiating_entity": "policy-engine",
15 "event_timestamp": 1719839998
16 }
17 }
18}Envoy’s ext_authz HTTP filter configuration wiring the gateway to the PDP as the enforcement point:

1http_filters:
2 - name: envoy.filters.http.ext_authz
3 typed_config:
4 "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
5 transport_api_version: V3
6 http_service:
7 server_uri:
8 uri: http://pdp.internal.kby.io:9191
9 cluster: pdp_cluster
10 timeout: 0.05s
11 authorization_request:
12 headers_to_add:
13 - key: x-caep-check
14 value: "true"
15 failure_mode_allow: falseThe PDP’s core decision logic, expressed in Go pseudocode, resolves against the trust registry rather than re-parsing the JWT payload:
1func Authorize(ctx context.Context, sub, sid string) (bool, string) {
2 key := fmt.Sprintf("caep:trust:%s:%s", sub, sid)
3 state, err := redisClient.Get(ctx, key).Result()
4 if err == redis.Nil {
5 return true, "no_signal_default_allow" // bounded by short token TTL
6 }
7 if state == "revoked" {
8 return false, "session_revoked"
9 }
10 if state == "device_noncompliant" {
11 return false, "posture_failed"
12 }
13 return true, "trusted"
14}#Failure Modes & Edge Cases
Continuous access evaluation trades a static-token vulnerability for a distributed-systems consistency problem, and that trade needs explicit handling:
- Event delivery lag — Push delivery over HTTPS can queue behind receiver-side backpressure. If the PDP’s ingestion worker pool saturates during a mass credential rotation (e.g. a password-spray remediation forcing 10,000 session revocations), the SET queue backs up and the exposure window widens silently unless lag is actively monitored.The KBY LexiconBackpressure (Flow Control)A feedback mechanism by which a downstream consumer signals its processing capacity to an upstream producer, forcing it to slow, buffer, or drop data to prevent overload.
- Event storms — A directory-wide policy change (e.g. disabling legacy auth org-wide) can emit signals for every active session simultaneously. Without batching and idempotent event IDs (
jtideduplication), the trust registry can thrash under write amplification.The KBY LexiconWrite AmplificationWrite amplification is the ratio between the physical amount of data written to durable storage media and the logical amount of data the application actually requested to write. It matters because it directly determines storage device wear, I/O bandwidth consumption, and the effective throughput ceiling of any system built on log-structured or copy-on-write storage engines. - Replay attacks on SETs — Because SETs are bearer JWTs themselves, an attacker with network position could replay a stale
token-claims-changeevent to force an unintended trust state. Receivers must validateiatfreshness and maintain ajtinonce cache with a bounded TTL. - Receiver downtime — If the PDP receiver endpoint is unreachable, most transmitters queue and retry with exponential backoff, but retention windows are finite (typically 24–72 hours). A prolonged outage silently drops revocation signals, and the estate reverts to trusting tokens purely on TTL.
- Network partition between PDP and PEP — This is the fail-open/fail-closed decision point. If the gateway cannot reach the PDP, does it deny all traffic (safe, but a total availability failure) or allow traffic on stale cache state (available, but reintroduces the original vulnerability)?
#Scaling & Security Trade-offs
Deploying continuous access evaluation across a large estate forces explicit trade-offs that should be documented in the platform’s architectural patterns registry rather than left as tribal knowledge:
- Push vs poll delivery — Push delivery gives sub-second propagation but requires the receiver to expose a publicly reachable, authenticated endpoint, increasing attack surface. Poll delivery is safer at the network boundary but adds polling-interval latency (typically 5–30s) to the exposure window.
- Fail-open vs fail-closed PEP behaviour — Fail-closed is mandatory for regulated workloads (PCI, HIPAA scope) despite the availability cost; fail-open is acceptable only for low-sensitivity internal tooling where a PDP outage should not become a full outage.
- Centralised PDP vs sidecar-local cache — A single centralised PDP simplifies consistency but becomes a single point of contention at high RPS; sidecar-local caching (with async replication of trust state) reduces latency but reintroduces a small consistency lag per node.
- Token TTL vs refresh volume — Every reduction in token TTL directly increases refresh token grant volume against the IdP’s token endpoint; capacity planning for the IdP must scale proportionally, typically requiring horizontal read replicas on the token-signing service.
- Event retention vs storage cost — Retaining SET history for audit and replay-detection purposes (SOC2/ISO27001 evidentiary requirements) means the trust registry cannot be purely ephemeral; a write-once audit log (e.g. an append-only Kafka topic) should sit behind the Redis-backed hot cache.
None of these trade-offs are resolved generically — they are a function of the specific regulatory posture and latency budget of the workload sitting behind the PEP, and continuous access evaluation should be tuned per trust tier rather than applied uniformly across the estate.
Evidence trail
Sources and verification
Primary documentation and external technical references used in this article.
Comments
Add a thoughtful note on Architecting Continuous Access Evaluation. Comments are checked for spam and held for moderation before appearing.
Related Engineering Labs
Calculator
K8s RBAC
Visually construct and generate compliant Kubernetes Role-Based Access Control manifests.
Calculator
DB Pool Sizer
Calculate the exact, safe maximum connection pool size per pod to ensure the database is never exhausted during an autoscaling event.
Calculator
Partition Calculator
Determine the exact minimum number of partitions required to achieve a target throughput without breaking ordering or over-provisioning infrastructure.
Related articles
Enterprise IT Management
Designing a Verifiable IT Management Workflow with Microsoft 365
A bounded Microsoft 365 Conditional Access workflow: staged rollout through report-only evaluation and pilot enforcement, explicit validation gates, and a rehearsed, non-destructive rollback path.
Enterprise IT Management
BYOD Management Tools: MAM Without Enrolment
How App Protection Policies, Conditional Access token binding and Graph API enforcement deliver BYOD management tools without full MDM enrolment.
Enterprise IT Management
Continuous Control Monitoring for SOC 2 Audits
How AWS Config, Okta logs and GitHub audit events feed a continuous control monitoring pipeline that replaces manual SOC 2 evidence pulls.
Enterprise IT Management
Tiered Admin Model: Killing Lateral Movement
How authentication silos, PAWs and Kerberos armoring enforce privileged access tiering to stop pass-the-hash lateral movement across AD tiers.
Learn More About KBY
About KBY
Learn about our mission, editorial standards, and commitment to trusted engineering knowledge.
Why Trust KBY
Explore the processes and policies that ensure our publications are accurate, useful, and responsible.
Newsletter
Get our latest editorial publications, research and practical insights sent directly to your inbox.
Was this useful?
Engineering insights, direct to you.
Receive the latest Systems Engineering tutorials, production guides, Engineering Labs and operational best practices.