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

OpenFGA Distributed ReBAC Architecture and Contextual Evaluation Invariants

Standardizes high-throughput, low-latency Relationship-Based Access Control (ReBAC) using OpenFGA across distributed microservices. Mandates atomic tuple synchronization via transactional outbox patterns, strict use of contextual tuples for ephemeral request states, and vector-evaluated batching to prevent N+1 authorization cascades and authorization drift.

Prohibited Anti-Pattern: Synchronous Dual-Writes of Relationship Tuples and In-Loop Sequential OpenFGA Checks Causing Authorization Drift and Cascading Latency

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenFGA Distributed ReBAC Architecture and Contextual Evaluation Invariants - Standardizes high-throughput, low-latency Relationship-Based Access Control (ReBAC) using OpenFGA across distributed microservices. Mandates atomic tuple synchronization via transactional outbox patterns, strict use of contextual tuples for ephemeral request states, and vector-evaluated batching to prevent N+1 authorization cascades and authorization drift.
globs: src/**/*.ts, src/authz/**/*.ts, src/services/**/*.ts, src/middleware/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-rebac-distributed-authorization-standard"
---

# OpenFGA Distributed ReBAC Architecture and Contextual Evaluation Invariants

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Synchronous Dual-Writes of Relationship Tuples and In-Loop Sequential OpenFGA Checks Causing Authorization Drift and Cascading Latency

## System Constraints
You are a Principal Security Architect enforcing OpenFGA ReBAC distributed standards. Enforce transactional outbox tuple persistence, contextual tuple injection, zero N+1 synchronous check loops, and explicit consistency tokens across all authorization boundaries.

## Strict Guidelines
- Services MUST synchronize OpenFGA relationship tuples via an atomic Transactional Outbox or CDC pipeline; engineers MUST NOT execute dual-writes to the operational database and OpenFGA in parallel.
- Engineers MUST NEVER execute single-item `fgaClient.check` calls inside sequential collection iterations (`map`, `for...of`, `forEach`); microservices MUST use `fgaClient.batchCheck` or push filtering to OpenFGA via `fgaClient.listObjects`.
- Engineers MUST inject transient or request-scoped attributes (e.g., temporary elevation, geofencing, client IP) via `contextual_tuples` or `context` parameters instead of writing persistent tuples to the OpenFGA storage engine.
- Authorization checks guarding critical write or delete paths MUST specify `consistency: ConsistencyPreference.AtLeastAsFresh` to prevent stale cache evaluations and eliminate the 'New Enemy' vulnerability.
- Applications MUST NOT fetch unrestricted record sets into service memory and post-filter via point-in-time checks; data querying MUST intersect with `listObjects` or authorized object ID sets to maintain bounded memory overhead.

## Bad vs Good Implementations
### Dual-Write Tuple Drift and N+1 Loop Checks vs. Outbox-Driven ListObjects Evaluation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Performs dual-writes directly from the request handler without transactional guarantees, leading to state drift if the OpenFGA write fails. Iterates over an unbounded list of documents executing individual synchronous `check` calls, introducing severe N+1 latency amplification.
```typescript
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({ apiUrl: process.env.FGA_API_URL! });

export async function getAccessibleDocuments(userId: string, orgId: string, db: any) {
  // ANTI-PATTERN: Fetching all records without access bounds
  const allDocs = await db.documents.findMany({ where: { orgId } });
  const authorizedDocs = [];

  // ANTI-PATTERN: N+1 sequential OpenFGA network calls across microservice boundary
  for (const doc of allDocs) {
    const response = await fgaClient.check({
      user: `user:${userId}`,
      relation: 'viewer',
      object: `document:${doc.id}`,
    });
    if (response.allowed) {
      authorizedDocs.push(doc);
    }
  }
  return authorizedDocs;
}

export async function assignDocumentOwner(userId: string, docId: string, db: any) {
  // ANTI-PATTERN: Non-atomic dual write; failure here leaves database and auth out of sync
  await db.documents.update({ where: { id: docId }, data: { ownerId: userId } });
  await fgaClient.write({
    writes: [{ user: `user:${userId}`, relation: 'owner', object: `document:${docId}` }],
  });
}
```

#### Production Standard (Correct)
> **Standard**: Replaces N+1 sequential checks with a single `listObjects` call that passes contextual tenant information. Enforces consistency using `AtLeastAsFresh` to prevent the New Enemy problem, and records authorization mutations inside the transactional outbox to ensure zero tuple drift.
```typescript
import { OpenFgaClient, ConsistencyPreference } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
  apiUrl: process.env.FGA_API_URL!,
  storeId: process.env.FGA_STORE_ID!,
});

export async function getAccessibleDocuments(userId: string, orgId: string, db: any) {
  // PRODUCTION INVARIANT: Query authorized IDs directly from OpenFGA using listObjects
  const { objects: authorizedDocUris } = await fgaClient.listObjects({
    user: `user:${userId}`,
    relation: 'viewer',
    type: 'document',
    contextualTuples: [
      // Dynamic transient relationship: current tenant boundary
      { user: `user:${userId}`, relation: 'member', object: `organization:${orgId}` }
    ],
    consistency: ConsistencyPreference.AtLeastAsFresh,
  });

  const docIds = authorizedDocUris.map((uri) => uri.replace('document:', ''));
  if (docIds.length === 0) return [];

  // Query database using pre-authorized vector set
  return db.documents.findMany({
    where: { id: { in: docIds }, orgId },
  });
}

export async function assignDocumentOwner(userId: string, docId: string, db: any) {
  // PRODUCTION INVARIANT: Write mutation and authorization tuple atomically via Transactional Outbox
  await db.$transaction(async (tx: any) => {
    await tx.documents.update({ where: { id: docId }, data: { ownerId: userId } });
    await tx.outboxEvents.create({
      data: {
        eventType: 'AUTHZ_TUPLE_WRITE',
        payload: {
          writes: [{ user: `user:${userId}`, relation: 'owner', object: `document:${docId}` }],
        },
      },
    });
  });
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenFGA Distributed ReBAC Architecture and Contextual Evaluation Invariants

OpenFGA Distributed ReBAC Architecture and Contextual Evaluation Invariants defines an industrial-grade behavioral standard for security engineering. Standardizes high-throughput, low-latency Relationship-Based Access Control (ReBAC) using OpenFGA across distributed microservices. Mandates atomic tuple synchronization via transactional outbox patterns, strict use of contextual tuples for ephemeral request states, and vector-evaluated batching to prevent N+1 authorization cascades and authorization drift. 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: Synchronous Dual-Writes of Relationship Tuples and In-Loop Sequential OpenFGA Checks Causing Authorization Drift and Cascading Latency 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 DriftSynchronous Dual-Writes of Relationship Tuples and In-Loop Sequential OpenFGA Checks Causing Authorization Drift and Cascading LatencyCritical
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 synchronize OpenFGA relationship tuples via an atomic Transactional Outbox or CDC pipeline

Services MUST synchronize OpenFGA relationship tuples via an atomic Transactional Outbox or CDC pipeline; engineers MUST NOT execute dual-writes to the operational database and OpenFGA in parallel.

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 NEVER execute single-item `fgaClient.check` calls inside sequential collection iterations (`map`, `for...of`, `forEach`)

Engineers MUST NEVER execute single-item `fgaClient.check` calls inside sequential collection iterations (`map`, `for...of`, `forEach`); microservices MUST use `fgaClient.batchCheck` or push filtering to OpenFGA via `fgaClient.listObjects`.

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 inject transient or request-scoped attributes (e.g., temporary elevation, geofencing, client IP) via `contextual_tuples` or `context` parameters instead of writing persistent tuples to the OpenFGA storage engine.

Engineers MUST inject transient or request-scoped attributes (e.g., temporary elevation, geofencing, client IP) via `contextual_tuples` or `context` parameters instead of writing persistent tuples to the OpenFGA storage engine.

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

Authorization checks guarding critical write or delete paths MUST specify `consistency

Authorization checks guarding critical write or delete paths MUST specify `consistency: ConsistencyPreference.AtLeastAsFresh` to prevent stale cache evaluations and eliminate the 'New Enemy' vulnerability.

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

Applications MUST NOT fetch unrestricted record sets into service memory and post-filter via point-in-time checks

Applications MUST NOT fetch unrestricted record sets into service memory and post-filter via point-in-time checks; data querying MUST intersect with `listObjects` or authorized object ID sets to maintain bounded memory overhead.

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 ReBAC Architecture and Contextual Evaluation Invariants critical for AI coding assistants?

Standardizes high-throughput, low-latency Relationship-Based Access Control (ReBAC) using OpenFGA across distributed microservices. Mandates atomic tuple synchronization via transactional outbox patterns, strict use of contextual tuples for ephemeral request states, and vector-evaluated batching to prevent N+1 authorization cascades and authorization drift. 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 (Synchronous Dual-Writes of Relationship Tuples and In-Loop Sequential OpenFGA Checks Causing Authorization Drift and Cascading Latency) 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