ozm - Oberzugriffsmeister ("chief access master") - is a command gate for AI coding agents. It lets agents run useful shell, script, and git commands while risky work still passes through human-owned policy or review.
Most agent setups force a bad choice: babysit every command, or trust the agent blindly. ozm gives you a third option. It sits between the agent and your shell, checks command intent and content, and remembers approvals per project so repeated safe work can flow.
ozm run, are reviewed by content hash, and show diffs when they change.ozm cmd, with exact command approvals cached per project.ozm run, ozm cmd, and ozm git call must include --agent-name and --agent-description, so approval dialogs show what the agent is trying to do.--reason for explicit user approval without changing caches or allowlists.ozm and write agent instructions for the project.ozm log, ozm status, ozm config, and ozm doctor expose what happened and how the install is configured.flowchart LR
Agent([AI Agent]):::blue ==>|command| Ozm{ozm}:::purple
Ozm ==>|cached, allowlisted,\nor semantic read-only| Run([Execute]):::green
Ozm ==>|new or changed| Dialog([Approval Dialog]):::yellow
Ozm ==>|blocked by config\nor git policy| Override{Reason?}:::orange
Override ==>|no| Deny([Denied]):::red
Override ==>|yes| Dialog
Dialog ==>|allow| Run
Dialog ==>|deny| Deny
Deny -..->|feedback| Agent
classDef blue fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f,stroke-width:2px
classDef purple fill:#ede9fe,stroke:#8b5cf6,color:#3b1f7e,stroke-width:2px
classDef green fill:#d1fae5,stroke:#10b981,color:#064e3b,stroke-width:2px
classDef red fill:#fee2e2,stroke:#ef4444,color:#7f1d1d,stroke-width:2px
classDef yellow fill:#fef9c3,stroke:#eab308,color:#713f12,stroke-width:2px
classDef orange fill:#ffedd5,stroke:#f97316,color:#7c2d12,stroke-width:2px
Screenshot placeholder: command approval dialog (
docs/screenshots/command-approval.png)Show agent name, agent description, editable command, allow/block rule pattern, Apply globally, and feedback field.
Screenshot placeholder: changed script diff review (
docs/screenshots/script-diff.png)Show a changed script with syntax-highlighted unified diff and approval buttons.
Screenshot placeholder: diagnostics and status (
docs/screenshots/doctor-status.png)Show
ozm doctor,ozm config, andozm statusoutput in a terminal.
# via Homebrew
brew tap kamyar/ozm https://github.com/kamyar/ozm
brew install ozm
# or via uv
uv tool install ozm
# or via pip
pip install ozm
cd your-project
ozm install --project
ozm doctor
ozm install --project installs the Claude Code and Codex hooks, then writes or appends CLAUDE.md and AGENTS.md instructions in the project. Restart Codex after installing so new sessions load the hook and execpolicy configuration.
Configuration is optional. Without config, unknown commands and new or changed scripts go through the approval dialog. To pre-approve common safe commands or block known dangerous ones, create .ozm.yaml, run ozm trust, and use ozm config to see where the trusted copy lives.
ozm works with any AI coding agent that executes shell commands:
PreToolUse system via ~/.claude/settings.json.~/.codex/config.toml, installs additive execpolicy rules in ~/.codex/rules/ozm-enforcement.rules, and writes AGENTS.md for project-level instructions.CLAUDE.md or AGENTS.md can route commands through ozm.For Claude Code and Codex, enforcement is automatic via hooks and policy. For other agents, compliance depends on the agent following the project instructions.
ozm runUse ozm run for scripts, not python script.py, bash script.sh, uv run, or ./script.sh directly.
ozm run --agent-name "Run tests" --agent-description "Execute the reviewed test script." ./scripts/test.sh
Scripts must have a shebang, but the source file does not need an executable file mode. Do not run chmod +x before ozm run; ozm executes the reviewed content from a private, user-executable snapshot. Ozm rejects scripts with only one executable line before cache or approval checks. It also rejects disk, stdin, and generated in-memory shell files when every command segment is an ozm invocation. Run those Ozm commands directly and one at a time so normal automatic approvals can apply. Run other single commands directly with ozm cmd, ozm gh, or ozm git; use ozm bash --command when shell syntax is required. The first approval stores the script's SHA-256 hash under the current project. Unchanged scripts run without prompting; changed scripts show a diff against the last approved snapshot before they can run again.
Put root options before the command family. Use --cwd DIRECTORY instead of a shell cd wrapper. Repeat --grep TERM to show stdout lines that contain any selected literal term. Use --head N or --tail N to select leading or trailing filtered lines:
ozm --cwd /path/to/worktree --grep "projection" --grep "coverage" --head 20 git --agent-name "Inspect main" --agent-description "Find projection and coverage code on main." show origin/main:path/to/config.go
The controls work with ozm cmd, ozm gh, ozm git, and ozm run. Ozm applies --cwd before project policy. It applies --grep before --head or --tail. Ozm leaves stderr unchanged, continues consuming stdout until the child finishes, and preserves the child exit code even when grep finds no line. Use these options instead of creating a shell pipeline with grep, rg, head, or tail only to filter output. Ozm nudges generated commands that end in || true, rejects raw or Ozm shell pipelines that end in a supported head form, and blocks Ozm pipelines to true because they discard output and can interrupt execution. Generated wrappers made only of separate simple commands must run each command directly. Generated wrappers must not invoke or source mutable scripts because the dialog would review the wrapper instead of the target script content.
ozm cmdUse ozm cmd for non-script commands.
ozm cmd --agent-name "Install deps" --agent-description "Install project dependencies." uv pip install -e .
ozm cmd --agent-name "Check API" --agent-description "Call the service health endpoint." curl https://api.example.com/health
Conservative built-in reads such as command -v, bazel query, brew search, npm view, and npm list run without command approval or cache checks. Write-capable and unknown forms retain normal policy. ozm cmd executes argv directly rather than through a shell. It detects direct, interpreter, and wrapper-based script execution, preserves script arguments in the ozm run nudge, and redirects before policy or cache checks, refuses ozm cmd git ... in favor of ozm git, refuses direct gh or ozm cmd gh ... usage in favor of ozm gh, and hard-blocks cases that are unsafe to blanket approve, including sed, gsed, and rg --pre. When chmod targets a file modified in the last 10 minutes, Ozm requires --confirm-recent-chmod before normal command policy checks continue. Bare env output is blocked because it can expose secrets. Executables under temporary locations bypass config and cache; they require a reasoned one-time override, display their SHA-256 digest, and are rechecked after approval.
Use ozm gh for GitHub operations. It applies the normal blocklist, allowlist, cache, and approval flow, then resolves gh from trusted system locations. Use typed ozm gh pr review-reply and ozm gh issue add-sub-issue operations for fixed repository writes; Ozm rejects equivalent raw REST POST requests and prints typed replacements. Exact repositories can authorize these operations under github.allowed_operations. Known high-level reads and unambiguous REST GET and HEAD requests can run without an approval dialog. REST writes, ambiguous methods, file-backed input, unsafe method-override headers, and absolute non-GitHub endpoints still require review. GraphQL requests such as gh api graphql -f query=... are auto-allowed only when the selected operation is definitely a query. Mutations, file-backed queries, malformed documents, or ambiguous multi-operation requests still require review.
ozm gitUse ozm git for git operations.
ozm git --agent-name "Commit fix" --agent-description "Create a short commit for the config fix." commit -m "Fix config loading"
ozm git --agent-name "Inspect status" --agent-description "Check the current git state." status
All git subcommands pass through, but policy checks apply to commits, pushes, dangerous history-rewrite commands, and dangerous config keys. Commit messages must use one single-line -m "message" with a 72-character subject limit and 500-character total limit. Commit-message shape errors cannot be overridden. Broad force pushes are blocked without a dialog. Only --force-with-lease=REF:EXPECTED_SHA can request a one-time override. Pushes to main or master remain override-gated.
For an override-eligible operation, add --reason "..." to request a one-time override:
ozm git --agent-name "Ship hotfix" --agent-description "Push the production fix branch." push --reason "Emergency release approved by the user."
ozm cmd --agent-name "Clean build" --agent-description "Remove generated build artifacts." rm -rf build/ --reason "Clear stale generated output before rebuilding."
Approved overrides run once, are logged, and are not cached or converted into allowlist rules.
$ ozm --help
Commands:
cmd Run an arbitrary command after approval.
config Show the path to this project's user-owned config.
doctor Check ozm installation health.
gh Operation-aware GitHub CLI proxy.
git Git pass-through.
install Install ozm hooks system-wide.
log Show recent audit log entries.
reset Forget approval for a script (or all scripts with --all).
run Run a script after content review (hash-gated).
status Show tracked files and commands with their approval status.
trust Snapshot the in-repo .ozm.yaml into ~/.ozm/projects/.
version Show ozm version.
See docs/commands.md for detailed usage and examples.
Configuration is optional. Without it, every new command or changed script goes through the approval dialog or project-scoped hash cache. To pre-approve safe commands, create .ozm.yaml in your project root:
allowed_commands:
- pytest
- "gh issue view"
- "gh pr view"
- "uv pip install *"
- "docker compose *"
blocked_commands:
- "rm -rf *"
- "curl * | sh"
commit:
allow_attribution: false
require_branch: false
branch_prefixes: []
Then run ozm trust to activate it. This copies .ozm.yaml into ~/.ozm/projects/, where ozm actually reads it. The in-repo file is never read at runtime, so agents can edit it freely but changes have no effect until a human explicitly trusts them.
Use ozm config to print the current project root, trusted project config path, global config path, and whether the trusted project config exists.
For commands you want available in every project, add allowed_commands or blocked_commands to ~/.ozm/config.yaml, or check Apply globally when saving a rule from the command approval dialog. If the rule field is blank, ozm saves the exact command globally. Global and project blocklists are evaluated before any allowlist.
Security note: Avoid patterns like
"uv run *","python *", or"uv *"inallowed_commands; these bypass content review for script files. Useozm runfor scripts instead.sed,gsed, andrg --preare never allowlisted because they can execute or edit content outside the reviewed script path.
See docs/configuration.md for all options.
ozm install writes the enforcement hook and configures Claude Code and Codex to use it.ozm run, ozm cmd, or ozm git.ozm run, ozm cmd, and ozm git reject missing, empty, multiline, or malformed agent metadata before execution.~/.ozm/hashes.yaml; changed script snapshots live under ~/.ozm/snapshots/.~/.ozm/audit.log. Use ozm log --summary --since 3h to count manual approvals, denials, and generated run approvals. Generated run entries include a content digest and safe command-family summary. Actions include clicked, cached, config, semantic, operation, override, denied, blocked, or no-dialog.On macOS, approvals use native Cocoa dialogs with syntax highlighting via Pygments, dark mode support, agent work context, editable command fields, and inline feedback. Without a GUI session, unknown commands and new or changed scripts are blocked rather than silently approved.
136 commits
32 commits
Python
88.1%
Swift
8.9%
TypeScript
2.7%
ozm - Oberzugriffsmeister ("chief access master") - is a command gate for AI coding agents. It lets agents run useful shell, script, and git commands while risky work still passes through human-owned policy or review.
Most agent setups force a bad choice: babysit every command, or trust the agent blindly. ozm gives you a third option. It sits between the agent and your shell, checks command intent and content, and remembers approvals per project so repeated safe work can flow.
ozm run, are reviewed by content hash, and show diffs when they change.ozm cmd, with exact command approvals cached per project.ozm run, ozm cmd, and ozm git call must include --agent-name and --agent-description, so approval dialogs show what the agent is trying to do.--reason for explicit user approval without changing caches or allowlists.ozm and write agent instructions for the project.ozm log, ozm status, ozm config, and ozm doctor expose what happened and how the install is configured.flowchart LR
Agent([AI Agent]):::blue ==>|command| Ozm{ozm}:::purple
Ozm ==>|cached, allowlisted,\nor semantic read-only| Run([Execute]):::green
Ozm ==>|new or changed| Dialog([Approval Dialog]):::yellow
Ozm ==>|blocked by config\nor git policy| Override{Reason?}:::orange
Override ==>|no| Deny([Denied]):::red
Override ==>|yes| Dialog
Dialog ==>|allow| Run
Dialog ==>|deny| Deny
Deny -..->|feedback| Agent
classDef blue fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f,stroke-width:2px
classDef purple fill:#ede9fe,stroke:#8b5cf6,color:#3b1f7e,stroke-width:2px
classDef green fill:#d1fae5,stroke:#10b981,color:#064e3b,stroke-width:2px
classDef red fill:#fee2e2,stroke:#ef4444,color:#7f1d1d,stroke-width:2px
classDef yellow fill:#fef9c3,stroke:#eab308,color:#713f12,stroke-width:2px
classDef orange fill:#ffedd5,stroke:#f97316,color:#7c2d12,stroke-width:2px
Screenshot placeholder: command approval dialog (
docs/screenshots/command-approval.png)Show agent name, agent description, editable command, allow/block rule pattern, Apply globally, and feedback field.
Screenshot placeholder: changed script diff review (
docs/screenshots/script-diff.png)Show a changed script with syntax-highlighted unified diff and approval buttons.
Screenshot placeholder: diagnostics and status (
docs/screenshots/doctor-status.png)Show
ozm doctor,ozm config, andozm statusoutput in a terminal.
# via Homebrew
brew tap kamyar/ozm https://github.com/kamyar/ozm
brew install ozm
# or via uv
uv tool install ozm
# or via pip
pip install ozm
cd your-project
ozm install --project
ozm doctor
ozm install --project installs the Claude Code and Codex hooks, then writes or appends CLAUDE.md and AGENTS.md instructions in the project. Restart Codex after installing so new sessions load the hook and execpolicy configuration.
Configuration is optional. Without config, unknown commands and new or changed scripts go through the approval dialog. To pre-approve common safe commands or block known dangerous ones, create .ozm.yaml, run ozm trust, and use ozm config to see where the trusted copy lives.
ozm works with any AI coding agent that executes shell commands:
PreToolUse system via ~/.claude/settings.json.~/.codex/config.toml, installs additive execpolicy rules in ~/.codex/rules/ozm-enforcement.rules, and writes AGENTS.md for project-level instructions.CLAUDE.md or AGENTS.md can route commands through ozm.For Claude Code and Codex, enforcement is automatic via hooks and policy. For other agents, compliance depends on the agent following the project instructions.
ozm runUse ozm run for scripts, not python script.py, bash script.sh, uv run, or ./script.sh directly.
ozm run --agent-name "Run tests" --agent-description "Execute the reviewed test script." ./scripts/test.sh
Scripts must have a shebang, but the source file does not need an executable file mode. Do not run chmod +x before ozm run; ozm executes the reviewed content from a private, user-executable snapshot. Ozm rejects scripts with only one executable line before cache or approval checks. It also rejects disk, stdin, and generated in-memory shell files when every command segment is an ozm invocation. Run those Ozm commands directly and one at a time so normal automatic approvals can apply. Run other single commands directly with ozm cmd, ozm gh, or ozm git; use ozm bash --command when shell syntax is required. The first approval stores the script's SHA-256 hash under the current project. Unchanged scripts run without prompting; changed scripts show a diff against the last approved snapshot before they can run again.
Put root options before the command family. Use --cwd DIRECTORY instead of a shell cd wrapper. Repeat --grep TERM to show stdout lines that contain any selected literal term. Use --head N or --tail N to select leading or trailing filtered lines:
ozm --cwd /path/to/worktree --grep "projection" --grep "coverage" --head 20 git --agent-name "Inspect main" --agent-description "Find projection and coverage code on main." show origin/main:path/to/config.go
The controls work with ozm cmd, ozm gh, ozm git, and ozm run. Ozm applies --cwd before project policy. It applies --grep before --head or --tail. Ozm leaves stderr unchanged, continues consuming stdout until the child finishes, and preserves the child exit code even when grep finds no line. Use these options instead of creating a shell pipeline with grep, rg, head, or tail only to filter output. Ozm nudges generated commands that end in || true, rejects raw or Ozm shell pipelines that end in a supported head form, and blocks Ozm pipelines to true because they discard output and can interrupt execution. Generated wrappers made only of separate simple commands must run each command directly. Generated wrappers must not invoke or source mutable scripts because the dialog would review the wrapper instead of the target script content.
ozm cmdUse ozm cmd for non-script commands.
ozm cmd --agent-name "Install deps" --agent-description "Install project dependencies." uv pip install -e .
ozm cmd --agent-name "Check API" --agent-description "Call the service health endpoint." curl https://api.example.com/health
Conservative built-in reads such as command -v, bazel query, brew search, npm view, and npm list run without command approval or cache checks. Write-capable and unknown forms retain normal policy. ozm cmd executes argv directly rather than through a shell. It detects direct, interpreter, and wrapper-based script execution, preserves script arguments in the ozm run nudge, and redirects before policy or cache checks, refuses ozm cmd git ... in favor of ozm git, refuses direct gh or ozm cmd gh ... usage in favor of ozm gh, and hard-blocks cases that are unsafe to blanket approve, including sed, gsed, and rg --pre. When chmod targets a file modified in the last 10 minutes, Ozm requires --confirm-recent-chmod before normal command policy checks continue. Bare env output is blocked because it can expose secrets. Executables under temporary locations bypass config and cache; they require a reasoned one-time override, display their SHA-256 digest, and are rechecked after approval.
Use ozm gh for GitHub operations. It applies the normal blocklist, allowlist, cache, and approval flow, then resolves gh from trusted system locations. Use typed ozm gh pr review-reply and ozm gh issue add-sub-issue operations for fixed repository writes; Ozm rejects equivalent raw REST POST requests and prints typed replacements. Exact repositories can authorize these operations under github.allowed_operations. Known high-level reads and unambiguous REST GET and HEAD requests can run without an approval dialog. REST writes, ambiguous methods, file-backed input, unsafe method-override headers, and absolute non-GitHub endpoints still require review. GraphQL requests such as gh api graphql -f query=... are auto-allowed only when the selected operation is definitely a query. Mutations, file-backed queries, malformed documents, or ambiguous multi-operation requests still require review.
ozm gitUse ozm git for git operations.
ozm git --agent-name "Commit fix" --agent-description "Create a short commit for the config fix." commit -m "Fix config loading"
ozm git --agent-name "Inspect status" --agent-description "Check the current git state." status
All git subcommands pass through, but policy checks apply to commits, pushes, dangerous history-rewrite commands, and dangerous config keys. Commit messages must use one single-line -m "message" with a 72-character subject limit and 500-character total limit. Commit-message shape errors cannot be overridden. Broad force pushes are blocked without a dialog. Only --force-with-lease=REF:EXPECTED_SHA can request a one-time override. Pushes to main or master remain override-gated.
For an override-eligible operation, add --reason "..." to request a one-time override:
ozm git --agent-name "Ship hotfix" --agent-description "Push the production fix branch." push --reason "Emergency release approved by the user."
ozm cmd --agent-name "Clean build" --agent-description "Remove generated build artifacts." rm -rf build/ --reason "Clear stale generated output before rebuilding."
Approved overrides run once, are logged, and are not cached or converted into allowlist rules.
$ ozm --help
Commands:
cmd Run an arbitrary command after approval.
config Show the path to this project's user-owned config.
doctor Check ozm installation health.
gh Operation-aware GitHub CLI proxy.
git Git pass-through.
install Install ozm hooks system-wide.
log Show recent audit log entries.
reset Forget approval for a script (or all scripts with --all).
run Run a script after content review (hash-gated).
status Show tracked files and commands with their approval status.
trust Snapshot the in-repo .ozm.yaml into ~/.ozm/projects/.
version Show ozm version.
See docs/commands.md for detailed usage and examples.
Configuration is optional. Without it, every new command or changed script goes through the approval dialog or project-scoped hash cache. To pre-approve safe commands, create .ozm.yaml in your project root:
allowed_commands:
- pytest
- "gh issue view"
- "gh pr view"
- "uv pip install *"
- "docker compose *"
blocked_commands:
- "rm -rf *"
- "curl * | sh"
commit:
allow_attribution: false
require_branch: false
branch_prefixes: []
Then run ozm trust to activate it. This copies .ozm.yaml into ~/.ozm/projects/, where ozm actually reads it. The in-repo file is never read at runtime, so agents can edit it freely but changes have no effect until a human explicitly trusts them.
Use ozm config to print the current project root, trusted project config path, global config path, and whether the trusted project config exists.
For commands you want available in every project, add allowed_commands or blocked_commands to ~/.ozm/config.yaml, or check Apply globally when saving a rule from the command approval dialog. If the rule field is blank, ozm saves the exact command globally. Global and project blocklists are evaluated before any allowlist.
Security note: Avoid patterns like
"uv run *","python *", or"uv *"inallowed_commands; these bypass content review for script files. Useozm runfor scripts instead.sed,gsed, andrg --preare never allowlisted because they can execute or edit content outside the reviewed script path.
See docs/configuration.md for all options.
ozm install writes the enforcement hook and configures Claude Code and Codex to use it.ozm run, ozm cmd, or ozm git.ozm run, ozm cmd, and ozm git reject missing, empty, multiline, or malformed agent metadata before execution.~/.ozm/hashes.yaml; changed script snapshots live under ~/.ozm/snapshots/.~/.ozm/audit.log. Use ozm log --summary --since 3h to count manual approvals, denials, and generated run approvals. Generated run entries include a content digest and safe command-family summary. Actions include clicked, cached, config, semantic, operation, override, denied, blocked, or no-dialog.On macOS, approvals use native Cocoa dialogs with syntax highlighting via Pygments, dark mode support, agent work context, editable command fields, and inline feedback. Without a GUI session, unknown commands and new or changed scripts are blocked rather than silently approved.
136 commits
32 commits
Python
88.1%
Swift
8.9%
TypeScript
2.7%