Integrating real-time MiCA enforcement in one sprint
A realistic day-by-day plan for adding pre-execution, MiCA-aligned policy enforcement to an AI agent that already moves money — using only the documented Intaglio SDK and proxy API, no undocumented endpoints.
Day 1-2: write the APL policy
Encode existing limits and requirements (per-transaction caps, sanctions screening, destination allowlists, human-approval thresholds) as an APL policy file. This is usually a direct translation of an existing written treasury/compliance policy, not new policy design:
policy treasury-agent v1.0.0
agent treasury-bot-01
operator acme-gmbh
scope {
rails [x402 solana-pay]
currencies [USDC USDT]
}
limit {
per_transaction { value 10000 currency USDC }
per_day { value 50000 currency USDC }
}
require {
human_approval_above { value 5000 currency USDC }
deny_if_sanctioned true
deny_if_destination NOT_IN whitelist.json
}
obligation {
log_to solana:devnet
retention 7y
}Day 3: wrap outbound calls with the SDK
Install @intaglio/sdk and wrap the agent's existing outbound request function. This matches the documented fetch-wrapper pattern:
// intaglioFetcher.ts
import { randomUUID } from "crypto";
const INTA_PROXY_URL = process.env.INTA_PROXY_URL || "http://localhost:3001";
const INTA_AGENT_SECRET = process.env.INTA_AGENT_SECRET;
export async function intaglioFetch(actionObj: any, upstreamUrl: string, fetchOptions: RequestInit = {}) {
const idempotencyKey = randomUUID();
const response = await fetch(`${INTA_PROXY_URL}/v1/x402/forward`, {
method: "POST",
headers: {
"Authorization": `Bearer ${INTA_AGENT_SECRET}`,
"Idempotency-Key": idempotencyKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
action: actionObj,
x402_request: { url: upstreamUrl, options: fetchOptions },
}),
});
if (!response.ok) {
throw new Error(`[Intaglio] Enforced short-circuit: ${response.statusText}`);
}
return response;
}Day 4: wire up REQUIRE_APPROVAL handling
Anything above the human-approval threshold needs a poll or webhook to resolve the pending decision before the agent can continue:
import { IntaglioClient } from "@intaglio/sdk";
const client = new IntaglioClient({
baseUrl: process.env.INTA_PROXY_URL!,
agentToken: process.env.INTA_AGENT_SECRET!,
});
const result = await client.enforce({ type: "payment", amount: 8000, currency: "USDC" });
if (result.decision.outcome === "REQUIRE_APPROVAL") {
const approval = await client.getApproval(result.approval_id!);
// GET /v1/approvals/:id -> { status: "APPROVED" | "PENDING" | "DENIED", ... }
}Day 5: verify the audit chain, not just the happy path
Submit a deliberately out-of-policy action and confirm it is actually rejected — not just that the policy file parses:
curl -X POST http://localhost:3001/v1/actions \
-H "Authorization: Bearer <agent-secret>" \
-H "Content-Type: application/json" \
-d '{
"action": {
"rail": "x402",
"amount": { "value": 999999, "currency": "USD" },
"timestamp": "2026-07-06T00:00:00Z"
}
}'
# Expect: { "decision": { "outcome": "DENY" }, ... }Then confirm each returned record's prev_record_hash matches the self_hash of the record before it — that chain is what makes the audit trail tamper-evident rather than just a database table.
Start enforcing policy today
MiCA CASP enforcement is active as of July 1, 2026.