Skip to content

permission hook: enforce an org-supplied command allowlist, hard denies, and start/end audit events for agent runs #3582

Open

Description

@hsinatfootprintai

Context

Agent runs on a box can run commands outside their tool-access level. The host operator needs (1) an org-supplied command allowlist enforced when a command is requested, (2) a typed denial when a command is outside it, and (3) an audit event for each command. Enforcement today is the run's --restricted and --allowedTools flags (box_run_policy.go), not a hook. This issue adds the mechanism.

Mechanism

Extend the existing run approval server (agent-box approval-mcp, internal/coderun/approval.go) or add a PreToolUse and PostToolUse hook pair. PostToolUse is needed for end events. The choice is made in the design step of this issue and recorded on it.

Acceptance criteria

  • Matching: a glob over argv elements. * matches within one element only. A command containing a shell operator never matches. The executable name matches exactly.
  • An allowlisted command runs outside its tool-access level. Hard denies still block it: outbound network to arbitrary hosts, git push, git remote, and the transport options. Tests for each.
  • A non-matching command is denied with a typed close reason and a blocked event. The run ends. Approval produces a new run; it does not resume this one.
  • Every command writes a start event before it runs, and an end event with exit code when it finishes. Output is not stored.
  • Events go to a daemon-owned sink the run user cannot write to. The existing journal is written by the run user (box_run.proto), so it is not used as the sink.
  • The start request carries the approval id and approver id when a run is a re-run; the decision records them.
  • Command class is a proto enum.
  • Argument redaction from a default list plus an operator-supplied addition list. Environment variables are never logged. Test that a token-looking argument is replaced.
  • Attribution per code run: attribute every permission answer (who, which channel, when) in journal and audit log #2187.
  • The allowlist widens a tool-access level only for matching entries.
  • go test ./... passes.

Out of scope

Cloud storage, the org administration UI, approval routing, and network-level denies (handled outside this issue).

Related

#2944, #2183, #2187, #2526, the approval MCP server (code run --approvals ask).

Activity

  1. hsinatfootprintai commented on Nov 12, 2026

    @hsinatfootprintai
    ContributorAuthor

    Status note: PR #3583 (merged 2026-11-09, in v0.136.0) delivers the hook pair, allowlist enforcement and start/end audit events described here. Leaving this open until the real-box pass of that PR's 'Not verified' items is recorded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions