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

OpenFGA Dynamic Contextual Tuple Latency Budget and Cycle Invariant

Restricts dynamic contextual tuple generation and graph resolution depth during OpenFGA authorization checks at edge API gateways. Mandates strict cardinality caps, cycle detection, and hard timeout budgets to prevent ReDoS-style graph traversal exhaustion and maintain sub-millisecond perimeter evaluation latencies.

Prohibited Anti-Pattern: Unbounded Contextual Tuple Injection Causing Graph Traversal Cascades and Perimeter Denial-of-Service

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenFGA Dynamic Contextual Tuple Latency Budget and Cycle Invariant - Restricts dynamic contextual tuple generation and graph resolution depth during OpenFGA authorization checks at edge API gateways. Mandates strict cardinality caps, cycle detection, and hard timeout budgets to prevent ReDoS-style graph traversal exhaustion and maintain sub-millisecond perimeter evaluation latencies.
globs: src/middleware/**/*.{ts,tsx}, src/security/**/*.{ts,tsx}, src/auth/**/*.{ts,tsx}, src/gateways/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/openfga-contextual-tuple-latency-budget-standard"
---

# OpenFGA Dynamic Contextual Tuple Latency Budget and Cycle Invariant

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Unbounded Contextual Tuple Injection Causing Graph Traversal Cascades and Perimeter Denial-of-Service

## System Constraints
You are a Principal Security Architect enforcing the OpenFGA Dynamic Contextual Tuple Latency Budget Standard. Dynamic contextual tuples injected during authorization checks at perimeter gateways bypass persistent store indexes and force the OpenFGA evaluation engine into in-memory recursive graph traversals. You must reject any code pattern that dynamically constructs unbounded contextual tuples, permits self-referential or cyclic edge insertion, lacks strict tuple cardinality guards (maximum 16 tuples), or fails to configure explicit per-check millisecond timeout budgets with fail-closed fallback semantics.

## Strict Guidelines
- Engineers MUST ALWAYS enforce a hard cardinality limit (maximum 16 tuples) on dynamic contextual tuples passed to OpenFGA check evaluations.
- Engineers MUST ALWAYS pre-validate contextual tuples to eliminate reflexive self-references (where object equals user) and cyclic directed relations prior to evaluation dispatch.
- Engineers MUST ALWAYS supply an explicit AbortSignal with a strict latency budget (maximum 5ms at gateway perimeters) to every OpenFGA check request.
- Services MUST fail closed with a 403 Forbidden or 504 Gateway Timeout if contextual tuple evaluation exceeds the configured latency budget or fails due to an abort signal.
- Engineers MUST NOT map raw, unvalidated HTTP request payloads, claims, or header parameters directly into contextual tuple definitions.
- Components NEVER permit recursive graph expansions or wildcard object references within transient contextual tuples.

## Bad vs Good Implementations
### Contextual Tuple Edge Guard with Latency Budget and Cycle Suppression

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Accepting arbitrary arrays from untrusted clients directly into contextualTuples allows an attacker to inject hundreds of tuples or cyclic references. This triggers recursive graph traversal in OpenFGA, exhausting CPU, spiking latency to seconds, and inducing a denial-of-service at the gateway with no timeout safeguards.
```typescript
import { OpenFgaClient } from '@openfga/sdk';
import { Request, Response, NextFunction } from 'express';

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

export async function authorizeBad(req: Request, res: Response, next: NextFunction) {
  // VULNERABILITY: Directly injects client-provided contextual relations without
  // bounds checking, cycle detection, or request-scoped timeouts.
  const dynamicContext = req.body.dynamicTenants.map((tenantId: string) => ({
    user: `user:${req.headers['x-user-id']}`,
    relation: 'member',
    object: `tenant:${tenantId}`,
  }));

  const { allowed } = await fgaClient.check({
    user: `user:${req.headers['x-user-id']}`,
    relation: 'can_access',
    object: `workspace:${req.params.workspaceId}`,
    contextualTuples: dynamicContext,
  });

  if (!allowed) {
    return res.status(403).json({ error: 'Forbidden' });
  }
  next();
}
```

#### Production Standard (Correct)
> **Standard**: Enforces a strict upper bound of 16 contextual tuples, validates regex formats, discards self-referential cycles and duplicate edges, and bounds the evaluation with an explicit 5ms AbortController timeout. Fails closed immediately upon exhaustion or timeout.
```typescript
import { OpenFgaClient, ClientCheckRequest, TupleKey } from '@openfga/sdk';
import { Request, Response, NextFunction } from 'express';

const MAX_CONTEXTUAL_TUPLES = 16;
const REBAC_TIMEOUT_MS = 5;

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

function sanitizeAndValidateTuples(userId: string, rawTenants: unknown): TupleKey[] {
  if (!Array.isArray(rawTenants)) return [];
  
  if (rawTenants.length > MAX_CONTEXTUAL_TUPLES) {
    throw new Error(`Contextual tuple cardinality exceeds perimeter limit of ${MAX_CONTEXTUAL_TUPLES}`);
  }

  const userUrn = `user:${userId}`;
  const validated: TupleKey[] = [];
  const seenObjects = new Set<string>();

  for (const tenantId of rawTenants) {
    if (typeof tenantId !== 'string' || !/^[a-zA-Z0-9_-]{1,64}$/.test(tenantId)) {
      throw new Error('Malformed tenant identifier in contextual relationship');
    }
    const objectUrn = `tenant:${tenantId}`;
    // Invariant: Disallow self-referential cycles and duplicate directed edges
    if (objectUrn === userUrn || seenObjects.has(objectUrn)) {
      continue;
    }
    seenObjects.add(objectUrn);
    validated.push({
      user: userUrn,
      relation: 'member',
      object: objectUrn,
    });
  }

  return validated;
}

export async function authorizeGood(req: Request, res: Response, next: NextFunction) {
  const rawUserId = req.headers['x-user-id'];
  if (typeof rawUserId !== 'string' || !rawUserId) {
    return res.status(401).json({ error: 'Unauthorized: Missing identity context' });
  }

  let contextualTuples: TupleKey[];
  try {
    contextualTuples = sanitizeAndValidateTuples(rawUserId, req.body?.dynamicTenants);
  } catch (err) {
    return res.status(400).json({ error: 'Invalid contextual relationship payload' });
  }

  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), REBAC_TIMEOUT_MS);

  try {
    const checkPayload: ClientCheckRequest = {
      user: `user:${rawUserId}`,
      relation: 'can_access',
      object: `workspace:${req.params.workspaceId}`,
      contextualTuples,
    };

    const response = await fgaClient.check(checkPayload, {
      signal: controller.signal,
    });

    if (!response.allowed) {
      return res.status(403).json({ error: 'Forbidden' });
    }
    return next();
  } catch (error: unknown) {
    // Fail closed on timeouts or downstream traversal errors
    return res.status(403).json({ error: 'Access evaluation terminated or budget exceeded' });
  } finally {
    clearTimeout(timer);
  }
}
```

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 Dynamic Contextual Tuple Latency Budget and Cycle Invariant

OpenFGA Dynamic Contextual Tuple Latency Budget and Cycle Invariant defines an industrial-grade behavioral standard for security engineering. Restricts dynamic contextual tuple generation and graph resolution depth during OpenFGA authorization checks at edge API gateways. Mandates strict cardinality caps, cycle detection, and hard timeout budgets to prevent ReDoS-style graph traversal exhaustion and maintain sub-millisecond perimeter evaluation latencies. 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 Contextual Tuple Injection Causing Graph Traversal Cascades and Perimeter Denial-of-Service 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 Contextual Tuple Injection Causing Graph Traversal Cascades and Perimeter Denial-of-ServiceCritical
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 a hard cardinality limit (maximum 16 tuples) on dynamic contextual tuples passed to OpenFGA check evaluations.

Engineers MUST ALWAYS enforce a hard cardinality limit (maximum 16 tuples) on dynamic contextual tuples passed to 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.
2

Engineers MUST ALWAYS pre-validate contextual tuples to eliminate reflexive self-references (where object equals user) and cyclic directed relations prior to evaluation dispatch.

Engineers MUST ALWAYS pre-validate contextual tuples to eliminate reflexive self-references (where object equals user) and cyclic directed relations prior to evaluation dispatch.

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 ALWAYS supply an explicit AbortSignal with a strict latency budget (maximum 5ms at gateway perimeters) to every OpenFGA check request.

Engineers MUST ALWAYS supply an explicit AbortSignal with a strict latency budget (maximum 5ms at gateway perimeters) to every OpenFGA check request.

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 with a 403 Forbidden or 504 Gateway Timeout if contextual tuple evaluation exceeds the configured latency budget or fails due to an abort signal.

Services MUST fail closed with a 403 Forbidden or 504 Gateway Timeout if contextual tuple evaluation exceeds the configured latency budget or fails due to an abort signal.

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

Engineers MUST NOT map raw, unvalidated HTTP request payloads, claims, or header parameters directly into contextual tuple definitions.

Engineers MUST NOT map raw, unvalidated HTTP request payloads, claims, or header parameters directly into contextual tuple definitions.

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

Components NEVER permit recursive graph expansions or wildcard object references within transient contextual tuples.

Components NEVER permit recursive graph expansions or wildcard object references within transient contextual tuples.

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 Dynamic Contextual Tuple Latency Budget and Cycle Invariant critical for AI coding assistants?

Restricts dynamic contextual tuple generation and graph resolution depth during OpenFGA authorization checks at edge API gateways. Mandates strict cardinality caps, cycle detection, and hard timeout budgets to prevent ReDoS-style graph traversal exhaustion and maintain sub-millisecond perimeter evaluation latencies. 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 Contextual Tuple Injection Causing Graph Traversal Cascades and Perimeter Denial-of-Service) 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