TTESTATION_SERVICE_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(Credential issuance failed: ${response.status});
}
const data = await response.json();
return data.token;
}
### Step 2: Query the Behavioral Profile
Before granting access to persistent storage, query the attestation service for a behavioral summary. The service aggregates tamper-evident audit events into a structured profile. Access requires a micro-payment via the x402 protocol to prevent automated probing and ensure query accountability.
```typescript
import { payWithX402 } from "@x402/client";
interface BehavioralProfile {
agent_id: string;
memory_behavior: {
total_memory_tokens: number;
memory_read_count: number;
memory_write_count: number;
read_write_ratio: number;
consistency_score: number;
access_pattern: string;
behavioral_summary: string;
};
verified_by: string;
jwks_uri: string;
audit_source: string;
generated_at: string;
}
async function fetchBehavioralProfile(agentId: string): Promise<BehavioralProfile> {
const paymentHeader = await payWithX402({
amount: "0.01",
currency: "USDC",
network: "base",
});
const response = await fetch(
`https://agentlair.dev/v1/agents/${agentId}/memory-trust`,
{
headers: { "X-PAYMENT": paymentHeader },
}
);
if (!response.ok) {
throw new Error(`Profile retrieval failed: ${response.status}`);
}
return response.json();
}
Step 3: Evaluate Against Policy
The trust decision lives in your infrastructure. A policy evaluator compares the behavioral profile against configurable thresholds. This ensures that access control remains deterministic and auditable.
interface AccessPolicy {
minimumHistoricalTokens: number;
minimumConsistencyThreshold: number;
permittedPatterns: string[];
maximumWriteRatio: number;
}
interface EvaluationResult {
approved: boolean;
justification: string;
}
async function evaluateAccess(
agentId: string,
policy: AccessPolicy
): Promise<EvaluationResult> {
const profile = await fetchBehavioralProfile(agentId);
const behavior = profile.memory_behavior;
if (behavior.total_memory_tokens < policy.minimumHistoricalTokens) {
return {
approved: false,
justification: `Insufficient history: ${behavior.total_memory_tokens} tokens recorded`,
};
}
if (behavior.consistency_score < policy.minimumConsistencyThreshold) {
return {
approved: false,
justification: `Irregular access cadence detected (score: ${behavior.consistency_score})`,
};
}
if (!policy.permittedPatterns.includes(behavior.access_pattern)) {
return {
approved: false,
justification: `Pattern mismatch: ${behavior.access_pattern} not in allowed set`,
};
}
const writeRatio = 1 - behavior.read_write_ratio;
if (writeRatio > policy.maximumWriteRatio) {
return {
approved: false,
justification: `Write intensity exceeds threshold: ${writeRatio.toFixed(2)}`,
};
}
return { approved: true, justification: behavior.behavioral_summary };
}
Step 4: Integrate into the Storage Gateway
The final layer sits between the incoming request and the persistent store. It extracts the agent identifier, runs the policy evaluation, and conditionally permits KV operations.
export interface Env {
AGENT_STORAGE: KVNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const agentId = request.headers.get("X-Agent-Identifier");
if (!agentId) {
return new Response("Agent identifier missing", { status: 401 });
}
const decision = await evaluateAccess(agentId, {
minimumHistoricalTokens: 50,
minimumConsistencyThreshold: 0.4,
permittedPatterns: ["read_heavy", "balanced"],
maximumWriteRatio: 0.3,
});
if (!decision.approved) {
return new Response(
JSON.stringify({ error: "Access denied", details: decision.justification }),
{ status: 403, headers: { "Content-Type": "application/json" } }
);
}
const storedValue = await env.AGENT_STORAGE.get(agentId);
return new Response(storedValue, { status: 200 });
},
};
Architecture Rationale
- Storage Layer (Cloudflare Agent Memory): Handles durability via Durable Objects and KV. It remains agnostic to identity or behavior. This separation prevents storage bloat and keeps latency predictable.
- Attestation Layer (AgentLair): Manages cryptographic identity, issues short-lived JWTs, and maintains a tamper-evident audit trail. The micro-payment requirement acts as an anti-gaming mechanism, ensuring that systematic probing accumulates cost while legitimate queries remain inexpensive.
- Policy Layer (Your Gateway): Enforces business-specific thresholds. Because policies are evaluated locally, you retain full control over risk tolerance without depending on external service logic.
Pitfall Guide
1. Treating Consistency Score as Absolute Truth
Explanation: The consistency score measures the coefficient of variation in inter-access gaps. A low score indicates bursty behavior, but burstiness isn't inherently malicious. Batch processors or scheduled agents naturally exhibit irregular patterns.
Fix: Combine the consistency score with pattern classification and historical volume. Allow exceptions for known batch agents by maintaining a whitelist or adjusting thresholds based on agent type.
2. Skipping JWKS Verification
Explanation: The behavioral profile includes a jwks_uri pointing to the attestation service's public keys. Assuming the response is trustworthy without verifying cryptographic signatures leaves you vulnerable to man-in-the-middle or spoofed responses.
Fix: Implement signature verification on the generated_at timestamp and behavioral summary. Cache the JWKS locally and rotate it according to the service's headers. Never trust unsigned assertions.
3. Hardcoding Policy Thresholds
Explanation: Embedding thresholds directly in worker code forces redeployment for every policy adjustment. This creates operational friction and increases the risk of stale configurations.
Fix: Store policies in a versioned configuration store or environment variables. Implement a policy resolver that fetches thresholds at runtime, enabling gradual rollouts and A/B testing of trust parameters.
4. Applying Memory Trust to Non-Memory Operations
Explanation: The behavioral profile only reflects memory-scoped token usage. It provides zero visibility into API calls, tool invocations, or financial transactions. Using it as a blanket trust mechanism creates dangerous blind spots.
Fix: Scope trust evaluation strictly to memory operations. Implement separate behavioral monitors for tool usage, network egress, and compute consumption. Aggregate signals only after independent validation.
5. Ignoring Payment Endpoint Failures
Explanation: The x402 micro-payment requirement means the trust endpoint can fail due to network issues, insufficient balance, or protocol mismatches. Failing to handle these gracefully results in false denials for legitimate agents.
Fix: Implement circuit breakers and fallback strategies. If the attestation service is unreachable, default to a restrictive policy but queue the request for retry. Log payment failures separately to distinguish between infrastructure issues and policy violations.
6. Assuming Read-Only Access is Risk-Free
Explanation: Read-heavy agents can still exfiltrate sensitive data, reconstruct internal state, or perform reconnaissance. A high read-to-write ratio does not guarantee benign intent.
Fix: Apply data classification to KV namespaces. Restrict read access to sensitive keys based on agent classification, not just behavioral patterns. Implement field-level redaction or sampling for untrusted agents.
7. Failing to Rotate Compromised Credentials
Explanation: Short-lived tokens reduce exposure, but if an agent's base identity is compromised, attackers can continuously request new memory-scoped credentials. Behavioral profiles may not immediately reflect this shift.
Fix: Implement identity revocation at the attestation layer. Monitor for sudden spikes in token issuance rates. Combine behavioral trust with rate limiting and anomaly detection on the credential issuance endpoint.
Production Bundle
Action Checklist
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| Internal team agents with known history | Behavioral trust with relaxed thresholds (min tokens: 20, consistency: 0.3) | Reduces friction while maintaining auditability | Low (micro-payments scale linearly) |
| External third-party agents | Strict behavioral trust + trial period with read-only access | Prevents initial exfiltration while building history | Moderate (requires policy management overhead) |
| High-frequency batch processors | Pattern-specific exemptions + consistency score bypass | Batch jobs naturally exhibit bursty access patterns | Low (avoids false denials) |
| Sensitive reasoning chain storage | Multi-layer trust: behavioral + JWKS verification + field redaction | Protects intellectual property and user context | High (requires additional encryption/redaction layer) |
| Attestation service degradation | Circuit breaker + conservative default policy | Maintains system stability during outages | Low (prevents cascading failures) |
Configuration Template
// trust-policy.config.ts
export const MEMORY_ACCESS_POLICIES = {
default: {
minimumHistoricalTokens: 50,
minimumConsistencyThreshold: 0.4,
permittedPatterns: ["read_heavy", "balanced"],
maximumWriteRatio: 0.3,
},
external_onboarding: {
minimumHistoricalTokens: 10,
minimumConsistencyThreshold: 0.2,
permittedPatterns: ["read_heavy"],
maximumWriteRatio: 0.05,
trialDurationHours: 72,
},
batch_processor: {
minimumHistoricalTokens: 5,
minimumConsistencyThreshold: 0.1,
permittedPatterns: ["burst_write", "balanced"],
maximumWriteRatio: 0.8,
consistencyOverride: true,
},
};
// worker-entry.ts
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const agentId = request.headers.get("X-Agent-Identifier");
if (!agentId) return new Response("Unauthorized", { status: 401 });
const policyKey = request.headers.get("X-Policy-Context") || "default";
const policy = MEMORY_ACCESS_POLICIES[policyKey as keyof typeof MEMORY_ACCESS_POLICIES];
try {
const decision = await evaluateAccess(agentId, policy);
if (!decision.approved) {
return new Response(JSON.stringify({ error: "Denied", reason: decision.justification }), {
status: 403,
headers: { "Content-Type": "application/json" },
});
}
const data = await env.AGENT_STORAGE.get(agentId);
return new Response(data, { status: 200 });
} catch (error) {
ctx.waitUntil(logTrustFailure(agentId, error));
return new Response("Service temporarily unavailable", { status: 503 });
}
},
};
Quick Start Guide
- Provision Attestation Credentials: Register your application with the attestation service and obtain an API key for credential issuance. Store it securely in your environment configuration.
- Deploy the Trust Gateway: Implement the policy evaluator and storage gateway worker. Configure your KV namespace and attach the worker to the appropriate route.
- Integrate x402 Payment: Install the x402 client library, configure your Base network wallet, and ensure sufficient USDC balance for micro-payments. Test the payment flow in a sandbox environment.
- Define Initial Policies: Start with conservative thresholds (
minTotalTokens: 50, consistency: 0.4, maxWriteRatio: 0.3). Monitor denial rates and adjust based on legitimate agent behavior.
- Enable Observability: Instrument the gateway to log trust evaluation outcomes, payment status, and policy violations. Set up alerts for sudden spikes in denials or payment failures.