KAKUNIN

MiCA Compliance for Autonomous Trading Bots

Markets in Crypto-Assets (MiCA) Regulation (EU) entered into force in 2023. Articles 67–72 establish strict requirements for operators of algorithmic trading systems — which includes autonomous AI trading bots.

This guide maps MiCA requirements to technical implementation using Kakunin runtime binding.


MiCA Article 67: Governance Framework

Requirement: Crypto asset service providers (CASPs) must maintain appropriate governance for algorithmic trading, including:

Implementation with Kakunin:

// MiCA Art. 67: Define governance framework
const tradingBotPolicy = {
  agentId: 'trading_bot_eu_v2',
  operator: 'acme_trading_ltd',
  operatorRegulatorId: 'ESMA-001234',  // Regulatory registration
  
  // Authority limits
  scope: {
    maxTransactionSize: 50000,  // EUR
    maxDailyVolume: 1000000,
    allowedMarkets: ['EUR_USD', 'GBP_EUR'],
    allowedRegions: ['eu-west-1'],
    tradingHours: {
      start: '08:00',
      end: '17:00',
      tz: 'UTC',
      excludeWeekends: true,
    },
  },

  // Risk controls
  riskControls: {
    killSwitchManual: true,           // Operator can kill at any time
    killSwitchAutomatic: 'anomaly_0.85', // Auto-revoke if anomaly > 0.85
    maxConsecutiveFailures: 3,
    circuitBreakerThreshold: 0.75,
  },

  // Testing schedule
  testing: {
    basefitTesting: '2026-06-01',     // Annual fitness test required
    scenarioTesting: 'quarterly',      // Quarterly stress tests
    penetrationTesting: 'annual',
  },

  // Governance documentation
  governance: {
    documentedBy: 'compliance_team@acme',
    approvedBy: 'ceo@acme',
    lastReview: '2026-05-01',
    nextReview: '2026-08-01',
  },
};

// Register this policy with Kakunin
const result = await kakunin.governance.registerPolicy(tradingBotPolicy);
console.log(`Policy registered: ${result.policyId}`);

MiCA Article 68: Pre-Trading Risk Controls

Requirement: Operators must have pre-trade controls that prevent orders violating scope limits before they're sent to the exchange.

Implementation:

// Pre-trade risk check (runs BEFORE signing)
async function preTradeRiskCheck(tradeRequest) {
  const scope = await kakunin.governance.getScope('trading_bot_eu_v2');
  const baseline = await kakunin.monitoring.getBaseline('trading_bot_eu_v2');

  // Check 1: Size limit
  if (tradeRequest.size > scope.maxTransactionSize) {
    return {
      allowed: false,
      reason: 'exceeds_scope_size',
      limit: scope.maxTransactionSize,
      requested: tradeRequest.size,
    };
  }

  // Check 2: Market allowed
  if (!scope.allowedMarkets.includes(tradeRequest.market)) {
    return {
      allowed: false,
      reason: 'market_not_allowed',
      allowed: scope.allowedMarkets,
      requested: tradeRequest.market,
    };
  }

  // Check 3: Daily volume cap
  const todayVolume = await kakunin.monitoring.getTodayVolume('trading_bot_eu_v2');
  if (todayVolume + tradeRequest.size > scope.maxDailyVolume) {
    return {
      allowed: false,
      reason: 'daily_volume_cap_exceeded',
      cap: scope.maxDailyVolume,
      current: todayVolume,
      requested: tradeRequest.size,
    };
  }

  // Check 4: Trading hours
  const now = new Date();
  const utcHour = now.getUTCHours();
  if (utcHour < 8 || utcHour >= 17) {
    return {
      allowed: false,
      reason: 'outside_trading_hours',
      hours: '08:00-17:00 UTC',
    };
  }

  // Check 5: Circuit breaker (anomaly score)
  const anomalyScore = await kakunin.monitoring.getCurrentAnomalyScore('trading_bot_eu_v2');
  if (anomalyScore > scope.circuitBreakerThreshold) {
    return {
      allowed: false,
      reason: 'circuit_breaker_active',
      anomalyScore,
      threshold: scope.circuitBreakerThreshold,
    };
  }

  return { allowed: true };
}

MiCA Article 69: Post-Trade Transparency

Requirement: All trades must be logged with sufficient detail for regulators to audit.

Implementation:

// Post-trade logging (MiCA Art. 69)
async function logTrade(tradeRequest, tradeResponse) {
  const auditEntry = {
    timestamp: new Date().toISOString(),
    
    // Agent identification
    agentId: 'trading_bot_eu_v2',
    agentCertSerial: 'f1d4e8c7b2a9f3e6',  // From certificate
    agentOperator: 'acme_trading_ltd',
    
    // Trade details
    orderId: tradeResponse.orderId,
    market: tradeRequest.market,
    side: tradeRequest.side,  // BUY or SELL
    size: tradeRequest.size,
    executionPrice: tradeResponse.executionPrice,
    executionTime: tradeResponse.executionTime,
    
    // Proof of authorization
    certificate: tradeRequest.certificate,  // X.509 cert
    signature: tradeRequest.signature,      // Cryptographic proof
    signatureVerified: true,
    
    // Pre-trade controls
    preTradeCheck: {
      withinScope: true,
      withinBaseline: true,
      anomalyScore: 0.23,
      circuitBreakerActive: false,
    },
    
    // Counterparty (if known)
    counterparty: tradeResponse.counterparty,
    counterpartyId: tradeResponse.counterpartyId,
  };

  // Store immutably (WORM — write-once, read-many)
  await kakunin.auditLog.insert(auditEntry);

  // Send to regulator reporting system
  await submitToFinancialReporting({
    reportingId: 'ESMA-EMIR',  // European transaction reporting
    entry: auditEntry,
  });
}

MiCA Article 70: Segregation of Duties

Requirement: The entity deploying the bot (the operator) must be distinct from the entity who authorized it (typically a board decision), and both must be distinct from the technical implementation.

Implementation via Certificate Issuer:

// MiCA Art. 70: Segregation of duties proven via certificate chain

// Step 1: Board decision
const boardResolution = {
  passed: '2026-05-01',
  approvedBy: ['ceo@acme', 'cfo@acme', 'compliance_lead@acme'],
  resolution: 'Authorize deployment of trading_bot_eu_v2 with €50K scope',
};

// Step 2: Operator deploys, but doesn't issue cert
// Kakunin (trusted third party) issues the certificate
const cert = await kakunin.agents.getCertificate(agent.id, {
  validityDays: 365,
  scope: { /* ... */ },
  issuer: 'Kakunin Root CA',  // Third-party issuer
  signedBy: 'kakunin-root-key',  // Not operator's key
});

// Step 3: Regulator can verify
// - Certificate was issued by Kakunin (not self-signed)
// - Board approved the scope
// - Operator deployed it
// - All three roles are separate

MiCA Article 71: Event Logging & Record-Keeping

Requirement: Maintain permanent, tamper-proof records of every algorithm decision and trade.

Implementation:

// Article 71: Write-once audit log with immutable records

// Every agent action creates an event
async function logAgentEvent(agent, event) {
  const logEntry = {
    _id: crypto.randomUUID(),
    timestamp: new Date().toISOString(),
    
    // Event classification
    eventType: 'trade.executed',  // or 'anomaly.detected', 'cert.revoked', etc.
    
    // Agent identification
    agentId: agent.id,
    agentCertificate: agent.certificatePem,
    agentSignature: event.signature,  // Proves agent authorized this
    
    // Event details
    actionType: event.actionType,
    payload: event.payload,
    riskScore: event.riskScore,
    
    // Pre/post state
    stateBefore: event.stateBefore,
    stateAfter: event.stateAfter,
    
    // Authorization chain
    authorizedBy: agent.id,  // Agent certificate
    verifiedBy: 'kakunin-signing-service',  // Kakunin verified it
    approvedBy: null,  // Null = not human-approved (automatic)
  };

  // Write to WORM log (cannot be updated or deleted)
  await kakunin.auditLog.insert(logEntry);

  // Replicate to external audit system (redundancy)
  await externalAuditStorage.write({
    path: `/agent-events/${agent.id}/${logEntry._id}`,
    data: logEntry,
  });

  return logEntry._id;
}

MiCA Article 72: Testing & Incident Response

Requirement: Regular testing of the algorithm's functioning under various market conditions. Document how the firm responds to incidents (circuit breaker, manual kill, etc.).

Implementation:

// Article 72: Fitness testing & incident procedures

const testingPlan = {
  // 1. Annual fitness test (required)
  annualFitnessTesting: {
    date: '2026-06-01',
    scope: [
      'Does the algorithm still execute trades correctly?',
      'Does the circuit breaker activate on anomalies?',
      'Can the operator manually kill the algorithm?',
      'Are all audit logs intact and tamper-proof?',
    ],
    results: null,  // To be filled after test
  },

  // 2. Quarterly stress testing
  stressTests: [
    {
      name: 'Flash crash scenario',
      description: 'Market drops 30% in 5 seconds. Can agent handle volatility?',
      date: '2026-05-31',
      passedChecks: [
        'Circuit breaker activated at anomaly > 0.75',
        'No trades executed above scope limit',
        'Audit log complete',
      ],
    },
    {
      name: 'Counterparty default',
      description: 'Major exchange goes offline. Does agent retry safely?',
      date: '2026-06-30',
    },
    {
      name: 'Market manipulation',
      description: 'Pump-and-dump detected. Agent detects anomaly and stops.',
      date: '2026-07-31',
    },
  ],

  // 3. Incident response procedures
  incidentResponse: {
    // Procedure 1: Anomaly detected
    anomalyDetected: {
      threshold: 0.85,
      action: 'Auto-revoke certificate',
      notification: 'SMS + email to operator team',
      graceperiod: '5 minutes',
      escalation: 'If not ACK'd, revoke is final',
    },

    // Procedure 2: Manual kill switch
    manualKillSwitch: {
      who: ['ceo@acme', 'cfo@acme', 'compliance_lead@acme'],
      howFast: '< 10 seconds from decision to certificate revocation',
      log: 'Logged with user identity + timestamp',
    },

    // Procedure 3: Post-incident audit
    postIncidentAudit: {
      trigger: 'Any anomaly > 0.75 or manual kill',
      timeline: 'Within 24 hours',
      scope: [
        'What caused the incident?',
        'What was the impact ($ trades blocked)?',
        'What controls failed?',
        'What controls worked?',
        'What changes needed?',
      ],
    },
  },
};

Complete MiCA Compliance Checklist

ArticleRequirementImplementationStatus
67Governance frameworkBoard-approved policy, documented scope, testing plan
68Pre-trade controlsSize, market, time, circuit breaker checks
69Post-trade transparencyComplete audit log with agent signature
70Segregation of dutiesThird-party cert issuer (Kakunin) proves separation
71Record-keepingWORM audit log, immutable event records
72Testing & responseAnnual fitness tests, incident procedures, auto-revocation

Deployment: MiCA-Compliant Architecture

# Kubernetes deployment for MiCA compliance

apiVersion: apps/v1
kind: Deployment
metadata:
  name: trading-bot-mica
spec:
  replicas: 1
  selector:
    matchLabels:
      app: trading-bot-mica
  template:
    metadata:
      labels:
        app: trading-bot-mica
      annotations:
        mica-policy: registered
        governance-framework: version-2
    spec:
      # Pod security: RLS (restrictive Linux security)
      securityContext:
        runAsNonRoot: true
        fsReadOnlyRootFilesystem: true

      containers:
      # Main trading bot
      - name: trading-bot
        image: myrepo/trading-bot:v2
        env:
        - name: KAKUNIN_API_KEY
          valueFrom:
            secretKeyRef:
              name: kakunin-secrets
              key: api-key
        - name: OPERATOR_ID
          value: acme_trading_ltd
        volumeMounts:
        - name: cert-volume
          mountPath: /var/certs
          readOnly: true
        - name: audit-log-volume
          mountPath: /var/audit
          readOnly: false

      # MiCA enforcer sidecar
      - name: mica-enforcer
        image: kakunin/mica-enforcer:latest
        env:
        - name: MICA_POLICY_ID
          value: trading_bot_eu_v2_policy
        - name: OPERATOR_ID
          value: acme_trading_ltd
        ports:
        - containerPort: 8443
          name: mica-api
        volumeMounts:
        - name: cert-volume
          mountPath: /var/certs
          readOnly: true
        - name: audit-log-volume
          mountPath: /var/audit
          readOnly: false

      volumes:
      - name: cert-volume
        projected:
          sources:
          - secret:
              name: agent-certificate
              items:
              - key: cert.pem
                path: cert.pem
              - key: kms-key-arn.txt
                path: kms-key-arn.txt
      - name: audit-log-volume
        persistentVolumeClaim:
          claimName: audit-log-pvc
          readOnly: false

      # Node affinity: EU regions only (GDPR)
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: region
                operator: In
                values:
                - eu-west-1
                - eu-central-1

Next Steps

  1. Register your governance policy with Kakunin
  2. Deploy the agent with MiCA-compliant scope + baseline
  3. Set up quarterly stress testing (and log results)
  4. Prepare regulatory documentation (board resolutions, testing reports)
  5. Monitor the dashboard — anomaly detection and audit logs are your compliance evidence

Ready to deploy? See Quickstart: MiCA-Compliant Trading Bot.