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

OpenFGA 1.8 Transactional CDC Outbox & Check Evaluation Consistency

Enforces zero authorization drift between relational domain models and OpenFGA 1.8 relationship tuples by eliminating dual-writes across microservices. Mandates that all tuple mutations occur atomically within the primary database transaction via a transactional outbox table streamed to OpenFGA via CDC (Change Data Capture) log tailing, while pairing read-after-write checks with contextual tuples or HIGHEST_CONSISTENCY evaluation parameters.

Prohibited Anti-Pattern: Dual-Writing Application-Layer Authorization Tuples to OpenFGA Alongside Relational Transactions

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenFGA 1.8 Transactional CDC Outbox & Check Evaluation Consistency - Enforces zero authorization drift between relational domain models and OpenFGA 1.8 relationship tuples by eliminating dual-writes across microservices. Mandates that all tuple mutations occur atomically within the primary database transaction via a transactional outbox table streamed to OpenFGA via CDC (Change Data Capture) log tailing, while pairing read-after-write checks with contextual tuples or HIGHEST_CONSISTENCY evaluation parameters.
globs: src/services/**/*.{ts,js}, src/repositories/**/*.{ts,js}, src/outbox/**/*.{ts,js}, src/authorization/**/*.{ts,js}, src/events/**/*.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-cdc-outbox-consistency-standard"
---

# OpenFGA 1.8 Transactional CDC Outbox & Check Evaluation Consistency

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Dual-Writing Application-Layer Authorization Tuples to OpenFGA Alongside Relational Transactions

## System Constraints
You are a Principal Security and Distributed Systems Architect enforcing strict OpenFGA 1.8 authorization invariants. Under no circumstances may application code execute asynchronous dual-writes to OpenFGA HTTP/gRPC endpoints directly alongside relational database commits. All tuple insertions, updates, and deletions MUST be committed to an append-only transactional outbox table within the same ACID transaction as the domain entity mutation. CDC pipelines (e.g., Debezium) MUST ingest the WAL and dispatch idempotent tuple writes to OpenFGA. Furthermore, any immediate post-mutation authorization evaluation MUST supply the newly committed relationship as a contextual tuple or configure `consistency: ConsistencyPreference.HIGHEST_CONSISTENCY` to eliminate race conditions caused by CDC ingestion lag.

## Strict Guidelines
- Engineers MUST NEVER invoke `fgaClient.write()` or `fgaClient.writeTuples()` directly inside standard application request-response handlers alongside relational transactions (dual-write anti-pattern).
- All authorization state changes MUST be serialized into an append-only `outbox_tuples` table within the same local database transaction as the entity mutation.
- The CDC outbox consumer MUST execute OpenFGA writes idempotently, handling out-of-order delivery and retries using deterministic idempotency keys or sequence offsets.
- Code executing authorization evaluations immediately following a mutation MUST inject in-flight contextual tuples via `contextualTuples` in `fgaClient.check()` to bridge CDC replication latency.
- Services requiring guaranteed read-after-write linearizability MUST explicitly configure OpenFGA 1.8 `consistency: ConsistencyPreference.HIGHEST_CONSISTENCY` on critical path authorization checks.
- Outbox tuple payloads MUST strictly conform to the OpenFGA 1.8 DSL authorization model schema definitions (`user`, `relation`, `object`, and optional `condition`).

## Bad vs Good Implementations
### Transactional Outbox Pattern vs Direct Application-Level Dual-Write

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Directly calling OpenFGA outside the relational transaction introduces a distributed dual-write vulnerability. If the network call times out, process crashes, or OpenFGA throttles the request, the database holds the new owner while OpenFGA maintains the old owner, breaking authorization consistency across the microservice ecosystem.
```typescript
import { OpenFgaClient } from '@openfga/sdk';
import { db } from '../database';

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

export async function transferDocumentOwnership(docId: string, oldOwnerId: string, newOwnerId: string) {
  // Anti-pattern: Dual-write hazard. If DB transaction succeeds but network fails to OpenFGA,
  // authorization diverges permanently from business state.
  await db.$transaction(async (tx) => {
    await tx.document.update({
      where: { id: docId },
      data: { ownerId: newOwnerId }
    });
  });

  // DUAL-WRITE: Unprotected external network call creates ghost permissions on failure
  await fgaClient.write({
    deletes: [{ user: `user:${oldOwnerId}`, relation: 'owner', object: `document:${docId}` }],
    writes: [{ user: `user:${newOwnerId}`, relation: 'owner', object: `document:${docId}` }]
  });
}
```

#### Production Standard (Correct)
> **Standard**: Mutations to the relational entity and the OpenFGA outbox log execute within a single atomic database transaction. Downstream CDC workers tail the database WAL to asynchronously commit tuples to OpenFGA without dual-write risk. Immediate read-after-write checks supply contextual tuples and use HIGHEST_CONSISTENCY to prevent latency-induced false negatives.
```typescript
import { db } from '../database';
import { OpenFgaClient, ConsistencyPreference } from '@openfga/sdk';
import { randomUUID } from 'node:crypto';

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

export async function transferDocumentOwnership(
  docId: string,
  oldOwnerId: string,
  newOwnerId: string
): Promise<void> {
  // Invariant: Entity state and authorization intent are atomically committed to the WAL
  await db.$transaction(async (tx) => {
    await tx.document.update({
      where: { id: docId },
      data: { ownerId: newOwnerId }
    });

    // Transactional Outbox write - CDC (Debezium) tails this to write to OpenFGA
    await tx.openFgaOutbox.create({
      data: {
        id: randomUUID(),
        aggregateType: 'document',
        aggregateId: docId,
        operation: 'TRANSFER_OWNERSHIP',
        payload: {
          writes: [{ user: `user:${newOwnerId}`, relation: 'owner', object: `document:${docId}` }],
          deletes: [{ user: `user:${oldOwnerId}`, relation: 'owner', object: `document:${docId}` }]
        },
        createdAt: new Date()
      }
    });
  });
}

export async function checkDocumentAccessWithLinearizability(
  userId: string,
  docId: string,
  pendingNewOwnerId?: string
): Promise<boolean> {
  // Invariant: Bridge CDC delay using contextual tuples or HIGHEST_CONSISTENCY
  const contextualTuples = pendingNewOwnerId
    ? [{ user: `user:${pendingNewOwnerId}`, relation: 'owner', object: `document:${docId}` }]
    : [];

  const { allowed } = await fgaClient.check({
    user: `user:${userId}`,
    relation: 'can_edit',
    object: `document:${docId}`,
    contextualTuples,
    consistency: ConsistencyPreference.HIGHEST_CONSISTENCY
  });

  return allowed ?? false;
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenFGA 1.8 Transactional CDC Outbox & Check Evaluation Consistency

OpenFGA 1.8 Transactional CDC Outbox & Check Evaluation Consistency defines an industrial-grade behavioral standard for security engineering. Enforces zero authorization drift between relational domain models and OpenFGA 1.8 relationship tuples by eliminating dual-writes across microservices. Mandates that all tuple mutations occur atomically within the primary database transaction via a transactional outbox table streamed to OpenFGA via CDC (Change Data Capture) log tailing, while pairing read-after-write checks with contextual tuples or HIGHEST_CONSISTENCY evaluation parameters. 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: Dual-Writing Application-Layer Authorization Tuples to OpenFGA Alongside Relational Transactions 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 DriftDual-Writing Application-Layer Authorization Tuples to OpenFGA Alongside Relational TransactionsCritical
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 NEVER invoke `fgaClient.write()` or `fgaClient.writeTuples()` directly inside standard application request-response handlers alongside relational transactions (dual-write anti-pattern).

Engineers MUST NEVER invoke `fgaClient.write()` or `fgaClient.writeTuples()` directly inside standard application request-response handlers alongside relational transactions (dual-write anti-pattern).

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

All authorization state changes MUST be serialized into an append-only `outbox_tuples` table within the same local database transaction as the entity mutation.

All authorization state changes MUST be serialized into an append-only `outbox_tuples` table within the same local database transaction as the entity mutation.

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

The CDC outbox consumer MUST execute OpenFGA writes idempotently, handling out-of-order delivery and retries using deterministic idempotency keys or sequence offsets.

The CDC outbox consumer MUST execute OpenFGA writes idempotently, handling out-of-order delivery and retries using deterministic idempotency keys or sequence offsets.

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 executing authorization evaluations immediately following a mutation MUST inject in-flight contextual tuples via `contextualTuples` in `fgaClient.check()` to bridge CDC replication latency.

Code executing authorization evaluations immediately following a mutation MUST inject in-flight contextual tuples via `contextualTuples` in `fgaClient.check()` to bridge CDC replication latency.

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

Services requiring guaranteed read-after-write linearizability MUST explicitly configure OpenFGA 1.8 `consistency

Services requiring guaranteed read-after-write linearizability MUST explicitly configure OpenFGA 1.8 `consistency: ConsistencyPreference.HIGHEST_CONSISTENCY` on critical path authorization checks.

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

Outbox tuple payloads MUST strictly conform to the OpenFGA 1.8 DSL authorization model schema definitions (`user`, `relation`, `object`, and optional `condition`).

Outbox tuple payloads MUST strictly conform to the OpenFGA 1.8 DSL authorization model schema definitions (`user`, `relation`, `object`, and optional `condition`).

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 1.8 Transactional CDC Outbox & Check Evaluation Consistency critical for AI coding assistants?

Enforces zero authorization drift between relational domain models and OpenFGA 1.8 relationship tuples by eliminating dual-writes across microservices. Mandates that all tuple mutations occur atomically within the primary database transaction via a transactional outbox table streamed to OpenFGA via CDC (Change Data Capture) log tailing, while pairing read-after-write checks with contextual tuples or HIGHEST_CONSISTENCY evaluation parameters. 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 (Dual-Writing Application-Layer Authorization Tuples to OpenFGA Alongside Relational Transactions) 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