This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: openfga-epoch-invalidation-consistency-standard

OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard

Enforces strict read-after-write consistency across globally distributed OpenFGA evaluation caches by requiring transactional tuple mutations to emit monotonic epoch sequence barriers. Prevents stale authorization grants and unauthorized access propagation when distributed sidecar engines or evaluation caches evaluate relationships immediately after grant or revoke operations.

Prohibited Anti-Pattern: Unsynchronized Tuple Writes and Unbounded Cache TTLs Causing Stale Authorization Decisions

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard - Enforces strict read-after-write consistency across globally distributed OpenFGA evaluation caches by requiring transactional tuple mutations to emit monotonic epoch sequence barriers. Prevents stale authorization grants and unauthorized access propagation when distributed sidecar engines or evaluation caches evaluate relationships immediately after grant or revoke operations.
globs: src/**/authz/**/*.ts, src/**/permissions/**/*.ts, src/**/fga/**/*.ts, src/**/access-control/**/*.ts, src/**/guards/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-epoch-invalidation-consistency-standard"
---

# OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Unsynchronized Tuple Writes and Unbounded Cache TTLs Causing Stale Authorization Decisions

## System Constraints
You are a Principal Engineer enforcing OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard. Mandate that all relationship tuple mutations (writes and deletes) synchronously register monotonic consistency tokens or epoch barriers into the distributed cache tier before returning success to callers. Reject any authorization evaluation pipeline that relies solely on time-based TTL invalidation without evaluating caller-asserted consistency barriers.

## Strict Guidelines
- Engineers MUST ALWAYS pair OpenFGA write or delete tuple operations with a transactional monotonic epoch barrier publication (e.g., Redis Pub/Sub, Raft log, or Zookie/consistency token) to invalidate edge caches.
- Engineers MUST NOT acknowledge relationship mutations to clients before confirming barrier propagation or local store transaction commitment with an associated monotonic token.
- Services MUST pass caller consistency tokens (continuation/epoch tokens) into subsequent OpenFGA check evaluations to guarantee read-after-write consistency.
- Code SHOULD enforce dual-read validation if the local cache layer reflects an epoch older than the minimum required consistency epoch presented in the client request context.
- Components NEVER evaluate authorization decisions using unverified local cache entries when evaluating access revocation paths.

## Bad vs Good Implementations
### Unsynchronized Tuple Revocation with Stale Cache Vulnerability

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Revocation mutation returns without publishing an invalidation barrier. Distributed cache nodes and edge proxies continue serving stale positive authorization decisions until arbitrary TTL expiration, creating a severe authorization bypass window.
```typescript
import { OpenFgaClient } from '@openfga/sdk';

export class AccessService {
  constructor(private fgaClient: OpenFgaClient, private localCache: Map<string, boolean>) {}

  // ANTI-PATTERN: Revokes access in OpenFGA but leaves distributed and local caches intact
  async revokeRole(user: string, relation: string, object: string): Promise<void> {
    await this.fgaClient.write({
      deletes: [{ user, relation, object }],
    });
    // Client immediately receives 200 OK while edge services evaluate stale cached checks
  }

  async checkAccess(user: string, relation: string, object: string): Promise<boolean> {
    const cacheKey = `${user}#${relation}@${object}`;
    if (this.localCache.has(cacheKey)) {
      return this.localCache.get(cacheKey)!;
    }
    const { allowed } = await this.fgaClient.check({ user, relation, object });
    this.localCache.set(cacheKey, allowed ?? false);
    return allowed ?? false;
  }
}
```

#### Production Standard (Correct)
> **Standard**: Employs an explicit monotonic epoch sequence with pub/sub barrier invalidation. Check requests honoring caller consistency barriers bypass stale caches if the cached epoch is strictly less than the required epoch, eliminating read-after-write authorization anomalies.
```typescript
import { OpenFgaClient } from '@openfga/sdk';
import { Redis } from 'ioredis';

interface ConsistencyBarrier {
  user: string;
  object: string;
  minEpoch: number;
}

export class AccessService {
  constructor(
    private fgaClient: OpenFgaClient,
    private redis: Redis
  ) {}

  async revokeRole(user: string, relation: string, object: string): Promise<{ consistencyEpoch: number }> {
    // 1. Monotonically increment global epoch for entity
    const entityEpochKey = `authz:epoch:${object}`;
    const nextEpoch = await this.redis.incr(entityEpochKey);

    // 2. Perform transactional OpenFGA tuple mutation
    await this.fgaClient.write({
      deletes: [{ user, relation, object }],
    });

    // 3. Publish epoch invalidation barrier across distributed cache bus
    await this.redis.publish('authz:invalidations', JSON.stringify({
      user,
      relation,
      object,
      epoch: nextEpoch
    }));

    return { consistencyEpoch: nextEpoch };
  }

  async checkAccess(
    user: string,
    relation: string,
    object: string,
    barrier?: ConsistencyBarrier
  ): Promise<boolean> {
    const cacheKey = `authz:decision:${user}:${relation}:${object}`;
    const cached = await this.redis.hgetall(cacheKey);

    const currentCachedEpoch = cached?.epoch ? Number(cached.epoch) : 0;
    const requiresBarrierBypass = barrier && barrier.minEpoch > currentCachedEpoch;

    if (cached?.allowed !== undefined && !requiresBarrierBypass) {
      return cached.allowed === 'true';
    }

    // Fresh evaluation bypassing stale cache tier
    const { allowed } = await this.fgaClient.check({ user, relation, object });
    const isAllowed = allowed ?? false;

    const currentEntityEpoch = Number(await this.redis.get(`authz:epoch:${object}`) ?? '0');
    await this.redis.hset(cacheKey, {
      allowed: String(isAllowed),
      epoch: String(currentEntityEpoch),
    });
    await this.redis.expire(cacheKey, 300);

    return isAllowed;
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard

OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard defines an industrial-grade behavioral standard for security engineering. Enforces strict read-after-write consistency across globally distributed OpenFGA evaluation caches by requiring transactional tuple mutations to emit monotonic epoch sequence barriers. Prevents stale authorization grants and unauthorized access propagation when distributed sidecar engines or evaluation caches evaluate relationships immediately after grant or revoke operations. 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: Unsynchronized Tuple Writes and Unbounded Cache TTLs Causing Stale Authorization Decisions 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 DriftUnsynchronized Tuple Writes and Unbounded Cache TTLs Causing Stale Authorization DecisionsCritical
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

Engineers MUST ALWAYS pair OpenFGA write or delete tuple operations with a transactional monotonic epoch barrier publication (e.g., Redis Pub/Sub, Raft log, or Zookie/consistency token) to invalidate edge caches.

Engineers MUST ALWAYS pair OpenFGA write or delete tuple operations with a transactional monotonic epoch barrier publication (e.g., Redis Pub/Sub, Raft log, or Zookie/consistency token) to invalidate edge caches.

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

Engineers MUST NOT acknowledge relationship mutations to clients before confirming barrier propagation or local store transaction commitment with an associated monotonic token.

Engineers MUST NOT acknowledge relationship mutations to clients before confirming barrier propagation or local store transaction commitment with an associated monotonic token.

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

Services MUST pass caller consistency tokens (continuation/epoch tokens) into subsequent OpenFGA check evaluations to guarantee read-after-write consistency.

Services MUST pass caller consistency tokens (continuation/epoch tokens) into subsequent OpenFGA check evaluations to guarantee read-after-write consistency.

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

Code SHOULD enforce dual-read validation if the local cache layer reflects an epoch older than the minimum required consistency epoch presented in the client request context.

Code SHOULD enforce dual-read validation if the local cache layer reflects an epoch older than the minimum required consistency epoch presented in the client request context.

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

Components NEVER evaluate authorization decisions using unverified local cache entries when evaluating access revocation paths.

Components NEVER evaluate authorization decisions using unverified local cache entries when evaluating access revocation paths.

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 OpenFGA Distributed Cache Invalidation and Read-After-Write Consistency Standard critical for AI coding assistants?

Enforces strict read-after-write consistency across globally distributed OpenFGA evaluation caches by requiring transactional tuple mutations to emit monotonic epoch sequence barriers. Prevents stale authorization grants and unauthorized access propagation when distributed sidecar engines or evaluation caches evaluate relationships immediately after grant or revoke operations. 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 (Unsynchronized Tuple Writes and Unbounded Cache TTLs Causing Stale Authorization Decisions) 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

OpenFGA