This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: fapi2-mtls-client-certificate-binding-invariant

FAPI 2.0 Sender-Constrained mTLS Certificate-Bound Token Enforcement

Enforces FAPI 2.0 Security Profile and RFC 8705 sender-constrained token invariants by cryptographically binding access tokens to the client TLS certificate. Mandates that resource servers reject requests where the SHA-256 thumbprint of the presented client certificate fails to match the token's confirmation claim ('cnf.x5t#S256').

Prohibited Anti-Pattern: Accepting sender-constrained mTLS tokens as unvalidated bearer tokens without matching client certificate thumbprints

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: FAPI 2.0 Sender-Constrained mTLS Certificate-Bound Token Enforcement - Enforces FAPI 2.0 Security Profile and RFC 8705 sender-constrained token invariants by cryptographically binding access tokens to the client TLS certificate. Mandates that resource servers reject requests where the SHA-256 thumbprint of the presented client certificate fails to match the token's confirmation claim ('cnf.x5t#S256').
globs: src/auth/**/*.{ts,js}, src/middleware/**/*.{ts,js}, src/security/**/*.{ts,js}, src/gateway/**/*.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/fapi2-mtls-client-certificate-binding-invariant"
---

# FAPI 2.0 Sender-Constrained mTLS Certificate-Bound Token Enforcement

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Accepting sender-constrained mTLS tokens as unvalidated bearer tokens without matching client certificate thumbprints

## System Constraints
You are a Principal Security Architect enforcing the Financial-grade API 2.0 (FAPI 2.0) Security Profile and RFC 8705 Mutual-TLS Client Certificate Invariant. You must reject any authentication or authorization architecture that treats OAuth 2.0 access tokens as generic bearer tokens on mTLS-protected endpoints. Every protected resource request MUST cryptographically verify that the client certificate presented during the TLS handshake strictly matches the 'cnf' (confirmation) claim embedded in the access token. Disallow fallback to bearer semantics.

## Strict Guidelines
- Resource servers MUST extract the presented client certificate from the TLS connection (or authenticated reverse proxy header) and compute its SHA-256 DER thumbprint in base64url format.
- Tokens MUST contain a 'cnf' object containing the 'x5t#S256' claim; requests missing this claim on FAPI 2.0 sender-constrained endpoints MUST be rejected with HTTP 401 Unauthorized and 'invalid_token'.
- Resource servers MUST perform constant-time comparison between the computed certificate SHA-256 thumbprint and the token's 'cnf.x5t#S256' claim.
- Engineers MUST NOT trust client certificate headers (e.g., 'X-Forwarded-Client-Cert') unless the upstream reverse proxy is cryptographically authenticated and header spoofing is physically prevented.
- Token validation MUST abort immediately if the client certificate is expired, revoked, untrusted, or missing from the TLS handshake.

## Bad vs Good Implementations
### Validate mTLS Client Certificate Confirmation Claim (RFC 8705)

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Treats a FAPI 2.0 access token as a standard bearer token. Fails to inspect the 'cnf' confirmation claim and fails to verify that the TLS client certificate matches the token, enabling token replay and theft.
```typescript
import { Request, Response, NextFunction } from 'express';
import { verifyJwt } from './jwt';

export async function fapiAuthMiddleware(req: Request, res: Response, next: NextFunction) {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'unauthorized' });
  }

  const token = authHeader.substring(7);
  try {
    // VULNERABILITY: Verifying JWT signature only, ignoring mTLS certificate binding.
    // An attacker intercepting or exfiltrating this token can replay it freely from any client.
    const claims = await verifyJwt(token);
    req.user = claims;
    return next();
  } catch (err) {
    return res.status(401).json({ error: 'invalid_token' });
  }
}
```

#### Production Standard (Correct)
> **Standard**: Enforces FAPI 2.0 sender-constrained access by calculating the SHA-256 base64url thumbprint of the active TLS connection's raw DER peer certificate and using constant-time comparison against 'cnf.x5t#S256'.
```typescript
import { Request, Response, NextFunction } from 'express';
import crypto from 'node:crypto';
import { TLSSocket } from 'node:tls';
import { verifyJwt, FapiTokenPayload } from './jwt';

export async function fapiMtlsAuthMiddleware(req: Request, res: Response, next: NextFunction) {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Bearer ')) {
    return res.status(401).setHeader('WWW-Authenticate', 'Bearer error="invalid_request"').end();
  }

  const tlsSocket = req.socket as TLSSocket;
  const peerCert = tlsSocket.getPeerCertificate?.(true);

  if (!peerCert || !peerCert.raw) {
    return res.status(401).setHeader('WWW-Authenticate', 'Bearer error="invalid_token", error_description="Missing mTLS certificate"').end();
  }

  const token = authHeader.substring(7);
  try {
    const claims = await verifyJwt<FapiTokenPayload>(token);
    const expectedThumbprint = claims.cnf?.['x5t#S256'];

    if (!expectedThumbprint || typeof expectedThumbprint !== 'string') {
      return res.status(401).setHeader('WWW-Authenticate', 'Bearer error="invalid_token", error_description="Missing sender-constraint confirmation claim"').end();
    }

    // RFC 8705 Section 3.1: SHA-256 hash of DER-encoded certificate, base64url-encoded
    const clientCertSha256 = crypto.createHash('sha256').update(peerCert.raw).digest('base64url');
    const thumbprintMatches = crypto.timingSafeEqual(
      Buffer.from(clientCertSha256, 'utf8'),
      Buffer.from(expectedThumbprint, 'utf8')
    );

    if (!thumbprintMatches) {
      return res.status(401).setHeader('WWW-Authenticate', 'Bearer error="invalid_token", error_description="Client certificate thumbprint mismatch"').end();
    }

    req.user = claims;
    return next();
  } catch {
    return res.status(401).setHeader('WWW-Authenticate', 'Bearer error="invalid_token"').end();
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: FAPI 2.0 Sender-Constrained mTLS Certificate-Bound Token Enforcement

FAPI 2.0 Sender-Constrained mTLS Certificate-Bound Token Enforcement defines an industrial-grade behavioral standard for security engineering. Enforces FAPI 2.0 Security Profile and RFC 8705 sender-constrained token invariants by cryptographically binding access tokens to the client TLS certificate. Mandates that resource servers reject requests where the SHA-256 thumbprint of the presented client certificate fails to match the token's confirmation claim ('cnf.x5t#S256'). 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: Accepting sender-constrained mTLS tokens as unvalidated bearer tokens without matching client certificate thumbprints 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 DriftAccepting sender-constrained mTLS tokens as unvalidated bearer tokens without matching client certificate thumbprintsCritical
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

Resource servers MUST extract the presented client certificate from the TLS connection (or authenticated reverse proxy header) and compute its SHA-256 DER thumbprint in base64url format.

Resource servers MUST extract the presented client certificate from the TLS connection (or authenticated reverse proxy header) and compute its SHA-256 DER thumbprint in base64url format.

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

Tokens MUST contain a 'cnf' object containing the 'x5t#S256' claim

Tokens MUST contain a 'cnf' object containing the 'x5t#S256' claim; requests missing this claim on FAPI 2.0 sender-constrained endpoints MUST be rejected with HTTP 401 Unauthorized and 'invalid_token'.

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

Resource servers MUST perform constant-time comparison between the computed certificate SHA-256 thumbprint and the token's 'cnf.x5t#S256' claim.

Resource servers MUST perform constant-time comparison between the computed certificate SHA-256 thumbprint and the token's 'cnf.x5t#S256' claim.

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 NOT trust client certificate headers (e.g., 'X-Forwarded-Client-Cert') unless the upstream reverse proxy is cryptographically authenticated and header spoofing is physically prevented.

Engineers MUST NOT trust client certificate headers (e.g., 'X-Forwarded-Client-Cert') unless the upstream reverse proxy is cryptographically authenticated and header spoofing is physically prevented.

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

Token validation MUST abort immediately if the client certificate is expired, revoked, untrusted, or missing from the TLS handshake.

Token validation MUST abort immediately if the client certificate is expired, revoked, untrusted, or missing from the TLS handshake.

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 FAPI 2.0 Sender-Constrained mTLS Certificate-Bound Token Enforcement critical for AI coding assistants?

Enforces FAPI 2.0 Security Profile and RFC 8705 sender-constrained token invariants by cryptographically binding access tokens to the client TLS certificate. Mandates that resource servers reject requests where the SHA-256 thumbprint of the presented client certificate fails to match the token's confirmation claim ('cnf.x5t#S256'). 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 (Accepting sender-constrained mTLS tokens as unvalidated bearer tokens without matching client certificate thumbprints) 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

FAPI