AgentGuard plugin · 0.2.2

Tool policy for Codex
and ChatGPT Work.

Start with a record you keep. Add enforcement when you are ready.

Burn 0.2.5, included in the free workflow. A real local session report, re-rendered for readability. The fixed-prefix bucket totals 113,030 tokens across eight responses, or 86.0% of recorded usage. It includes the system prompt, tool schemas and initial user context, counted with the matching cached prefix on later turns.

Install from the public repository

Three commands. Then review the hooks.

  1. codex plugin marketplace add MerchantGuard/agentguard-codex-plugin
  2. codex plugin add agentguard@agentguard
  3. In the installed plugin root reported by Codex:

    npm ci

Use Node 22. Start a new session, open /hooks, inspect the commands and trust them. Codex 0.154 uses the compatibility installation selected by this marketplace.

AgentGuard checks supported local tool calls against your policy: capability tiers, tool allowlists, ethical-wall denies and configured per-matter or per-agent budgets. Burn handles subagent fan-out and sustained usage. The plugin records signed, content-free decisions and outcomes on your machine, including input digests and sizes instead of document text.

Free to observe. Licensed to enforce.

FreePaid
Free shadow mode. Every decision is signed and recorded; nothing is blocked. Includes Burn why and pace.A valid Solo, Startup or Growth license, including Pro variants, enables enforce mode, team policy files, receipts export and seat metering. Includes Burn why and pace.

The plugin uses the existing licenses. See plans and pricing. Activate a key with activate license <KEY> through the agentguard-policy skill.

A record you can inspect

One decision. Its linked outcome.

These are two real signed ledger rows produced by plugin 0.2.1 from synthetic tool events. No document service was called. The outcome describes the supplied test result. This free shadow example records the decision without enforcing it.

Signed decision

{
  "tool": "mcp__synthetic__get_document",
  "mode": "shadow",
  "action": "shadow",
  "capability": "read_only",
  "inputBytes": 16,
  "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
  "entryHash": "3a449e32c44f8195074731aace847b31ec95dcd71bdf48841a1c15976f2ee007"
}
Read the complete signed row
{
  "sequence": 0,
  "decision": {
    "actor": {
      "tenantId": "synthetic-example",
      "agentId": "synthetic-example-agent",
      "sessionId": "synthetic-public-example",
      "provider": "synthetic"
    },
    "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
    "timestamp": "2026-09-19T00:11:10.265Z",
    "action": "shadow",
    "triggeredCap": null,
    "triggeredScopeKey": null,
    "projectedCents": 0,
    "windowSpendBefore": 0,
    "windowSpendAfter": 0,
    "provider": "synthetic",
    "modelRequested": "get_document",
    "modelResolved": "get_document",
    "policyId": "agentguard-codex",
    "policyVersion": 1,
    "enforcementMode": "shadow",
    "reasons": [
      "license_required",
      "tool_policy_allowed"
    ],
    "costBasis": {
      "inputCentsPerKtok": 0,
      "outputCentsPerKtok": 0,
      "rateSource": "override:manual"
    },
    "plugin": {
      "schema": "agentguard.codex.v1",
      "requestId": "22e41f98-66a7-4959-b10c-9a19866c9362",
      "gate": "spend",
      "toolName": "mcp__synthetic__get_document",
      "toolUseId": "synthetic-public-call",
      "sessionId": "synthetic-public-example",
      "agentId": "synthetic-example-agent",
      "inputSha256": "bba2d36669004a3ef16764b0dfe370dfc0c22263976dfd3d896370b3fa39be0d",
      "inputBytes": 16,
      "inputKeys": 1,
      "startedAt": "2026-09-19T00:11:10.262Z",
      "event": "decision",
      "capabilityTier": "read_only",
      "unitCostCents": 0,
      "chargedCents": 0,
      "chargedWindows": [],
      "license": {
        "paid": false,
        "tier": "free",
        "seatsUsed": null,
        "seatLimit": 1,
        "expiresAt": null,
        "mode": "shadow",
        "reason": "license_required",
        "offlineGrace": false
      },
      "reasonCode": "license_required"
    }
  },
  "previousHash": "0000000000000000000000000000000000000000000000000000000000000000",
  "entryHash": "3a449e32c44f8195074731aace847b31ec95dcd71bdf48841a1c15976f2ee007",
  "signature": "6a349c4f635156a96a2b23e796c9091273215d871b2fcdc6290eb7fc8be106470814a6af07972b40727c9fceb214803663efbab5d0dbd84618ab93894c6f1e05",
  "signerFingerprint": "2bd736f15a24c521",
  "publicKeyHex": "454b0a9a00894c91c6a711d9aedb8f0af43648d8740565a3f49e588ece03ac38"
}

Signed outcome receipt

{
  "status": "completed",
  "durationMs": 1,
  "outputBytes": 11,
  "originalDecisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
  "entryHash": "c19c32a89ca46b22e6fa5fb720467a5ec7fa08985d66aecfea7f907be01affa1"
}
Read the complete signed row
{
  "sequence": 1,
  "decision": {
    "decisionId": "473fad1b-d62b-4057-8c41-5b344becdbf4",
    "timestamp": "2026-09-19T00:11:10.268Z",
    "action": "allow",
    "triggeredCap": null,
    "triggeredScopeKey": null,
    "projectedCents": 0,
    "windowSpendBefore": 0,
    "windowSpendAfter": 0,
    "provider": "unknown",
    "modelRequested": "outcome-runtime",
    "modelResolved": "outcome-runtime",
    "policyId": "agentguard-codex",
    "policyVersion": 1,
    "enforcementMode": "shadow",
    "reasons": [
      "license_required",
      "Outcome runtime metadata receipt recorded locally"
    ],
    "entryType": "outcome",
    "outcomeReceipt": {
      "flow": "codex-tool",
      "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
      "status": "completed",
      "durationMs": 1,
      "outputBytes": 11,
      "totalCostCents": 0
    },
    "originalDecisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
    "actor": {
      "tenantId": "synthetic-example",
      "agentId": "synthetic-example-agent",
      "sessionId": "synthetic-public-example",
      "provider": "synthetic"
    },
    "plugin": {
      "schema": "agentguard.codex.v1",
      "requestId": "6312891e-b0af-4c52-9400-06f83b9639ce",
      "gate": "receipt",
      "toolName": "mcp__synthetic__get_document",
      "toolUseId": "synthetic-public-call",
      "sessionId": "synthetic-public-example",
      "agentId": "synthetic-example-agent",
      "inputSha256": "bba2d36669004a3ef16764b0dfe370dfc0c22263976dfd3d896370b3fa39be0d",
      "inputBytes": 16,
      "inputKeys": 1,
      "startedAt": "2026-09-19T00:11:10.268Z",
      "outputBytes": 11,
      "success": true,
      "durationMs": 1,
      "durationSource": "host",
      "event": "outcome",
      "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
      "license": {
        "paid": false,
        "tier": "free",
        "seatsUsed": null,
        "seatLimit": 1,
        "expiresAt": null,
        "mode": "shadow",
        "reason": "license_required",
        "offlineGrace": false
      },
      "reasonCode": "license_required"
    }
  },
  "previousHash": "3a449e32c44f8195074731aace847b31ec95dcd71bdf48841a1c15976f2ee007",
  "entryHash": "c19c32a89ca46b22e6fa5fb720467a5ec7fa08985d66aecfea7f907be01affa1",
  "signature": "1f1d4c21716588ec838c86929eb57838ee3fcbd71763eb9f64d59d7828f5af78870c26a8a3fcdeeb375baf9aac14562c164b8c06da4f59e50773613cc983040e",
  "signerFingerprint": "2bd736f15a24c521",
  "publicKeyHex": "454b0a9a00894c91c6a711d9aedb8f0af43648d8740565a3f49e588ece03ac38"
}

The public fixture verifies as a two-entry chain. Signatures protect the recorded fields; they do not independently attest to an external action. The fixture contains identifiers, digests and sizes, with no tool input or output text.

Coverage and limits.

Hooks cover supported local tools in Codex and ChatGPT Work, including plugin MCP tools. Web ChatGPT and hosted tools such as WebSearch are outside that path. Continuing an approved shell session does not create a new pre-tool decision, and some specialized tool paths can opt out.

Hooks are fail-open: an internal error or timeout allows the call and warns when possible. Disabled or untrusted hooks do not govern calls. The plugin is an additional policy layer; service-side authorization remains the boundary for access to documents or payments.

The worker signs and writes a row before replying, then syncs it asynchronously. An unconfirmed tail can be lost on power failure; restart records a signed integrity event when evidence survives. Read the runtime and durability details.

Install a reviewed policy across a firm.

The enterprise guide covers reviewed trust configuration, private marketplaces and managed hook delivery through MDM. Managed delivery does not turn fail-open hooks into fail-closed authorization.