apm approve
Synopsis
Section titled “Synopsis”apm approve [PACKAGE_REF...] [OPTIONS]apm policy explain <PACKAGE_REF>Description
Section titled “Description”When the executable gate is enabled, APM blocks unapproved executable
primitives (hooks, bin/ executables, self-defined MCP servers, LSP servers,
and canvas extensions) from dependency packages. Trust is expressed through
one noun, executables, across three layers:
| Layer | Store | Who manages it | Committed? | Authority |
|---|---|---|---|---|
| Project | apm.yml executables.{allow,deny} |
Maintainer / CI setup (apm approve/apm deny) |
Yes | Admin (shared) |
| User | ~/.apm/config.json executables.{allow,deny} |
apm approve --user / apm deny --user |
No | Lowest; below org/project deny |
| Org | apm-policy.yml executables: |
Org admin | Yes (policy repo) | Ceiling on deny |
apm approve adds a grant; apm deny adds a block. By default,
both commands write the project apm.yml (committed, so the whole team
inherits the decision). --user writes your personal
~/.apm/config.json instead – a machine-local grant with lower authority than
org or project denies. Use apm deny --user to narrow trust on one machine.
Text primitives (skills, agents, instructions) are never gated. Local project
content (the root .apm/ directory) is always trusted.
What is gated
Section titled “What is gated”| Type | Gated | Notes |
|---|---|---|
Hooks (.apm/hooks/, hooks/) |
Yes | Auto-fire in IDE on lifecycle events |
Bin executables (bin/) |
Yes | Deployed to agent PATH via symlinks |
| MCP servers (self-defined) | Yes | registry: false servers write to IDE MCP config |
| LSP servers | Yes | Supported runtimes may start generated server commands automatically |
Canvas extensions (.apm/extensions/) |
Yes | Deploys executable Node.js to IDE extensions |
| Text primitives (skills, agents, instructions) | No | No code execution risk |
Precedence (deny-wins, first match wins)
Section titled “Precedence (deny-wins, first match wins)”The install gate and apm audit resolve trust through one shared ladder. The
first matching rung decides:
1. org deny_all / org deny -> denied (absolute ceiling)2. user deny -> denied (narrowing)3. project deny -> denied (committed narrowing)4. project allow -> allowed5. user allow -> allowed6. org recommend -> allowed (user-overridable)7. (no match) -> gated pending approval (denied but approvable)Deny always wins. The org layer is the ceiling on deny – personal consent
cannot widen past an org or project deny. The default (rung 7) is gated
pending approval, not a hard deny: a package with executables and no opinion
anywhere is parked until you approve it, and apm install still succeeds (see
apm install).
There is no enforce mandate runtime or cryptographic signing in this release.
An org executables.enforce rung degrades to recommend (allowed but still
overridable by a deny). Local bundle MCP, LSP, and canvas approvals are bound to
the exact SHA-256 content key printed by apm install.
The gate opt-in
Section titled “The gate opt-in”The gate is enabled when any layer opts in: the project declares an
executables: block (even empty {}), or the org policy carries a non-empty
executables: block. Without any opt-in, executables deploy unconditionally
(backward-compatible).
Options
Section titled “Options”apm approve
Section titled “apm approve”| Flag | Description |
|---|---|
PACKAGE_REF |
One or more packages to approve (e.g. owner/repo). |
--pending |
List all packages with unapproved executables. |
--all |
Approve all currently blocked packages. |
--recommended |
Bulk-accept the org executables.recommend set. |
--list |
Show the fleet-level effective trust decision and deciding layer per installed package. |
--user |
Write the grant to ~/.apm/config.json instead of apm.yml. |
apm policy explain
Section titled “apm policy explain”apm policy explain <PACKAGE_REF> prints the effective executable-trust
decision for a package: allowed or blocked per executable type, the deciding
policy layer, and any shadowed (overridden) lower-authority layers. It is a
subcommand of the apm policy group – the per-package companion
to apm policy status (the policy-chain view).
apm policy explain owner/repoFor a fleet-level view, apm doctor runs an executable-trust drift check that
flags any package allowed locally but denied by org policy and points to apm policy explain for the per-package detail.
Store format
Section titled “Store format”The project executables.allow / executables.deny maps are keyed by
owner/repo#version (or version-blind owner/repo) with per-type boolean
flags:
# apm.yml (committed)executables: allow: "owner/repo#1.2.0": hooks: true bin: true lsp: true deny: "evil/pkg": hooks: true mcp: true bin: true canvas: true lsp: trueThe legacy top-level allowExecutables: block is deprecated. It is still
read as an alias for executables.allow for one minor cycle and is migrated to
executables.allow on the next apm approve / apm deny write. Prefer
executables.allow.
The personal store uses the same shape under executables in
~/.apm/config.json. The standalone ~/.apm/approvals.yml file has been
removed; its contents are migrated into ~/.apm/config.json automatically
on first read.
Ordinary dependency grant keys are package-scoped in v1: a bare owner/repo
key and an owner/repo#1.2.0 key both match the package name regardless of the
installed version. Use that versioned form for audit readability, not as a
per-release trust boundary. Local bundle grants are different: copy the full
name#version@sha256:<digest> key from the install diagnostic. A changed local
bundle does not inherit the prior grant.
Examples
Section titled “Examples”Approve a specific package (writes committed project trust):
apm approve owner/repoApprove for this machine only:
apm approve --user owner/repoList packages awaiting approval:
apm approve --pendingAfter review, approve everything still pending:
apm approve --allAccept the org-recommended set:
apm approve --recommendedInspect effective trust state across installed packages:
apm approve --listTo block a package instead, see apm deny.
Non-interactive / CI usage
Section titled “Non-interactive / CI usage”In CI environments (CI=true, APM_NON_INTERACTIVE=1, or when stdin is not a
TTY), apm install parks unapproved executables and prints the approval
remedy instead of prompting. Pre-approve packages by committing them to the
project executables.allow block (the way to share trust via source control).
Required-but-untrusted executables are enforced by apm audit through the
required-executable-untrusted signal:
executables: allow: "ci-hooks/acme#1.2.0": hooks: true bin: trueSee also
Section titled “See also”apm deny– block executable primitives for packagesapm install– the install command that enforces the gateapm audit– audit installed packages- apm-policy.yml schema – the org
executables:ceiling