Skip to content

Model Governance

v3.0.0 introduces model-policy.json — a per-project governance file that controls which providers and models are allowed.

Quick Start

# Show current policy
dev governance show

# Set corporate mode
dev governance policy corporate

# Edit policy manually
dev config  # opens setup.conf

Policy File Schema

model-policy.json lives at the project root and is generated by 43-governance.sh:

{
  "version": 1,
  "mode": "allow-all",
  "allowed_providers": [],
  "denied_providers": [],
  "allowed_models": [],
  "denied_models": [],
  "max_cost_per_1m": null,
  "audit": false
}

Fields

Field Type Description
version int Schema version (currently 1)
mode string allow-all, allowlist, or corporate
allowed_providers string[] Provider allowlist (empty = all in allow-all mode)
denied_providers string[] Provider blocklist
allowed_models string[] Model allowlist ("*" = all models of allowed providers)
denied_models string[] Model blocklist
max_cost_per_1m number Maximum cost per 1M tokens (null = no limit)
audit bool Enable audit trail (44-audit.sh)

Modes

allow-all

Default. All providers allowed, no restrictions.

{ "mode": "allow-all", "audit": false }

allowlist

Only explicitly listed providers are allowed.

{
  "mode": "allowlist",
  "allowed_providers": ["deepseek", "opencode"],
  "allowed_models": [],
  "audit": false
}

corporate

Strict mode with allowlist + blocklist, cost limits, and audit enabled.

{
  "mode": "corporate",
  "allowed_providers": ["deepseek", "opencode", "openai"],
  "denied_providers": ["ollama", "vllm", "sglang"],
  "denied_models": ["*"],
  "max_cost_per_1m": 30.0,
  "audit": true
}

Enforcement

Policy is enforced at multiple layers:

  1. 18-opencode-json.sh — filters providers in generated opencode.json
  2. pre-session-check.sh — validates policy before each session
  3. 43-governance.sh _provider_allowed() — runtime check per API call
  4. 42-hooks.sh — pre-request hook blocks denied providers

Audit Trail

When "audit": true, every model call is logged to ~/.cache/opencode/audit.jsonl:

{"ts":"2026-08-08T12:00:00Z","event":"model_call","provider":"deepseek","model":"deepseek-v4-pro","tokens_in":1234,"tokens_out":567,"cost":0.0032}
{"ts":"2026-08-08T12:00:05Z","event":"tool_call","tool":"bash","args_hash":"abc123"}
{"ts":"2026-08-08T12:00:10Z","event":"provider_switch","from":"deepseek","to":"zai","reason":"rate_limit"}
{"ts":"2026-08-08T12:00:15Z","event":"pii_redacted","detector":"email","count":3}

7 event types: model_call, tool_call, provider_switch, pii_redacted, config_change, policy_violation, session_boundary.

Rotation

When audit.jsonl exceeds 10MB: - Compressed to audit-YYYY-MM-DD.jsonl.gz - Archived to Qdrant (semantic search) - New audit.jsonl starts fresh - SHA-256 hash-chain links consecutive files

Commands

# Show current policy
dev governance show

# Set policy mode
dev governance policy allow-all
dev governance policy allowlist
dev governance policy corporate

# View audit log
dev audit log
dev audit log --provider deepseek --today

# Audit statistics
dev audit stats

# Force rotation
dev audit rotate

See Also