KAKUNIN

Secure Runtime Binding: Cryptographic Agent Identity at Execution Time

Overview

Runtime binding is the cryptographic proof that a specific agent with a specific certificate is executing code right now in a specific environment with specific scope limits. Without it:

With runtime binding:


Core Concept: Binding at Layers

Runtime binding happens across three layers:

Layer 1: Process Identity (OS-level)

The agent process itself is bound to a certificate:

Process PID 12345 ← X.509 certificate (bound at startup)
  ├─ Private key in KMS (never loaded into memory)
  ├─ Public key used for verification
  └─ Scope policy enforced by OS-level controls

Linux example:

# Agent binary launched with bound certificate
/opt/agents/trading-bot \
  --cert-arn arn:aws:kms:eu-west-1:123456789:key/... \
  --scope-policy /etc/agent-policies/trading-bot.json

The OS tracks: "PID 12345 is trading_bot_v2 with max 50k EUR/USD"

Layer 2: Network Identity (TLS)

Every network call is mTLS-authenticated:

Agent (PID 12345) → TLS handshake ← Exchange API
Client cert: trading_bot_v2.crt
Client key: in KMS (agent calls `sign` to authorize)
Server verifies: "You are trading_bot_v2 — allowed"

Layer 3: Action Identity (Cryptographic Signature)

Every action is signed by the agent's private key:

Agent computes: trade_request = {market: "EUR_USD", size: 45000}
Agent signs: signature = KMS.sign(trade_request, keyArn)
Agent submits: {trade_request, agent_cert, signature}
Receiver verifies: cert.publicKey.verify(trade_request, signature) == true

Why Binding Matters: Attack Scenarios

Scenario 1: Compromised API Key

Without binding:

Attacker steals API key from agent code
Attacker runs: curl -H "Authorization: Bearer $STOLEN_KEY" https://api.exchange/trade \
  -d '{"market": "EUR_USD", "size": 500000}'  // 10x the limit!
Exchange accepts: "Key is valid, execute trade"
Result: €500k unauthorized trade

With runtime binding:

Attacker steals the agent binary and key ARN, runs it on their machine
Agent runs: calls KMS to sign request
KMS enforces: "Only on IP 10.0.1.x (agent's VPC), only during business hours"
KMS rejects: "Unauthorized region"
Result: Trade is refused before it reaches the exchange

Scenario 2: Scope Escape

Without binding:

Data processor agent (read /raw-data/, write /processed-data/) is compromised
Attacker modifies agent code: os.system("cp /secrets/api-key.json /tmp/exfil")
Agent runs: File copy succeeds silently
Result: Credentials stolen

With runtime binding:

OS-level scope enforcer (SELinux / AppArmor) has policy:
  label agent_data_processor {
    allow /raw-data/* read;
    allow /processed-data/* write;
    deny /secrets/* all;  // explicit deny
  }
Attacker tries: os.system("cat /secrets/api-key.json")
OS blocks: "Process labeled agent_data_processor cannot access /secrets/"
Result: Attempt logged, no breach

Scenario 3: Identity Hijacking

Without binding:

Admin notices unusual activity from trading bot
Admin tries to revoke the bot's certificate
But the bot's running on an air-gapped server — revocation not checked
Bot continues trading for hours while revocation propagates
Result: €2M loss before revocation is enforced

With runtime binding:

Risk monitoring detects anomaly (10x normal trade size)
System revokes bot's certificate in OCSP/CRL
Bot attempts next trade: calls KMS to sign request
KMS queries: Is cert still valid? (OCSP check, 5-second TTL)
KMS responds: "No, revoked 2 minutes ago"
KMS refuses to sign
Bot cannot execute trade
Result: Loss prevented in milliseconds

Implementation Patterns

Pattern 1: Process-Level Binding (Kubernetes)

Deploy agent as Kubernetes pod with sidecar:

apiVersion: v1
kind: Pod
metadata:
  name: trading-bot-v2
  labels:
    agent-id: trading_bot_v2
spec:
  serviceAccountName: trading-bot
  containers:
  - name: agent
    image: trading-bot:latest
    env:
    - name: KMS_KEY_ARN
      valueFrom:
        secretKeyRef:
          name: agent-secrets
          key: kms-key-arn
    - name: AGENT_CERTIFICATE
      valueFrom:
        secretKeyRef:
          name: agent-secrets
          key: certificate-pem
    volumeMounts:
    - name: agent-config
      mountPath: /etc/agent
      readOnly: true
    resources:
      limits:
        memory: "512Mi"
        cpu: "500m"
  
  # Sidecar: continuous scope enforcement
  - name: scope-enforcer
    image: kakunin/scope-enforcer:latest
    env:
    - name: AGENT_ID
      value: trading_bot_v2
    - name: POLICY_FILE
      value: /etc/agent/trading-bot-policy.json
    volumeMounts:
    - name: agent-config
      mountPath: /etc/agent
      readOnly: true
  
  volumes:
  - name: agent-config
    configMap:
      name: trading-bot-policy
      items:
      - key: policy.json
        path: trading-bot-policy.json

Scope policy (configmap):

{
  "agent_id": "trading_bot_v2",
  "version": "1.0.0",
  "execution_constraints": {
    "allowed_regions": ["eu-west-1"],
    "allowed_hours": "08:00-17:00 UTC",
    "max_concurrent_trades": 5,
    "rate_limit": "100 trades/hour"
  },
  "data_access": {
    "/data/market-feeds/*": ["read"],
    "/data/positions/*": ["read", "write"],
    "/logs/trades/*": ["write"]
  },
  "network_rules": {
    "allowed_hosts": [
      "api.exchange.com",
      "market-data.provider.com"
    ],
    "denied_hosts": [
      "*.internal-network.local",
      "169.254.169.254"  // block IMDS on AWS
    ]
  },
  "revocation_check": {
    "enabled": true,
    "cache_ttl_seconds": 5,
    "fail_open": false  // deny if revocation check fails
  }
}

The scope enforcer sidecar:

  1. Reads the policy at startup
  2. Monitors the agent process
  3. Blocks syscalls that violate the policy
  4. Logs all violations to audit trail

Pattern 2: mTLS with Certificate Pinning

Agent connects to API with mutual TLS:

import https from 'https';
import fs from 'fs';
import { KakuninClient } from '@kakunin/sdk';

const kakunin = new KakuninClient({
  kmsKeyArn: process.env.KMS_KEY_ARN!,
  agentId: 'trading_bot_v2',
});

// Load agent certificate (public part)
const agentCert = fs.readFileSync(process.env.AGENT_CERTIFICATE!);

// mTLS agent with certificate pinning
const httpsAgent = new https.Agent({
  cert: agentCert,
  key: async (cb) => {
    // Private key never materialized — KMS handles signing
    // This signer intercepts the TLS handshake
    const signer = kakunin.tlsSignerFor('trading_bot_v2');
    cb(null, signer);
  },
  ca: fs.readFileSync('/etc/ssl/certs/exchange-ca.pem'), // Pin API CA
  rejectUnauthorized: true,
});

// All requests use mTLS
const response = await fetch('https://api.exchange.com/v1/trades', {
  method: 'POST',
  agent: httpsAgent,
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(tradeRequest),
});

Exchange receives request:

Client cert subject: CN=trading_bot_v2
Client cert issuer: CN=Kakunin Root CA
TLS verification: ✓ trusted chain
Scope from cert extensions: [EUR_USD, GBP_USD, max_50k]
Request body: {market: "EUR_USD", size: 45000}
Action taken: Accept (agent is trading_bot_v2, within scope)

Pattern 3: Continuous Signature Verification

Every API call includes a signature proof:

async function submitTrade(tradeRequest) {
  // Step 1: Serialize request deterministically
  const requestBody = JSON.stringify(tradeRequest, Object.keys(tradeRequest).sort());
  
  // Step 2: Agent signs with its private key (via KMS)
  const signature = await kakunin.sign({
    payload: requestBody,
    agentId: 'trading_bot_v2',
    timestamp: Date.now(),
  });
  
  // Step 3: Submit with proof
  const response = await fetch('https://api.exchange.com/v1/trades', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Agent-Signature': signature.signature,
      'X-Agent-Certificate': signature.certificate_pem,
      'X-Agent-Timestamp': signature.timestamp.toString(),
    },
    body: requestBody,
  });
  
  return response.json();
}

Exchange verifies:

// Express middleware
app.post('/v1/trades', (req, res, next) => {
  const signature = req.headers['x-agent-signature'];
  const cert = req.headers['x-agent-certificate'];
  const timestamp = req.headers['x-agent-timestamp'];
  
  // 1. Verify certificate (chain of trust)
  if (!verifyCertificateChain(cert)) {
    return res.status(401).json({ error: 'Invalid certificate chain' });
  }
  
  // 2. Check certificate is not revoked
  const revocationStatus = checkOCSP(cert, { cacheTTL: 5000 });
  if (revocationStatus === 'revoked') {
    return res.status(401).json({ error: 'Certificate revoked' });
  }
  
  // 3. Verify timestamp freshness (within 60 seconds)
  if (Date.now() - parseInt(timestamp) > 60000) {
    return res.status(400).json({ error: 'Request timestamp expired' });
  }
  
  // 4. Verify signature (proves agent authorized this action)
  const publicKey = extractPublicKeyFromCert(cert);
  const isValid = publicKey.verify(req.body, signature);
  if (!isValid) {
    return res.status(401).json({ error: 'Signature verification failed' });
  }
  
  // 5. Extract scope from certificate
  const scope = extractScopeFromCert(cert);
  const { market, size } = req.body;
  
  // 6. Enforce scope
  if (!scope.allowed_markets.includes(market)) {
    return res.status(403).json({ error: 'Market not in agent scope' });
  }
  if (size > scope.max_transaction_size) {
    return res.status(403).json({ error: 'Transaction size exceeds limit' });
  }
  
  // 7. Log to audit trail
  await auditLog.insert({
    event_type: 'trade.submitted',
    agent_id: cert.subject.CN,
    action: { market, size },
    signature_valid: true,
    timestamp: new Date(),
  });
  
  next();
});

Continuous Verification Lifecycle

Agent startup
  ├─ Load certificate from Kakunin
  ├─ Bind identity to process
  ├─ Enforce scope policy (OS-level)
  └─ Register with monitoring system

Every action
  ├─ Check local revocation cache (TTL 5s)
  │   ├─ If cached: use cached result
  │   └─ If expired: query OCSP responder
  ├─ If revoked: refuse to sign, halt execution
  ├─ If valid: KMS signs the action
  ├─ Submit action with signature + certificate
  └─ API verifies signature + scope, executes or rejects

Continuous monitoring
  ├─ Detect anomalous behavior (risk scoring)
  ├─ If risk > 0.85: trigger revocation
  ├─ Publish revocation to OCSP
  ├─ Monitoring systems push revocation notice
  └─ Agent checks revocation status on next action
    ├─ Sees: "You are revoked"
    ├─ Halts all execution
    └─ Logs incident to audit trail

Agent shutdown (normal)
  ├─ Flush any pending events to audit log
  ├─ Unregister from monitoring
  └─ Release identity binding

Agent shutdown (revocation)
  ├─ Certificate no longer valid
  ├─ Any attempt to act fails with signature verification
  ├─ All logs show: "agent_id: trading_bot_v2 | revocation_reason: behavioral_anomaly"
  └─ Incident response team investigates

Compliance Mapping

MiCA Article 67 (Operational Resilience)

Requirement: Crypto exchanges must detect and respond to operational anomalies.

Runtime binding solution:

MiCA Article 72 (Incident Reporting)

Requirement: Report which system executed a transaction.

Runtime binding solution:

EU AI Act Article 13 (Human Oversight)

Requirement: High-risk AI systems must be "subject to human oversight."

Runtime binding solution:


Best Practices

1. Certificate Rotation

// Weekly rotation job (via QStash)
const rotation = await kakunin.rotateAgentCertificate({
  agentId: 'trading_bot_v2',
  newValidityDays: 365,
  gracePeriod: 3600, // 1 hour for old cert to be flushed
});

// All running agents switch to new cert within the grace period
// Old cert is revoked after grace period

2. Scope Enforcement Strategy

Use defense-in-depth:

  1. API boundary: Check scope from certificate
  2. OS level: SELinux/AppArmor policy denies access
  3. Data layer: RLS policies on database
  4. Audit layer: Log all attempted scope violations

3. Revocation Velocity

{
  "revocation_check_interval_seconds": 5,
  "ocsp_cache_ttl_seconds": 5,
  "fail_open": false
}

4. Audit Trail Completeness

Log every action with full context:

{
  "event_type": "action.executed",
  "agent_id": "trading_bot_v2",
  "agent_cert_serial": "f1d4e8c7b2a9f3e6",
  "action": {"market": "EUR_USD", "size": 45000},
  "signature_valid": true,
  "scope_check_passed": true,
  "timestamp": "2026-06-15T14:33:45Z",
  "duration_ms": 124
}

Resources