Shield Agent AI

← Docs hub

Customer guide

Import the AGT audit log

AGT enforces; KYA reports and proves. Upload the audit log written by the Claude Code plugin of Microsoft's Agent Governance Toolkit and its allow, review and deny decisions show up in your console next to everything else. The OSS CLI does the same locally with kya import --from agt.

# console: /app/kya/import, source "agt", file ~/.claude/agt/audit-log.json
curl -X POST "https://shield-agent.com/api/v1/kya/import?from=agt"   -H "X-API-Key: $KYA_API_KEY" -H "Content-Type: application/json"   --data-binary @"$HOME/.claude/agt/audit-log.json"

The body is the whole log: a JSON array, or {seamHash, entries} after AGT rolled over its 10,000-entry cap. Response: accepted, rejected, duplicates, chainVerified, warnings and a capped errors list.

What lands in the trail

AGT logs {timestamp, agentId, action, decision, previousHash, hash} and never records tool arguments, so neither does the import. Every row is host: import, observe mode, importedFrom: agt, stamped with the entry's own timestamp (an entry dated ahead of the import, accepted up to one day for clock skew, is stored as the import time), and carries a chain-verified flag. The console feed shows it as agt: chain verified or agt: chain unverified.

AGTKYA
decision: allowALLOW, IMPORTED_AGT_ALLOW
decision: denyDENY, IMPORTED_AGT_DENY
decision: review (or ask)REQUIRE_APPROVE, IMPORTED_AGT_REVIEW
action: tool.Bashtool Bash (the tool. prefix is stripped)
agentId: claude-code:<session>must be non-empty; the session label is validated but not stored (not linked to a KYA session)

Control characters in names (newlines, ESC, NUL) become spaces. Entries are rejected, and counted, when the decision is not allow, deny, review or ask, the tool name or session id is empty, the stored hash is not 64 lowercase hex characters, or the timestamp is not ISO 8601 within 2000-01-01 and tomorrow.

Hash-chain verification

KYA recomputes every entry hash with AGT's own formula (unkeyed SHA-256 over {timestamp, agentId, action, decision, previousHash}) and never trusts the stored hash field.

  • Chain intact: rows are chainVerified: true.
  • Chain broken (an edited or reordered entry, a missing middle entry, a bare array with its head cut off): the import still runs, warnings names the first bad entry (0-based), and every row from that file is stored chainVerified: false.
  • Re-imports are idempotent per workspace, keyed by the recomputed hash. A forged log imported first can never block the genuine one: the genuine entry still imports as verified.
  • A body that is not an AGT audit log answers 400 and writes nothing.

The chain is unkeyed, so verified means internally consistent, not authentic. Cutting entries off the tail, or cutting the head of a {seamHash, entries} log and resetting seamHash, cannot be detected from AGT's format.

Certify

Rows with an unverified chain are ignored by certify. AGT review is the host's permission prompt, not a KYA human approval, so imported AGT rows never satisfy the approval-path control (SEC-03), even when verified. A verified import can still evidence the deny-path control (SEC-02).

Limits

Workspace-scoped: another workspace importing the same file neither collides with nor sees your rows. Bodies cap at 10MB and imported rows count against the monthly import allowance (Free 10k, Starter 100k, Pro 500k, Scale unlimited); re-imported duplicates cost nothing. Over the allowance the request is refused with 402 and nothing is written. See also Import traces.

Docs hub · Install · How KYA works · Source