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:
Runtime binding happens across three layers:
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"
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"
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
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
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
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
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:
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)
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();
});
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
Requirement: Crypto exchanges must detect and respond to operational anomalies.
Runtime binding solution:
Requirement: Report which system executed a transaction.
Runtime binding solution:
Requirement: High-risk AI systems must be "subject to human oversight."
Runtime binding solution:
// 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
Use defense-in-depth:
{
"revocation_check_interval_seconds": 5,
"ocsp_cache_ttl_seconds": 5,
"fail_open": false
}
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
}