aic-agent — Reference (EN)EN
aic-agent reference
Code-accurate lookup for aic-agent: every Config field with defaults, the
AIC-JWT and DA shapes, refusal/problem shapes, versions and constants.
Package and versions
| Item | Value |
|---|---|
| Module | github.com/varwof/aic-agent |
| Go | go 1.26, no cgo |
CLCRevision |
semantics.CLCRevision → CLC-1.8 (same as aic-verifier) |
| Remote signer default | DefaultUserSignerAddr = https://127.0.0.1:8444 |
| LLM default | DefaultLLMServerURL = https://api.openai.com/v1 |
| Token lifetime (local) | default 1h (bearer.SignOptions.Lifetime) |
Config — every field
type Config struct {
Mode AuthMode // Bearer or MTLS
Key *identity.AgentKey // Bearer: agent signing key
Token string // Bearer: pre-minted token (Key + signer opts ignored when set)
// Local-mint claims
Issuer string
Audience []string
Subject string
Realm, ID string
Capabilities []aicjwt.Capability
DelegationMode string // aicjwt.ModeAuthorized (default) | ModeRepresentative
// MTLS material
CertFile string
KeyFile string
ServerCA string // service CA pin; empty → system roots (both modes)
// Transport override (advanced)
Transport http.RoundTripper // when set, SDK does not build its own carrier
// TLS for SDK-managed outbound (user signer, remote issuer, LLM)
RootCA string // PEM files, comma/space separated; appended to system roots
// Remote issuance
RemoteIssuer *url.URL
DA string // DA assertion; empty + RemoteIssuer → fetched from UserSigner
UserSigner string // default DefaultUserSignerAddr
DASignerMode string // "local" (default) | "signer"
DASigner DASigner // full override
IssuerClientID string
IssuerClientSecret string
Logger *slog.Logger // default slog.Default()
LogFile string // 0600 file append, released by Close()
EvidenceProvider EvidenceProvider // client half of the evidence-facts mechanism
LLMConfig LLMConfig // used by Agent.Chat
}
Config.Validate() rejects contradictions (e.g. RootCA == ServerCA for the
same file, missing key in Bearer mode without Token/RemoteIssuer).
AIC-JWT shapes
Locally minted bearer (bearer.Sign):
| Claim | Value |
|---|---|
alg |
ES256 / EdDSA |
typ |
aic+jwt |
kid |
SPKI hash of the signing key |
sub/aud/iat/exp/jti |
identity + single-use |
cnf.jkt |
RFC 7638 thumbprint of the presenter key |
aic.principal |
{realm, id} → the agent's principal |
aic.delegation_mode |
authorized / representative |
aic.capabilities |
the declared capability set |
DA assertion (bearer.SignDA, v2):
| Field | Value |
|---|---|
principal.key_hash |
SPKI hash of the principal signing key (authored by SignDA automatically) |
agentKeyBinding (v2) |
binds the delegation to this agent's SPKI — the default layout when an identity key is configured |
iss/sub/aud/iat/exp/jti |
RFC 7523 grant fields |
Remote exchange (RFC 7523): outer token is issued by the token endpoint,
short-lived, with cnf.jkt re-binding the presenter key.
Refusal / problem shapes
Two shapes from aic-verifier; both parse into *RefusalError.
Plain (application/json):
{"code":"access_denied","message":"agent missing required capabilities"}
Remediable (application/problem+json, RFC 9457) — adds type, title,
status, detail, an extended challenge member (CLC-CHALLENGE-v1:
required[].id/constraint/reason, retry_timing.not_before / expires_at),
and may carry a Retry-After header (seconds). errors.As on RefusalError
surfaces Challenge, ChallengeUnavailable, HasRetryAfter,
RetryAfterSec.
allow_unresolved is not allow: neither the client pre-check nor a
challenge is a verdict.
Evidence semantics (client side)
| Term | Meaning |
|---|---|
EvidenceProvider |
deployment hook; returns whether evidence facts now exist at the verifier's EvidenceFacts gate |
| retry bound | wait Retry-After / retry_timing.not_before, never past expires_at |
| byte-identical | the retried request is identical (same body state) |
| at most once | a second denial is returned as-is; never blind retries |
Challenge.Usable |
expired/stale challenges are never retried (anti load-amplification) |
Constants and tokens
| Token | Recommendation |
|---|---|
OutcomeObserved etc. (verifier side) |
outcome classifications belong to the deployment |
AuthorizationApproved / AuthorizationDenied |
AuthorizationDecision.Decision values |
AICRequestStatusApproved |
issuance status enum value |
Conventions
- Per-request minting in local Bearer mode: the verifier treats
jtias single-use, soKeymode never reuses a cached token.Token()is an inspection view only. - Idempotent-only 401 refresh: GET/HEAD/OPTIONS/TRACE,
nilbody, or aGetBody-replayable body. Non-idempotent POST/PUT with a consumed body returns the 401 directly. - Never transmit evidence: the protocol has no evidence channel; the
EvidenceProviderquestions the deployment, never the wire.