aic-agent — Deployment (EN)EN

aic-agent deployment

Operational playbook: how to run an aic-agent-based caller in production — keys, issuer wiring, the evidence machine, monitoring, rotation. Assumes you know what the agent does; this page is the "make it real" checklist.

1. Choose the credential flow

Flow When Key liabilities
Local mint (Config.Key) trust the agent to sign its own token; the verifier pins your SPKI key the agent key is the crown jewel — KMS it
mTLS (CertFile/KeyFile) an issuance/CA pipeline already grants the AIC cert cert/key file handling; rotation is CA-driven
Remote issuer (RemoteIssuer + DA) you want the verifier to trust a shared issuer CA and get short-lived tokens the issuer endpoint must be HTTPS; DA acquisition (signer or local)
User signer ObtainAIC agent has no AIC certificate yet; human-in-the-loop issuance the signer is a trust root; approvals are an audit trail

For a first deployment, ServerCA pinning closes the "which service am I talking to" question without a full PKI.

2. Keys and files

File/key Recommendation
Agent key (identity.GenerateKey output) 0600, private dir, never in source control; on a KMS-backed signer when available
CertFile/KeyFile (mTLS mode) same posture as the agent key; rotate with the CA schedule
config.example.json read via LoadClientConfigFile, keep 0600; unknown fields are rejected so a typo can't silently disable an option
LogFile created 0600; route to a collector via Logger (slog) instead for production
RootCA vs ServerCA keep separate bundles: ServerCA is the service pin, RootCA the SDK's own trust (signer/issuer/LLM)

3. Remote-issuance wiring

  • Issuer: Config.RemoteIssuer must be HTTPS (the SDK rejects plaintext token endpoints; only loopback / AllowPlaintextHTTP are exceptions). Set IssuerClientID/Secret if the issuer demands client auth.
  • DA acquisition: leave DA empty and set UserSigner to the signing service (default loopback https://127.0.0.1:8444). If you pre-mint DAs, set DA directly; DASignerMode=local signs with Config.Key.
  • Refresh: the agent auto-refreshes the token on 401 (idempotent requests only). Keep the issuer's exp reasonably short so refresh churn is visible in your metrics — 401-spikes mean either clock skew or the audience/issuer claims drifted.

4. The evidence machine

When the verifier is configured with an evidence requirement (it refuses with a CLC-CHALLENGE-v1 until satisfied), the agent can close the loop only if your deployment made the facts available to the verifier's EvidenceFacts hook:

  • Configure EvidenceProvider to ask the deployment (e.g. "has the human approval receipt been recorded and stored?"), returning (bool, error).
  • Monitor DoResult.EvidenceRefused — a live challenge that went unanswered. That is a real operational signal (the fact-store did not arrive in time), not a protocol bug.
  • WithoutEvidenceRetry: true per request lets a caller opt out of the retry for exactly-once workflows (e.g. a job that must not double-run).

5. Human-in-the-loop issuance (ObtainAIC)

  • The agent never holds the principal's private key; the flow is user-signer → human approves → core mints a cert for the agent's own key.
  • In production, surface the request id to the operator (the stepwise SubmitAICRequestWaitForAIC functions exist for exactly this) and monitor approval latency — approval backlog is the operational metric.
  • DAVersion: 1 only for peers that can't read v2. Prefer v2 (SPKI-bound) so the DA is tied to the key the AIC will be issued for.

6. Monitoring & logs

  • Denials: bucket by RefusalError.Code and Status. A jump in ChallengeUnavailable means the verifier changed its refusal shape — interop alert.
  • Retries: count EvidenceClosed vs EvidenceRefused per deployment.
  • Token failures: 401 spikes (see §3), Refresh() errors, issuer timeouts.
  • Logs: route Logger to your collector; never log Token, DA, or key material. The SDK won't, and your hooks must not either.

7. Rotation & drills

  • Agent key rotation: mint a new key, register its kid/SPKI with the verifier's JWTCAFile trust anchor, drain, remove.
  • Issuer CA rotation: add new CA to RootCA first, drain old, remove.
  • Server CA rotation: same on ServerCA; test with a staging target.
  • Certificate expiry (mTLS mode): alert at T-30d (the verifier fails closed on expiry).
  • Drill: rotate the signer's CA, break the issuer URL, and confirm the agent fails with a typed error rather than hanging. Rotate the agent key and confirm the verifier refuses old-key requests.

8. Checklist

  • [ ] Agent key on KMS/HSM or 0600 private file — never in the repo
  • [ ] ServerCA pin set; RootCA separate bundle
  • [ ] Issuer endpoint HTTPS; AllowPlaintextHTTP unset in prod
  • [ ] Token exp short; refresh-on-401 verified in staging
  • [ ] EvidenceProvider configured with a real fact-store question; EvidenceRefused monitored
  • [ ] SDK logs route to a collector; keys/tokens never logged
  • [ ] Agent-key and CA rotation drills done
  • [ ] consumer-view gate green; go.sum committed