This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: capacitor-7-native-bridge-memory-zeroization

Capacitor 7 Native Bridge Memory Zeroization Standard

Enforces deterministic in-memory cryptographic zeroization of transient biometric payloads, cryptographic keys, and authentication tokens across the Capacitor 7 JavaScript-to-Native bridge. Mandates byte-array manipulation over immutable strings to eliminate memory retention risks in V8/JSC heaps and native memory segments. Prohibits persistence or garbage-collector dependence for high-entropy secrets.

Prohibited Anti-Pattern: Passing Secrets via Immutable JS Strings and Un-Zeroed Bridge Dictionaries

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Capacitor 7 Native Bridge Memory Zeroization Standard - Enforces deterministic in-memory cryptographic zeroization of transient biometric payloads, cryptographic keys, and authentication tokens across the Capacitor 7 JavaScript-to-Native bridge. Mandates byte-array manipulation over immutable strings to eliminate memory retention risks in V8/JSC heaps and native memory segments. Prohibits persistence or garbage-collector dependence for high-entropy secrets.
globs: src/**/*.{ts,tsx}, ios/App/App/**/*.swift, android/app/src/main/java/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/capacitor-7-native-bridge-memory-zeroization"
---

# Capacitor 7 Native Bridge Memory Zeroization Standard

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Passing Secrets via Immutable JS Strings and Un-Zeroed Bridge Dictionaries

## System Constraints
You are a Principal Mobile Systems Architect and Security Engineer enforcing the Capacitor 7 Native Bridge Memory Zeroization Standard. Capacitor serializes bridge messages across the JavaScript-to-Native boundary, frequently stranding sensitive credentials in heap allocations governed solely by unpredictable garbage collectors. You must strictly mandate that all biometric tokens, master keys, passkeys, and authentication payloads transition via explicit Uint8Array byte buffers, which are overwritten with zeros immediately upon dispatch or consumption. Immutable strings must never hold raw secrets. Native endpoints in Swift and Kotlin must perform defensive copies into native memory, perform cryptographic memset operations, and clear Capacitor JSObject/PluginCall dictionaries post-invocation.

## Strict Guidelines
- Engineers MUST ALWAYS transmit transient biometric payloads, session keys, and sensitive tokens as raw byte buffers (Uint8Array or ArrayBuffer) rather than immutable strings to enable explicit in-memory wiping.
- Engineers MUST ALWAYS explicitly zeroize byte buffers in JavaScript using crypto.getRandomValues() followed by buffer.fill(0) inside a guaranteed `finally` block immediately after calling the Capacitor bridge.
- Engineers MUST NOT allow secrets to traverse the Capacitor 7 bridge serialized within JSON strings or standard object dictionaries that rely on non-deterministic V8/JavaScriptCore garbage collection.
- Native Swift plugins MUST pin incoming byte arrays into UnsafeMutableRawBufferPointer, perform the cryptographic operation, and invoke `memset_s` or `sodium_memzero` before releasing the buffer.
- Native Android (Kotlin) plugins MUST consume incoming byte arrays directly, wrap them in cleanable native ByteBuffer allocations or primitive ByteArray segments, and execute `Arrays.fill(bytes, 0.toByte())` in a defensive `finally` block.
- Services MUST reject any bridge call where authentication tokens or cryptographic materials remain resident in memory beyond the single invocation lifecycle.

## Bad vs Good Implementations
### Biometric Token Bridge Serialization and Zeroization

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Strings in JavaScript are immutable. Storing high-entropy tokens or biometric outcomes in plain strings prevents explicit memory wiping. The token remains resident in heap dumps until non-deterministic garbage collection occurs, exposing it to memory extraction attacks.
```typescript
import { registerPlugin } from '@capacitor/core';

interface SecureVaultPlugin {
  authenticateBiometrics(options: { challenge: string }): Promise<{ token: string }>;
}

const Vault = registerPlugin<SecureVaultPlugin>('SecureVault');

export async function unlockUserSession(challenge: string): Promise<void> {
  // Anti-pattern: String allocation remains in JS heap indefinitely until GC runs
  const result = await Vault.authenticateBiometrics({ challenge });
  const authToken = result.token;
  
  await fetch('/api/v1/session/verify', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${authToken}` }
  });
  // String cannot be cleared; token remains in JSC/V8 heap dump
}
```

#### Production Standard (Correct)
> **Standard**: Allocates mutable TypedArrays for bridge transfer. Ensures challenge and received credentials are cryptographically scrubbed via zeroizeBuffer() inside a mandatory `finally` block, leaving zero persistent artifacts in the JavaScript engine memory space.
```typescript
import { registerPlugin } from '@capacitor/core';

interface SecureVaultPlugin {
  authenticateBiometrics(options: { challengeBuffer: string }): Promise<{ tokenBuffer: string }>;
}

const Vault = registerPlugin<SecureVaultPlugin>('SecureVault');

function zeroizeBuffer(buffer: Uint8Array): void {
  // Overwrite with pseudorandom noise first, then zeroize to defeat cache analysis
  crypto.getRandomValues(buffer);
  buffer.fill(0);
}

export async function unlockUserSession(challengeBytes: Uint8Array): Promise<void> {
  // Base64 encoding used strictly for IPC wire format over the bridge
  const challengeB64 = btoa(String.fromCharCode(...challengeBytes));
  let rawToken: Uint8Array | null = null;

  try {
    const response = await Vault.authenticateBiometrics({ challengeBuffer: challengeB64 });
    const binaryString = atob(response.tokenBuffer);
    rawToken = new Uint8Array(binaryString.length);
    for (let i = 0; i < binaryString.length; i++) {
      rawToken[i] = binaryString.charCodeAt(i);
    }

    await fetch('/api/v1/session/verify', {
      method: 'POST',
      body: rawToken,
      headers: { 'Content-Type': 'application/octet-stream' }
    });
  } finally {
    if (rawToken) {
      zeroizeBuffer(rawToken);
    }
    zeroizeBuffer(challengeBytes);
  }
}
```

### Capacitor 7 Swift Plugin Native Zeroization

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Swift String allocations are copy-on-write reference-counted buffers managed by ARC. They cannot be reliably zeroized, allowing intermediate tokens to survive in iOS heap memory segments indefinitely.
```swift
import Capacitor

@objc(SecureVaultPlugin)
public class SecureVaultPlugin: CAPPlugin {
    @objc func authenticateBiometrics(_ call: CAPPluginCall) {
        guard let challenge = call.getString("challengeBuffer") else {
            call.reject("Invalid challenge")
            return
        }
        
        // Anti-pattern: String retains biometric signature in Swift managed runtime
        let secretToken = BiometricManager.sign(challenge: challenge)
        call.resolve(["tokenBuffer": secretToken])
    }
}
```

#### Production Standard (Correct)
> **Standard**: The native implementation wraps the secret payload in an UnsafeMutableBytes buffer and leverages `memset_s` in a `defer` block. This guarantees cryptographic erasure before stack unwinding, preventing native memory retention.
```swift
import Capacitor
import LocalAuthentication

@objc(SecureVaultPlugin)
public class SecureVaultPlugin: CAPPlugin {
    @objc func authenticateBiometrics(_ call: CAPPluginCall) {
        guard let challengeB64 = call.getString("challengeBuffer"),
              let challengeData = Data(base64Encoded: challengeB64) else {
            call.reject("Malformed challenge payload")
            return
        }
        
        var tokenBytes = [UInt8](repeating: 0, count: 64)
        defer {
            // Mandatory secure zeroization of native memory buffer
            tokenBytes.withUnsafeMutableBytes { ptr in
                _ = memset_s(ptr.baseAddress, ptr.count, 0, ptr.count)
            }
        }
        
        let success = BiometricCryptoEngine.generateToken(from: challengeData, outBuffer: &tokenBytes)
        guard success else {
            call.reject("Biometric verification failed")
            return
        }
        
        let tokenData = Data(tokenBytes)
        call.resolve(["tokenBuffer": tokenData.base64EncodedString()])
    }
}
```

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: Capacitor 7 Native Bridge Memory Zeroization Standard

Capacitor 7 Native Bridge Memory Zeroization Standard defines an industrial-grade behavioral standard for mobile engineering. Enforces deterministic in-memory cryptographic zeroization of transient biometric payloads, cryptographic keys, and authentication tokens across the Capacitor 7 JavaScript-to-Native bridge. Mandates byte-array manipulation over immutable strings to eliminate memory retention risks in V8/JSC heaps and native memory segments. Prohibits persistence or garbage-collector dependence for high-entropy secrets. 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: Passing Secrets via Immutable JS Strings and Un-Zeroed Bridge Dictionaries 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 DriftPassing Secrets via Immutable JS Strings and Un-Zeroed Bridge DictionariesCritical
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 transmit transient biometric payloads, session keys, and sensitive tokens as raw byte buffers (Uint8Array or ArrayBuffer) rather than immutable strings to enable explicit in-memory wiping.

Engineers MUST ALWAYS transmit transient biometric payloads, session keys, and sensitive tokens as raw byte buffers (Uint8Array or ArrayBuffer) rather than immutable strings to enable explicit in-memory wiping.

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 explicitly zeroize byte buffers in JavaScript using crypto.getRandomValues() followed by buffer.fill(0) inside a guaranteed `finally` block immediately after calling the Capacitor bridge.

Engineers MUST ALWAYS explicitly zeroize byte buffers in JavaScript using crypto.getRandomValues() followed by buffer.fill(0) inside a guaranteed `finally` block immediately after calling the Capacitor bridge.

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 secrets to traverse the Capacitor 7 bridge serialized within JSON strings or standard object dictionaries that rely on non-deterministic V8/JavaScriptCore garbage collection.

Engineers MUST NOT allow secrets to traverse the Capacitor 7 bridge serialized within JSON strings or standard object dictionaries that rely on non-deterministic V8/JavaScriptCore garbage collection.

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

Native Swift plugins MUST pin incoming byte arrays into UnsafeMutableRawBufferPointer, perform the cryptographic operation, and invoke `memset_s` or `sodium_memzero` before releasing the buffer.

Native Swift plugins MUST pin incoming byte arrays into UnsafeMutableRawBufferPointer, perform the cryptographic operation, and invoke `memset_s` or `sodium_memzero` before releasing the buffer.

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

Native Android (Kotlin) plugins MUST consume incoming byte arrays directly, wrap them in cleanable native ByteBuffer allocations or primitive ByteArray segments, and execute `Arrays.fill(bytes, 0.toByte())` in a defensive `finally` block.

Native Android (Kotlin) plugins MUST consume incoming byte arrays directly, wrap them in cleanable native ByteBuffer allocations or primitive ByteArray segments, and execute `Arrays.fill(bytes, 0.toByte())` in a defensive `finally` block.

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

Services MUST reject any bridge call where authentication tokens or cryptographic materials remain resident in memory beyond the single invocation lifecycle.

Services MUST reject any bridge call where authentication tokens or cryptographic materials remain resident in memory beyond the single invocation lifecycle.

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 Capacitor 7 Native Bridge Memory Zeroization Standard critical for AI coding assistants?

Enforces deterministic in-memory cryptographic zeroization of transient biometric payloads, cryptographic keys, and authentication tokens across the Capacitor 7 JavaScript-to-Native bridge. Mandates byte-array manipulation over immutable strings to eliminate memory retention risks in V8/JSC heaps and native memory segments. Prohibits persistence or garbage-collector dependence for high-entropy secrets. 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 (Passing Secrets via Immutable JS Strings and Un-Zeroed Bridge Dictionaries) 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.

Related MOBILE Rules

View all rules →
1 Rule in Stack

Capacitor