← Back to Blog

Under the Hood: How Two-Gate Enforcement Works

Security marketing is full of buzzwords. At PolicyLayer, we believe in “Provable Security.”

Our core architecture is based on a concept called Two-Gate Enforcement. This post explains the cryptography behind how we secure agent transactions without ever holding your private keys.

The Challenge

We need to validate a transaction against a policy (e.g., “Max $100”) before it is broadcast to the blockchain, but we (PolicyLayer) do not have the private key to sign it.

This creates a timing gap: the moment between “policy approved this transaction” and “transaction actually signed.” In that gap, a compromised agent could modify the transaction—changing the amount, recipient, or asset—and still claim it was approved.

The question: How do we cryptographically bind a policy decision to the exact transaction that gets signed?

Why Two Gates? The Single-Gate Vulnerability

Many policy systems use a single checkpoint: validate the intent, return approval, done. This seems sufficient, but it’s fundamentally broken.

Single-gate flow:

Agent → Policy Check → "Approved" → Agent signs whatever it wants

The problem: there’s no verification that what gets signed matches what was approved. The “Approved” response is just a boolean. A malicious or buggy agent can:

  1. Request approval for a $50 transfer
  2. Receive “Approved”
  3. Sign a $50,000 transfer instead
  4. Broadcast to blockchain

The policy system has no way to detect this substitution. It approved something, but has no cryptographic proof of what.

The Two-Gate Solution

Two-gate enforcement closes this gap by creating a cryptographic link between approval and execution.

┌─────────┐       ┌──────────────┐       ┌──────────────┐       ┌─────────┐
│  Agent  │──────▶│   Gate 1:    │──────▶│   Gate 2:    │──────▶│  Sign & │
│         │ Intent│   Validate   │ Token │   Verify     │Approve│Broadcast│
└─────────┘       │   + Hash     │       │   Hash Match │       └─────────┘
                  └──────────────┘       └──────────────┘

Gate 1 doesn’t just say “approved”—it creates a fingerprint of the exact transaction and embeds it in a signed token.

Gate 2 re-calculates the fingerprint and compares. If anything changed, the hashes won’t match.

Gate 1: Intent Validation

  1. The Agent constructs a transaction object (the Intent):

    • To: 0xBob
    • Value: 50 USDC
    • Chain: Base
  2. The SDK sends this Intent to the PolicyLayer API.

  3. The API evaluates against policies:

    • Does this violate the Daily Limit? No.
    • Is 0xBob whitelisted? Yes.
    • Is 50 USDC under the per-transaction limit? Yes.
  4. The API creates a fingerprint of the Intent:

function calculateFingerprint(intent: TransactionIntent): string {
  const canonical = JSON.stringify({
    chain: intent.chain,
    asset: intent.asset,
    to: intent.to.toLowerCase(),
    amount: intent.amount,
    // Include all fields that affect the transaction
  });
  return crypto.createHash('sha256').update(canonical).digest('hex');
}
  1. The API issues a signed JWT containing:
    • The fingerprint hash
    • Timestamp and expiry (60 seconds)
    • Unique token ID (for replay prevention)

Gate 2: Verification & Signing

  1. The Agent receives the Auth Token.

  2. Before signing, the SDK calls Gate 2 with the Intent + Auth Token.

  3. The Validator performs three checks:

    • Is the JWT signature valid? (Proves it came from PolicyLayer)
    • Has the token expired? (60-second window)
    • Has the token been used before? (Replay prevention)
  4. The Critical Check: Re-calculate the fingerprint from the current Intent:

    If (CurrentHash === AuthToken.Hash) → APPROVE
    If (CurrentHash !== AuthToken.Hash) → REJECT: "Intent modified"
  5. Mark token as consumed (single-use enforcement).

  6. Only then does the agent sign and broadcast.

Attack Scenarios: What Two-Gate Prevents

Tampering Attack (Primary Threat)

Without Gate 2:

  • Agent requests approval for 50 USDC to 0xBob
  • Receives approval
  • Modifies to 50,000 USDC to 0xAttacker
  • Signs and broadcasts
  • Policy system has no idea

With Gate 2:

  • Agent requests approval for 50 USDC to 0xBob
  • Receives token with fingerprint abc123...
  • Modifies to 50,000 USDC to 0xAttacker
  • Calls Gate 2: fingerprint is now xyz789...
  • xyz789 !== abc123REJECTED

Replay Attack

Without single-use tokens:

  • Agent gets approval for legitimate 50 USDC transfer
  • Saves the approval token
  • Executes transfer
  • Replays same token 100 more times
  • Drains 5,000 USDC with one approval

With single-use enforcement:

  • First execution: token marked as consumed
  • Second attempt: “Token already used” → REJECTED

Time-Delay Attack

Without expiry:

  • Agent gets approval during business hours
  • Waits until 3am when no one is monitoring
  • Executes transaction

With 60-second expiry:

  • Token expires before execution window
  • Agent must re-request approval → REJECTED

Performance Considerations

Two-gate adds latency. Here’s what to expect:

OperationTypical Latency
Gate 1 (Policy Check)20-50ms
Gate 2 (Verification)10-30ms
Total overhead30-80ms

For most agent use cases, this is negligible compared to blockchain confirmation times (seconds to minutes). The security benefit far outweighs the latency cost.

Optimisation options:

  • Gate 2 can run locally (SDK-side verification) for lower latency
  • Batch operations can share a single Gate 1 call
  • Caching for repeated recipient/amount patterns

Comparison to Other Approaches

ApproachKey LocationTampering PreventionCustody Risk
Two-Gate (PolicyLayer)Your server✅ CryptographicNone
MPC WalletsDistributed❌ No policy bindingShared
MultisigMultiple parties❌ No policy bindingMultiple custodians
Smart Contract GuardsOn-chain✅ On-chain enforcementNone
Custodial APIsThird party❌ Trust-basedFull custody

Why not smart contract guards?

On-chain enforcement works but has drawbacks:

  • Gas costs for every policy check
  • Policy changes require contract upgrades
  • Limited policy complexity (gas constraints)
  • No off-chain audit trail

Two-gate gives you the security of cryptographic binding without the on-chain overhead.

The Security Guarantee

Two-gate enforcement provides mathematical proof that:

  1. The transaction that was signed is exactly what was approved
  2. The approval was used exactly once
  3. The approval was used within the valid time window

No trust required. No custody required. Just cryptography.


Related reading:

Ready to secure your AI agents?

Ready to secure your AI agents?

Get spending controls for autonomous agents in 5 minutes.

Get Early Access