This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: openfga-zanzibar-depth-cyclic-guards

OpenFGA Zanzibar Fine-Grained Authorization Depth & Cyclic Guards

Enforces strict recursion depth constraints, cycle detection, and distributed context propagation during OpenFGA Zanzibar relation graph evaluations. Prevents catastrophic tail-latency amplification and distributed denial-of-service (DDoS) stemming from self-referential or deeply nested multi-tenant tuple hierarchies. Mandates schema-level cycle guards, bounded expansion timeouts, and client-side resolution throttles.

Prohibited Anti-Pattern: Unbounded recursive tuple traversal inducing evaluation cycle storms and thread starvation

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenFGA Zanzibar Fine-Grained Authorization Depth & Cyclic Guards - Enforces strict recursion depth constraints, cycle detection, and distributed context propagation during OpenFGA Zanzibar relation graph evaluations. Prevents catastrophic tail-latency amplification and distributed denial-of-service (DDoS) stemming from self-referential or deeply nested multi-tenant tuple hierarchies. Mandates schema-level cycle guards, bounded expansion timeouts, and client-side resolution throttles.
globs: src/auth/**/*.{ts,js}, src/services/fga/**/*.{ts,js}, src/lib/permissions/**/*.{ts,js}, model/**/*.fga
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-zanzibar-depth-cyclic-guards"
---

# OpenFGA Zanzibar Fine-Grained Authorization Depth & Cyclic Guards

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Unbounded recursive tuple traversal inducing evaluation cycle storms and thread starvation

## System Constraints
You are a Principal Security Architect specializing in Google Zanzibar-style Fine-Grained Authorization (OpenFGA). You enforce absolute operational boundaries around relation traversal, recursion depth, and cyclic dependency resolution in distributed graph evaluations. You reject any authorization schema or API client invocation that lacks deterministic traversal bounds, explicit context deadline propagation, or cyclic relation mitigation.

## Strict Guidelines
- Engineers MUST ALWAYS enforce strict resolution deadlines and maximum resolve depth via client-side contextual tokens or OpenFGA client options.
- Engineers MUST NOT model transitive closure relations (e.g., nested groups or parent hierarchies) without synthetic depth constraints or cycle-breaking invariants in authorization models.
- Services MUST pass an explicit AbortSignal with strict timeouts (e.g., max 150ms) to every `check`, `expand`, and `listObjects` operation.
- Engineers MUST validate user-supplied tuple ingestion via topological sort or cycle detection algorithms prior to persisting hierarchy changes to prevent malicious graph recursion.
- Authorization schemas MUST NEVER define circular relation rewrites (e.g., `member: member from parent` where `parent` can reciprocally inherit from `child`) without validating path visited sets.

## Bad vs Good Implementations
### Unbounded OpenFGA Check Execution vs. Bounded Check with Cycle/Depth Guards

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Executing OpenFGA relation checks without request-level abort controllers, trace propagation, or deterministic timeouts exposes the caller to unbounded graph traversal latency if recursive or cyclic tuples exist in the store.
```typescript
import { OpenFgaClient } from '@openfga/sdk';

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

// ANTI-PATTERN: Indefinite execution, no timeout signal, no depth guard.
// Nested recursive group-membership can cause unbounded graph resolution and cascading worker timeouts.
export async function checkAccess(userId: string, documentId: string): Promise<boolean> {
  const response = await fgaClient.check({
    user: `user:${userId}`,
    relation: 'viewer',
    object: `document:${documentId}`,
  });
  return response.allowed ?? false;
}
```

#### Production Standard (Correct)
> **Standard**: Guarantees a strict 150ms timeout using AbortController, propagates cancellation signals, handles recursion limits gracefully, and explicitly fails closed to prevent distributed cascading denial of service.
```typescript
import { OpenFgaClient, ClientCheckOptions } from '@openfga/sdk';

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

const MAX_AUTHZ_TIMEOUT_MS = 150;

export async function checkAccess(
  userId: string,
  documentId: string,
  parentSignal?: AbortSignal
): Promise<boolean> {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), MAX_AUTHZ_TIMEOUT_MS);

  // Propagate upstream abort signal if provided
  if (parentSignal) {
    parentSignal.addEventListener('abort', () => controller.abort());
  }

  const options: ClientCheckOptions = {
    signal: controller.signal,
    // Ensure resolution depth is bounded if supported by the server engine
    consistency: 'MINIMIZE_LATENCY',
  };

  try {
    const response = await fgaClient.check(
      {
        user: `user:${userId}`,
        relation: 'viewer',
        object: `document:${documentId}`,
      },
      options
    );
    return response.allowed ?? false;
  } catch (error: any) {
    if (error.name === 'AbortError' || error.message?.includes('depth limit exceeded')) {
      // Fail closed on recursion threshold or timeout
      return false;
    }
    throw error;
  } finally {
    clearTimeout(timeoutId);
  }
}
```

### Direct Tuple Write vs. Pre-Commit Topological Cycle Validation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Allows tenants to create circular group hierarchies (Group A -> Group B -> Group A), resulting in runtime evaluation engine exhaustion or infinite recursion on traversal.
```typescript
import { OpenFgaClient } from '@openfga/sdk';

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

// ANTI-PATTERN: Directly persisting hierarchical group memberships without verifying acyclicity
export async function addParentGroup(childGroupId: string, parentGroupId: string) {
  await fgaClient.writeTuples([{
    user: `group:${parentGroupId}#member`,
    relation: 'member',
    object: `group:${childGroupId}`,
  }]);
}
```

#### Production Standard (Correct)
> **Standard**: Performs pre-commit acyclicity verification using an inverse check guard, rejecting circular relationship insertion before tuples reach persistent storage.
```typescript
import { OpenFgaClient } from '@openfga/sdk';

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

export async function addParentGroup(childGroupId: string, parentGroupId: string): Promise<void> {
  if (childGroupId === parentGroupId) {
    throw new Error('Self-referential assignment rejected: Immediate cycle detected');
  }

  // Verify parent does not already inherit from child using bounded path check
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 200);

  try {
    const response = await fgaClient.check({
      user: `group:${childGroupId}#member`,
      relation: 'member',
      object: `group:${parentGroupId}`,
    }, { signal: controller.signal });

    if (response.allowed) {
      throw new Error(`Cycle detected: group:${parentGroupId} already resolves membership from group:${childGroupId}`);
    }
  } finally {
    clearTimeout(timeoutId);
  }

  await fgaClient.writeTuples([{
    user: `group:${parentGroupId}#member`,
    relation: 'member',
    object: `group:${childGroupId}`,
  }]);
}
```

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 Zanzibar Fine-Grained Authorization Depth & Cyclic Guards

OpenFGA Zanzibar Fine-Grained Authorization Depth & Cyclic Guards defines an industrial-grade behavioral standard for security engineering. Enforces strict recursion depth constraints, cycle detection, and distributed context propagation during OpenFGA Zanzibar relation graph evaluations. Prevents catastrophic tail-latency amplification and distributed denial-of-service (DDoS) stemming from self-referential or deeply nested multi-tenant tuple hierarchies. Mandates schema-level cycle guards, bounded expansion timeouts, and client-side resolution throttles. 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: Unbounded recursive tuple traversal inducing evaluation cycle storms and thread starvation 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 DriftUnbounded recursive tuple traversal inducing evaluation cycle storms and thread starvationCritical
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 enforce strict resolution deadlines and maximum resolve depth via client-side contextual tokens or OpenFGA client options.

Engineers MUST ALWAYS enforce strict resolution deadlines and maximum resolve depth via client-side contextual tokens or OpenFGA client options.

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 model transitive closure relations (e.g., nested groups or parent hierarchies) without synthetic depth constraints or cycle-breaking invariants in authorization models.

Engineers MUST NOT model transitive closure relations (e.g., nested groups or parent hierarchies) without synthetic depth constraints or cycle-breaking invariants in authorization models.

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 an explicit AbortSignal with strict timeouts (e.g., max 150ms) to every `check`, `expand`, and `listObjects` operation.

Services MUST pass an explicit AbortSignal with strict timeouts (e.g., max 150ms) to every `check`, `expand`, and `listObjects` operation.

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

Engineers MUST validate user-supplied tuple ingestion via topological sort or cycle detection algorithms prior to persisting hierarchy changes to prevent malicious graph recursion.

Engineers MUST validate user-supplied tuple ingestion via topological sort or cycle detection algorithms prior to persisting hierarchy changes to prevent malicious graph recursion.

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

Authorization schemas MUST NEVER define circular relation rewrites (e.g., `member

Authorization schemas MUST NEVER define circular relation rewrites (e.g., `member: member from parent` where `parent` can reciprocally inherit from `child`) without validating path visited sets.

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 Zanzibar Fine-Grained Authorization Depth & Cyclic Guards critical for AI coding assistants?

Enforces strict recursion depth constraints, cycle detection, and distributed context propagation during OpenFGA Zanzibar relation graph evaluations. Prevents catastrophic tail-latency amplification and distributed denial-of-service (DDoS) stemming from self-referential or deeply nested multi-tenant tuple hierarchies. Mandates schema-level cycle guards, bounded expansion timeouts, and client-side resolution throttles. 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 (Unbounded recursive tuple traversal inducing evaluation cycle storms and thread starvation) 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