This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: openfga-contextual-tuple-cycle-interceptor

Mandatory Contextual Tuple DAG Cycle Detection and Traversal Deadlines in OpenFGA

Contextual tuples passed dynamically into OpenFGA authorization checks can introduce cyclic relationships and deep recursive graphs that cause algorithmic denial-of-service (ReDoS/Graph DoS) and thread starvation. Authorization services must enforce pre-dispatch directed acyclic graph (DAG) cycle interception and strict, non-negotiable evaluation timeouts on every recursive check call.

Prohibited Anti-Pattern: Unchecked Runtime Contextual Tuples Injected Directly into OpenFGA Check Calls Causing Recursive Graph Loops

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Mandatory Contextual Tuple DAG Cycle Detection and Traversal Deadlines in OpenFGA - Contextual tuples passed dynamically into OpenFGA authorization checks can introduce cyclic relationships and deep recursive graphs that cause algorithmic denial-of-service (ReDoS/Graph DoS) and thread starvation. Authorization services must enforce pre-dispatch directed acyclic graph (DAG) cycle interception and strict, non-negotiable evaluation timeouts on every recursive check call.
globs: src/auth/**/*.ts, src/security/**/*.ts, src/services/fga/**/*.ts, src/middleware/authorization*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-contextual-tuple-cycle-interceptor"
---

# Mandatory Contextual Tuple DAG Cycle Detection and Traversal Deadlines in OpenFGA

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Unchecked Runtime Contextual Tuples Injected Directly into OpenFGA Check Calls Causing Recursive Graph Loops

## System Constraints
You are a Principal Software Architect enforcing algorithmic DoS protections and graph cycle interceptors in fine-grained authorization layers using OpenFGA. You must ensure that runtime contextual tuples are validated as strict directed acyclic graphs (DAGs) and bound to deterministic timeouts before evaluation.

## Strict Guidelines
- Engineers MUST ALWAYS validate runtime contextual tuples for cycles using a directed-acyclic-graph (DAG) cycle detector before passing them to the OpenFGA client.
- Engineers MUST ALWAYS enforce a strict evaluation deadline (e.g., max 150ms) using AbortSignal or context cancellation on all OpenFGA check evaluations.
- Engineers MUST NOT allow unbounded contextual tuple counts; contextual tuple payloads MUST be capped to a strict maximum (e.g., <= 50 tuples per check).
- Services MUST fail closed (deny authorization) and log critical telemetry when a contextual cycle is intercepted or when a timeout deadline is reached.
- Components NEVER execute raw OpenFGA client check methods with unvalidated, caller-supplied contextual tuples directly from request payloads.

## Bad vs Good Implementations
### Unbounded Contextual Check vs. Cycle-Interception and Deadline-Enforced Traversal

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Passing untrusted contextual tuples directly into the OpenFGA check call allows malicious or malformed cyclic graph edges to consume authorization engine CPU and memory. The check lacks cycle pre-validation, tuple-size bounding, and explicit evaluation deadline enforcement via AbortSignal.
```typescript
import { OpenFgaClient, type ClientCheckRequest } from '@openfga/sdk';

export class UnsafeAuthorizationService {
  constructor(private readonly fgaClient: OpenFgaClient) {}

  // VULNERABLE: Direct passthrough of contextual tuples without cycle validation or timeouts
  async isAuthorized(user: string, relation: string, object: string, contextualTuples: Array<{ user: string; relation: string; object: string }>): Promise<boolean> {
    const payload: ClientCheckRequest = {
      user,
      relation,
      object,
      contextualTuples
    };

    // Algorithmic DoS risk: Cyclic contextual tuples (e.g., A -> parent -> B, B -> parent -> A)
    // cause infinite recursion or excessive engine latency without cooperative cancellation
    const response = await this.fgaClient.check(payload);
    return response.allowed ?? false;
  }
}
```

#### Production Standard (Correct)
> **Standard**: Validates runtime contextual tuples as a directed acyclic graph (DAG) using a 3-color cycle detection algorithm before evaluation, limits maximum allowed tuples, attaches an explicit 150ms timeout via AbortController, and strictly fails closed on any detection or cancellation.
```typescript
import { OpenFgaClient, type ClientCheckRequest } from '@openfga/sdk';

export interface ContextTuple {
  user: string;
  relation: string;
  object: string;
}

export class GraphCycleDetectedError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'GraphCycleDetectedError';
  }
}

export class SecureAuthorizationService {
  private static readonly MAX_CONTEXTUAL_TUPLES = 50;
  private static readonly EVALUATION_TIMEOUT_MS = 150;

  constructor(private readonly fgaClient: OpenFgaClient) {}

  private assertDirectedAcyclicGraph(tuples: ContextTuple[]): void {
    if (tuples.length > SecureAuthorizationService.MAX_CONTEXTUAL_TUPLES) {
      throw new Error(`Contextual tuple limit exceeded: max ${SecureAuthorizationService.MAX_CONTEXTUAL_TUPLES}`);
    }

    const adj = new Map<string, string[]>();
    for (const tuple of tuples) {
      const source = tuple.user;
      const target = tuple.object;
      if (!adj.has(source)) adj.set(source, []);
      adj.get(source)!.push(target);
    }

    // 0: Unvisited, 1: Visiting (in active recursion stack), 2: Fully visited
    const state = new Map<string, number>();

    const dfs = (node: string): boolean => {
      state.set(node, 1);
      for (const neighbor of adj.get(node) ?? []) {
        const neighborState = state.get(neighbor) ?? 0;
        if (neighborState === 1) return true;
        if (neighborState === 0 && dfs(neighbor)) return true;
      }
      state.set(node, 2);
      return false;
    };

    for (const node of adj.keys()) {
      if ((state.get(node) ?? 0) === 0) {
        if (dfs(node)) {
          throw new GraphCycleDetectedError(`Contextual graph cycle detected at node: ${node}`);
        }
      }
    }
  }

  async isAuthorized(
    user: string,
    relation: string,
    object: string,
    contextualTuples: ContextTuple[] = []
  ): Promise<boolean> {
    try {
      this.assertDirectedAcyclicGraph(contextualTuples);
    } catch (err) {
      // Fail closed on graph cycle or boundary breach
      return false;
    }

    const payload: ClientCheckRequest = {
      user,
      relation,
      object,
      contextualTuples
    };

    const abortController = new AbortController();
    const timeoutId = setTimeout(() => abortController.abort(), SecureAuthorizationService.EVALUATION_TIMEOUT_MS);

    try {
      const response = await this.fgaClient.check(payload, {
        signal: abortController.signal
      });
      return response.allowed ?? false;
    } catch (err) {
      // Fail closed on abort or traversal failure
      return false;
    } finally {
      clearTimeout(timeoutId);
    }
  }
}
```

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: Mandatory Contextual Tuple DAG Cycle Detection and Traversal Deadlines in OpenFGA

Mandatory Contextual Tuple DAG Cycle Detection and Traversal Deadlines in OpenFGA defines an industrial-grade behavioral standard for security engineering. Contextual tuples passed dynamically into OpenFGA authorization checks can introduce cyclic relationships and deep recursive graphs that cause algorithmic denial-of-service (ReDoS/Graph DoS) and thread starvation. Authorization services must enforce pre-dispatch directed acyclic graph (DAG) cycle interception and strict, non-negotiable evaluation timeouts on every recursive check call. 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: Unchecked Runtime Contextual Tuples Injected Directly into OpenFGA Check Calls Causing Recursive Graph Loops 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 DriftUnchecked Runtime Contextual Tuples Injected Directly into OpenFGA Check Calls Causing Recursive Graph LoopsCritical
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 validate runtime contextual tuples for cycles using a directed-acyclic-graph (DAG) cycle detector before passing them to the OpenFGA client.

Engineers MUST ALWAYS validate runtime contextual tuples for cycles using a directed-acyclic-graph (DAG) cycle detector before passing them to the OpenFGA client.

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 ALWAYS enforce a strict evaluation deadline (e.g., max 150ms) using AbortSignal or context cancellation on all OpenFGA check evaluations.

Engineers MUST ALWAYS enforce a strict evaluation deadline (e.g., max 150ms) using AbortSignal or context cancellation on all OpenFGA check evaluations.

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 NOT allow unbounded contextual tuple counts

Engineers MUST NOT allow unbounded contextual tuple counts; contextual tuple payloads MUST be capped to a strict maximum (e.g., <= 50 tuples per check).

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 fail closed (deny authorization) and log critical telemetry when a contextual cycle is intercepted or when a timeout deadline is reached.

Services MUST fail closed (deny authorization) and log critical telemetry when a contextual cycle is intercepted or when a timeout deadline is reached.

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 execute raw OpenFGA client check methods with unvalidated, caller-supplied contextual tuples directly from request payloads.

Components NEVER execute raw OpenFGA client check methods with unvalidated, caller-supplied contextual tuples directly from request payloads.

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 Mandatory Contextual Tuple DAG Cycle Detection and Traversal Deadlines in OpenFGA critical for AI coding assistants?

Contextual tuples passed dynamically into OpenFGA authorization checks can introduce cyclic relationships and deep recursive graphs that cause algorithmic denial-of-service (ReDoS/Graph DoS) and thread starvation. Authorization services must enforce pre-dispatch directed acyclic graph (DAG) cycle interception and strict, non-negotiable evaluation timeouts on every recursive check call. 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 (Unchecked Runtime Contextual Tuples Injected Directly into OpenFGA Check Calls Causing Recursive Graph Loops) 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

Mandatory