IBEX Harness
DocsBenchmarksBlogChangelogRoadmap
GitHub
IBEX Harness

Documentation

Architecture Decision RecordsADR-0002: Repository foundation bootstrapADR-0003: Branch protection and merge policyADR-0004: Protobuf and code generation policyADR-0005: Postgres migration strategyADR-0006: Auth protobuf contract (`ibex.auth.v1`)ADR-0007: Auth token validation implementationADR-0008: Security scanning and CI quality gatesADR-0009: Permission bitmap layoutADR-0010: Cryptography policyADR-0011: Proxy auth gRPC client and middlewareADR-0012: Proxy request normalization (OpenAI chat)ADR-0013: Proxy input validation and stable error envelopeADR-0014: Core domain migration sequencingADR-0015: Proxy rate limit skeleton (Phase 1)ADR-0016: Proxy agent identity verification (Phase 1)ADR-0017: Request ID and trace context strategy (Phase 1)ADR-0018: Graceful shutdown contract (Phase 1)ADR-0019: OpenTelemetry provider configuration (Phase 1)ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`ADR-0021: Prometheus Metric Catalog (Phase 1)ADR-0022: Health check contract (Phase 1)ADR-0023: Docs site architecture (Phase 1.5)ADR-0024: Benchmark data publishing modelADR-0025: LLM provider abstractionADR-0026: OpenAI client designADR-0027: Streaming dual-write strategyADR-0028: Auth cache designADR-0029: Token revocation propagation via Redis pub/subADR-0030: Directive versioning strategyADR-0031: System prompt injection strategyADR-0032: Session data model and retentionADR-0033: ClickHouse llm_traces schema and retentionADR-0034: Proxy overhead performance measurement methodologyADR-0035: Chat Idempotency-Key Redis dedupeADR-0038: Context assembly service design and gRPC contractADR-0039: Proxy Postgres ownership for session and directive storesADR-0040: Anthropic provider adapterADR-0041: Model capability registryADR-0042: Self-hosted OpenAI-compatible LLM adapterADR-0043: Tokenizer registry architectureADR-0044: Non-streaming response pipelineADR-0045: Streaming response transformationADR-0046: Embedder interface and profile registryADR-0047: Memory temporal validity foundationADR-0048: Memory multi-label categoriesADR-0049: Memory relationship graph readinessADR-0050: MCP server skeleton (transport, auth, audit)ADR-0051: Local LGTM observability stack (Phase 2.5 exit pull-forward)ADR-0052: Memory schema v2 expand (HNSW, quality columns)ADR-0053: Vector store abstraction and composite scoring v2
ADRs›ADR-0029: Token revocation propagation via Redis pub/sub
ADRs

ADR-0029: Token revocation propagation via Redis pub/sub

Accepted — Redis pub/sub invalidates proxy LRU by token_id on revoke; documents 30s LRU TTL vs 1s/5s SLA gap and reconnect follow-up.

ADR-0029: Token revocation propagation via Redis pub/sub

  • Status: Accepted (implemented in 2.2.2)
  • Date: 2026-07-19
  • Authors: IBEX Harness team
  • Milestone: 2.2.2 Token revocation propagation

Context

Milestone 2.2.1 introduces an auth LRU cache with a 30-second maximum TTL. Without active invalidation, a revoked token can remain usable until natural expiry. Phase 2 SLAs require revoked tokens rejected within 5 seconds (exit gate) and ideally within 1 second end-to-end after pub/sub delivery.

Redis is already required for rate limiting. Pub/sub fans out revoke events to all proxy instances without new infrastructure.

RevokeToken receives token_id + org_id only — never the raw bearer. Stored tokens.hash is Argon2id, which is not authcache.TokenHash (SHA-256 of the bearer). Therefore the pub/sub event cannot carry a cache digest derived at revoke time without an extra migration column.

Decision

  1. Channel: ibex:token:revocations (global; not org-scoped).
  2. Event: JSON RevocationEvent with schema version v, token_id (UUID string), revoked_at, and org_id (audit only).
  3. Auth publisher: After durable Postgres revoke, publish asynchronously (REDIS_URL). Redis failure must not fail RevokeToken — Postgres remains source of truth. Proxies that never wrapped the auth cache (empty/unreachable Redis at startup) already revalidate via gRPC on every request.
  4. Proxy subscriber: On message, call CachingValidator.InvalidateByTokenID(tokenID). The claims LRU maintains a secondary tokenID → digest index populated on putLRU. Lifecycle owned by packages/shutdown. Proxy bootstrap wraps the cache only when Redis is present and Ping succeeds; otherwise WARN and skip wrap (no stale LRU without a revocation channel).
  5. SLA vs TTL gap (documented): Steady-state with healthy pub/sub meets ~1s invalidate / 5s exit SLA. If a proxy misses messages (disconnect, subscribe lag, process restart before resubscribe), the worst case is still the 30s LRU TTL until natural expiry. That gap is accepted for Phase 2 with the follow-up below.

Optional follow-up (not Phase 2 blocking)

On Redis reconnect (or subscriber start), optionally fetch the full recent revocation set (e.g. Redis SET / sorted set of token IDs since now - LRU_TTL, or a short Postgres poll of recently revoked tokens) and bulk-invalidate the local LRU. Closes the reconnect window without waiting for TTL.

Consequences

  • Milestone 2.2.2 implements publisher + subscriber per this ADR (packages/revocation).
  • Exit gate "revoked within 5s" assumes healthy pub/sub; reconnect window is explicitly documented; missed events fall back to LRU TTL.
  • Metrics: ibex_auth_revocation_publish_total{result}, ibex_proxy_revocation_invalidate_total; WARN on publish/subscribe failures.

Alternatives considered

  1. Shorter LRU TTL (1–5s) — increases auth gRPC load; rejected as primary fix.
  2. gRPC streaming revoke channel — extra coupling; Redis already present.
  3. Ignore pub/sub; rely on TTL only — fails 5s SLA.
  4. Add lookup_hash (SHA-256) column — works with hash-keyed invalidate but requires a migration; deferred. token_id secondary index avoids schema change.

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0028: Auth cache designNextADR-0030: Directive versioning strategy

On this page

  • Context
  • Decision
  • Optional follow-up (not Phase 2 blocking)
  • Consequences
  • Alternatives considered
0%