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

OpenFGA CDC Outbox Strict Tuple Serialization Pipeline Standard

Enforces dual-write prevention and guarantees absolute authorization state consistency between application databases and OpenFGA stores via a transactional outbox CDC pipeline. Prohibits direct dual-writing to OpenFGA API endpoints within application boundary business logic to prevent authorization drift under partial failure modes.

Prohibited Anti-Pattern: Dual-Writing Authorization Tuples Directly to OpenFGA API Alongside Primary Database Transactions

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenFGA CDC Outbox Strict Tuple Serialization Pipeline Standard - Enforces dual-write prevention and guarantees absolute authorization state consistency between application databases and OpenFGA stores via a transactional outbox CDC pipeline. Prohibits direct dual-writing to OpenFGA API endpoints within application boundary business logic to prevent authorization drift under partial failure modes.
globs: src/**/*.ts, src/**/*.service.ts, src/**/*.repository.ts, src/outbox/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-cdc-outbox-strict-tuple-serialization"
---

# OpenFGA CDC Outbox Strict Tuple Serialization Pipeline Standard

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Dual-Writing Authorization Tuples Directly to OpenFGA API Alongside Primary Database Transactions

## System Constraints
You are a Principal Security Architect enforcing the OpenFGA CDC Outbox Strict Tuple Serialization Pipeline. Direct OpenFGA API writes (writeTuples/deleteTuples) inside primary business transactions or HTTP request cycles are catastrophic vulnerabilities causing permanent authorization state drift when one operation fails. Mandate transactional outbox persistence where authorization tuple mutations are atomically committed to the primary relational store within the same database transaction as business entities, and subsequently published via Change Data Capture (Debezium/Kafka) with deterministic idempotency keys and strict ordering guarantees.

## Strict Guidelines
- Engineers MUST ALWAYS write tuple mutations (user, relation, object) directly into the local `fga_outbox` table within the active database transaction encompassing the domain model mutation.
- Engineers MUST NOT invoke OpenFGA client write endpoints (`fgaClient.write`, `writeTuples`) directly from REST/GraphQL controllers, RPC handlers, or standard application service layers.
- Code SHOULD enforce deterministic serialization of OpenFGA tuple keys (canonical casing, strict string delimitation `type:id#relation@type:id`) prior to committing to the outbox table.
- Services MUST process outbox events via CDC workers with at-least-once delivery, strictly scoped monotonic sequence keys or partition keys based on `object` namespace to maintain write ordering.
- Components NEVER drop or skip outbox records on OpenFGA API write rejection; unrecoverable serialization failures MUST redirect to an isolated dead-letter queue (DLQ) with automated alert triage.

## Bad vs Good Implementations
### Dual-Write Vulnerability vs. Transactional Outbox Tuple Persistence

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Performing DB mutation and OpenFGA write as distinct steps introduces partial failure states. If the OpenFGA network write fails, the document has a new owner in the database but the previous owner retains access control rights in OpenFGA.
```typescript
import { OpenFgaClient } from '@openfga/sdk';
import { DataSource, EntityManager } from 'typeorm';

export class DocumentService {
  constructor(
    private readonly dataSource: DataSource,
    private readonly fgaClient: OpenFgaClient
  ) {}

  async transferDocumentOwnership(docId: string, oldOwnerId: string, newOwnerId: string): Promise<void> {
    // ANTI-PATTERN: Dual-write hazard. DB updates commit, but OpenFGA may fail,
    // or OpenFGA succeeds while DB crashes, causing irrecoverable permission desynchronization.
    await this.dataSource.transaction(async (manager: EntityManager) => {
      await manager.update('documents', { id: docId }, { ownerId: newOwnerId });
    });

    // CRITICAL BUG: Outside transaction; if network fails, ownership changes in DB but RBAC stays stale
    await this.fgaClient.write({
      writes: [{ user: `user:${newOwnerId}`, relation: 'owner', object: `document:${docId}` }],
      deletes: [{ user: `user:${oldOwnerId}`, relation: 'owner', object: `document:${docId}` }],
    });
  }
}
```

#### Production Standard (Correct)
> **Standard**: By staging OpenFGA tuple operations directly inside the `fga_outbox` relational table in the same transaction, atomic consistency is guaranteed. Downstream CDC consumers read this log and reliably replay changes to OpenFGA with partitioned ordering.
```typescript
import { DataSource, EntityManager } from 'typeorm';

interface FgaOutboxRecord {
  id: string;
  operation: 'WRITE' | 'DELETE';
  user: string;
  relation: string;
  object: string;
  partitionKey: string;
  createdAt: Date;
}

export class DocumentService {
  constructor(private readonly dataSource: DataSource) {}

  async transferDocumentOwnership(docId: string, oldOwnerId: string, newOwnerId: string): Promise<void> {
    await this.dataSource.transaction(async (manager: EntityManager) => {
      // 1. Mutate primary domain state
      await manager.update('documents', { id: docId }, { ownerId: newOwnerId });

      const docObject = `document:${docId}`;

      // 2. Atomically persist authorization deltas in same relational transaction
      const outboxEntries: Array<Omit<FgaOutboxRecord, 'id' | 'createdAt'>> = [
        {
          operation: 'DELETE',
          user: `user:${oldOwnerId}`,
          relation: 'owner',
          object: docObject,
          partitionKey: docObject,
        },
        {
          operation: 'WRITE',
          user: `user:${newOwnerId}`,
          relation: 'owner',
          object: docObject,
          partitionKey: docObject,
        },
      ];

      await manager.createQueryBuilder()
        .insert()
        .into('fga_outbox')
        .values(outboxEntries)
        .execute();
    });
    // Debezium / CDC tailer processes fga_outbox strictly ordered by partitionKey
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenFGA CDC Outbox Strict Tuple Serialization Pipeline Standard

OpenFGA CDC Outbox Strict Tuple Serialization Pipeline Standard defines an industrial-grade behavioral standard for security engineering. Enforces dual-write prevention and guarantees absolute authorization state consistency between application databases and OpenFGA stores via a transactional outbox CDC pipeline. Prohibits direct dual-writing to OpenFGA API endpoints within application boundary business logic to prevent authorization drift under partial failure modes. 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 Authorization Tuples Directly to OpenFGA API Alongside Primary Database 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 Authorization Tuples Directly to OpenFGA API Alongside Primary Database 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 ALWAYS write tuple mutations (user, relation, object) directly into the local `fga_outbox` table within the active database transaction encompassing the domain model mutation.

Engineers MUST ALWAYS write tuple mutations (user, relation, object) directly into the local `fga_outbox` table within the active database transaction encompassing the domain model 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.
2

Engineers MUST NOT invoke OpenFGA client write endpoints (`fgaClient.write`, `writeTuples`) directly from REST/GraphQL controllers, RPC handlers, or standard application service layers.

Engineers MUST NOT invoke OpenFGA client write endpoints (`fgaClient.write`, `writeTuples`) directly from REST/GraphQL controllers, RPC handlers, or standard application service layers.

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

Code SHOULD enforce deterministic serialization of OpenFGA tuple keys (canonical casing, strict string delimitation `type

Code SHOULD enforce deterministic serialization of OpenFGA tuple keys (canonical casing, strict string delimitation `type:id#relation@type:id`) prior to committing to the outbox table.

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

Services MUST process outbox events via CDC workers with at-least-once delivery, strictly scoped monotonic sequence keys or partition keys based on `object` namespace to maintain write ordering.

Services MUST process outbox events via CDC workers with at-least-once delivery, strictly scoped monotonic sequence keys or partition keys based on `object` namespace to maintain write ordering.

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 drop or skip outbox records on OpenFGA API write rejection

Components NEVER drop or skip outbox records on OpenFGA API write rejection; unrecoverable serialization failures MUST redirect to an isolated dead-letter queue (DLQ) with automated alert triage.

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 CDC Outbox Strict Tuple Serialization Pipeline Standard critical for AI coding assistants?

Enforces dual-write prevention and guarantees absolute authorization state consistency between application databases and OpenFGA stores via a transactional outbox CDC pipeline. Prohibits direct dual-writing to OpenFGA API endpoints within application boundary business logic to prevent authorization drift under partial failure modes. 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 Authorization Tuples Directly to OpenFGA API Alongside Primary Database 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