Manage mods for your organization changedplugins/mods/admin
Nearest release: v2.1.304, published 6 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 20 Oct 2026 02:14 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 22 Oct 2026 18:07 UTC.
Upstream edited
Recorded here
Lines+51added
Lines−51removed
From line
2
where the diff opens
First seen
1 Oct 2026
this site's first read of the page
Recorded edits14to this page, all time
The whole hunk
from line 2, old and new numbered
/
from line 2
22
33> Control Claude Code mods with managed settings: stop user-installed mods, allow only your own, review what a mod can do, and enforce policy with your own mod.
44
5A [mod](/docs/en/plugins/mods/overview) is a plugin that runs code inside Claude Code with the permissions of the user who installed it. Mods aren't sandboxed. Through [managed settings](/docs/en/managed-settings), you decide whether mods run on your users' machines, which ones, and in what order. You can also install a mod of your own that watches or refuses what other mods do.
5A [mod](/docs/en/plugins/mods/overview.md) is a plugin that runs code inside Claude Code with the permissions of the user who installed it. Mods aren't sandboxed. Through [managed settings](/docs/en/managed-settings.md), you decide whether mods run on your users' machines, which ones, and in what order. You can also install a mod of your own that watches or refuses what other mods do.
66
77This page is for the person who deploys managed settings for Claude Code, whether as a file, through MDM, or from the claude.ai admin console. Mods are on by default in Claude Code v2.1.286 and later. Start with the section that matches what you came to do:
88
from line 14
1414>
1515> These cases are covered on other pages:
1616>
17> * **You haven't deployed managed settings before**: start with [Deploy managed settings](/docs/en/managed-settings)
18> * **You want to control which plugins users can install**: see [Manage plugins for your organization](/docs/en/plugins/org)
17> * **You haven't deployed managed settings before**: start with [Deploy managed settings](/docs/en/managed-settings.md)
18> * **You want to control which plugins users can install**: see [Manage plugins for your organization](/docs/en/plugins/org.md)
1919
2020## Stop user-installed mods from loading
2121
from line 35
3535
3636With the option set in managed settings:
3737
38* **No mod a user brings runs its hooks**: that covers a mod in a plugin the user installed, a mod loaded with `--plugin-dir`, and a mod [Claude wrote during a session](/docs/en/plugins/mods/create#ask-claude-for-a-mod)
38* **No mod a user brings runs its hooks**: that covers a mod in a plugin the user installed, a mod loaded with `--plugin-dir`, and a mod [Claude wrote during a session](/docs/en/plugins/mods/create.md#ask-claude-for-a-mod)
3939* **Your organization's mods still run**: a mod that [counts as your organization's](#install-your-organizations-mods) isn't checked. Every other mod counts as a user's and is refused. That includes a mod in a plugin you enable from a GitHub or other remote marketplace, and one your organization turns on for its members on claude.ai. If none counts as yours, no installed mod runs its hooks.
4040* **Users can't undo it**: the guard reads the option from managed settings only, so the same entry in a user, project, or local settings file, or in a file passed with `--settings`, changes nothing
41* **A file or MDM policy covers every provider**: when you deliver the option as a file or through MDM, it works the same way on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry. For delivery from the claude.ai admin console, see [Platform availability](/docs/en/server-managed-settings#platform-availability)
42* **Users' other customizations keep working**: their [hooks in settings files](/docs/en/hooks) and in plugins' `hooks/hooks.json`, status lines, and `/goal` aren't affected
43* **Built-in mods keep running**: mods built into Claude Code, such as `AGENTS.md` support, each have [their own switch](/docs/en/plugins/mods/overview#mods-built-into-claude-code)
41* **A file or MDM policy covers every provider**: when you deliver the option as a file or through MDM, it works the same way on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry. For delivery from the claude.ai admin console, see [Platform availability](/docs/en/server-managed-settings.md#platform-availability)
42* **Users' other customizations keep working**: their [hooks in settings files](/docs/en/hooks.md) and in plugins' `hooks/hooks.json`, status lines, and `/goal` aren't affected
43* **Built-in mods keep running**: mods built into Claude Code, such as `AGENTS.md` support, each have [their own switch](/docs/en/plugins/mods/overview.md#mods-built-into-claude-code)
4444
45To confirm the option on a user's machine, start Claude Code there with `--plugin-dir` and the path of a directory that holds a mod, such as `claude --plugin-dir ./first-mod`. The mod's hooks don't run, and the transcript and the debug log have the [guard's message](/docs/en/plugins/mods/troubleshoot#messages-from-the-built-in-guard), which names the mod and `allowManagedModsOnly`. If the message isn't there, see [Check that a policy is in force](/docs/en/managed-settings#check-that-a-policy-is-in-force) and the [rules that decide whether an option takes effect](#set-options-on-the-built-in-guard).
45To confirm the option on a user's machine, start Claude Code there with `--plugin-dir` and the path of a directory that holds a mod, such as `claude --plugin-dir ./first-mod`. The mod's hooks don't run, and the transcript and the debug log have the [guard's message](/docs/en/plugins/mods/troubleshoot.md#messages-from-the-built-in-guard), which names the mod and `allowManagedModsOnly`. If the message isn't there, see [Check that a policy is in force](/docs/en/managed-settings.md#check-that-a-policy-is-in-force) and the [rules that decide whether an option takes effect](#set-options-on-the-built-in-guard).
4646
4747If you set `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS` to `0` during early access, replace it with this option. Claude Code v2.1.287 and later ignores the variable at any value, so a `0` there leaves mods on.
4848
from line 62
6262* **Permission rules and `PreToolUse` hooks take precedence over a user's mod.** With the guard loaded, by default a user's mod can't approve a call that a `deny` rule refuses or an `ask` rule prompts for, whichever settings file holds the rule. The mod can't approve a call that any `PreToolUse` hook blocked, either.
6363
6464 Permission rules and `PreToolUse` hooks apply to Claude's tool calls, not to a mod's [`$.fs` and `$.process` calls](/docs/en/plugins/mods/api#reach-files-processes-and-the-network). With `Read(.env)` denied, a mod can still read that file with `$.fs.read` or start a program that does. To limit a mod's own `$.fs` and `$.process` calls, [keep the mod from loading](#stop-user-installed-mods-from-loading) or handle them in a [policy mod](#enforce-a-policy-with-a-mod-of-your-own).
65* **A user's mod can still skip some prompts.** In [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode), a call the mod approves runs without a classifier check, unless the guard is loaded and the session runs with [`--permission-prompt-tool`](/docs/en/cli-reference#cli-flags) or an Agent SDK [`canUseTool` callback](/docs/en/agent-sdk/user-input#handle-tool-approval-requests). There the classifier checks the call first. For the prompts a mod's approval doesn't skip, see [Extend permissions with hooks](/docs/en/permissions#precedence-among-rules-hooks-and-mods).
65* **A user's mod can still skip some prompts.** In [auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), a call the mod approves runs without a classifier check, unless the guard is loaded and the session runs with [`--permission-prompt-tool`](/docs/en/cli-reference#cli-flags) or an Agent SDK [`canUseTool` callback](/docs/en/agent-sdk/user-input#handle-tool-approval-requests). There the classifier checks the call first. For the prompts a mod's approval doesn't skip, see [Extend permissions with hooks](/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).
6666
6767The guard's source is public in the [`mods/sec-default` directory of the Claude Code repository](https://github.com/anthropics/claude-code/tree/main/mods/sec-default).
6868
from line 74
7474* **Deny rules take precedence where the guard loads.** A user's mod can't approve a call that a `deny` rule refuses, unless you set [`allowModsToOverrideDenyRules`](#set-options-on-the-built-in-guard).
7575* **Managed hooks run first.** A `PreToolUse` hook in managed settings runs before any mod's [`tool.call`](/docs/en/plugins/mods/reference#tools) hook, and when that managed hook blocks a tool call, no mod's `tool.call` hook runs for that call. If the call goes ahead and a mod rewrites it, your managed hooks run again on the rewritten call, so they can still block it.
7676
77 `PreToolUse` hooks from other settings files and from plugins run after the last mod. If a mod answers the tool call itself, the tool never runs and neither do those hooks. See [The order mods run in](/docs/en/plugins/mods/events#the-order-mods-run-in).
77 `PreToolUse` hooks from other settings files and from plugins run after the last mod. If a mod answers the tool call itself, the tool never runs and neither do those hooks. See [The order mods run in](/docs/en/plugins/mods/events.md#the-order-mods-run-in).
7878* **Network policy covers `$.http.fetch`.**
7979
80 * **Your organization's policy doesn't allow WebFetch**: Claude Code also refuses every mod's `$.http.fetch` request. See [WebFetch availability](/docs/en/tools-reference#webfetch-availability).
81 * **You turn off the WebFetch tool with [`CLAUDE_CODE_DISABLE_WEB_FETCH`](/docs/en/env-vars#variables) or a `WebFetch` [deny rule](/docs/en/permissions#tool-specific-permission-rules), in managed settings or any other settings file**: mods can still make `$.http.fetch` requests.
80 * **Your organization's policy doesn't allow WebFetch**: Claude Code also refuses every mod's `$.http.fetch` request. See [WebFetch availability](/docs/en/tools-reference.md#webfetch-availability).
81 * **You turn off the WebFetch tool with [`CLAUDE_CODE_DISABLE_WEB_FETCH`](/docs/en/env-vars#variables) or a `WebFetch` [deny rule](/docs/en/permissions.md#tool-specific-permission-rules), in managed settings or any other settings file**: mods can still make `$.http.fetch` requests.
8282
83 To stop them for every mod your users install, [keep user-installed mods from loading](#stop-user-installed-mods-from-loading), or hook `http.fetch` in a [policy mod](#enforce-a-policy-with-a-mod-of-your-own) and refuse requests from users' mods. Give that hook a [`.catch` handler](/docs/en/plugins/mods/events#handle-a-hook-that-fails) that refuses too, because Claude Code skips a hook that fails and the request then goes ahead. If you only [restrict which plugins users can install](/docs/en/plugins/org#restrict-what-users-can-install), fewer mods load, but those you allow still make these requests.
84 * **You set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](/docs/en/env-vars)**: a mod that you or your users install can still make these requests. The variable stops only the [mods built into Claude Code](/docs/en/plugins/mods/overview#mods-built-into-claude-code), plus any `$.http.fetch` request that carries the session's Anthropic credentials. Before v2.1.288, the variable stopped every mod's `$.http.fetch` request.
83 To stop them for every mod your users install, [keep user-installed mods from loading](#stop-user-installed-mods-from-loading), or hook `http.fetch` in a [policy mod](#enforce-a-policy-with-a-mod-of-your-own) and refuse requests from users' mods. Give that hook a [`.catch` handler](/docs/en/plugins/mods/events#handle-a-hook-that-fails) that refuses too, because Claude Code skips a hook that fails and the request then goes ahead. If you only [restrict which plugins users can install](/docs/en/plugins/org.md#restrict-what-users-can-install), fewer mods load, but those you allow still make these requests.
84 * **You set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](/docs/en/env-vars)**: a mod that you or your users install can still make these requests. The variable stops only the [mods built into Claude Code](/docs/en/plugins/mods/overview.md#mods-built-into-claude-code), plus any `$.http.fetch` request that carries the session's Anthropic credentials. Before v2.1.288, the variable stopped every mod's `$.http.fetch` request.
8585
8686 None of these covers a program the mod starts with `$.process.run`, which reaches the network with the user's own access.
87* **Plugin controls cover mods.** A mod is a plugin, so the [settings that restrict what users can install](/docs/en/plugins/org#restrict-what-users-can-install), such as `strictKnownMarketplaces`, decide whether it can be installed at all.
87* **Plugin controls cover mods.** A mod is a plugin, so the [settings that restrict what users can install](/docs/en/plugins/org.md#restrict-what-users-can-install), such as `strictKnownMarketplaces`, decide whether it can be installed at all.
8888* **Mods can't change the permission prompt.** A mod can restyle much of Claude Code's interface, but not the permission prompt, so it can't change what a prompt shows. A mod can still approve or deny a tool call before the prompt appears, as [Know what happens by default](#know-what-happens-by-default) describes.
8989* **Trust prompts come first.** In an interactive session in a directory the user hasn't trusted yet, no mod loads until they answer the trust prompt.
9090* **`--safe-mode` turns installed mods off, yours included.** Start a session with `claude --safe-mode` to check whether a mod caused a problem.
from line 103
103103| A marketplace allowlist | A mod from the marketplaces you allow, or from any directory with `--plugin-dir`. A mod Claude writes during a session loads only when the allowlist [includes `skills-dir`](/docs/en/plugins/org#keep-skills-directory-plugins-loading). |
104104| A marketplace allowlist and `disableSideloadFlags` | A mod from the marketplaces you allow |
105105
106[Manage plugins for your organization](/docs/en/plugins/org) lists the ways a plugin loads and the setting that controls each.
106[Manage plugins for your organization](/docs/en/plugins/org.md) lists the ways a plugin loads and the setting that controls each.
107107
108108To check the mods in a marketplace before your users install them, see [Review what a mod can do](#review-what-a-mod-can-do). To keep users' mods out until you've done that, see [Stop user-installed mods from loading](#stop-user-installed-mods-from-loading).
109109
from line 122
122122 ❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.open
123123```
124124
125The `hooks:` line lists the events the mod receives. The `calls:` line lists the mods API methods its code calls. The [mods API](/docs/en/plugins/mods/api), written `$` in a mod's code, is how a mod reaches files, processes, and the network. Claude Code refuses to load a mod that uses the mods API in a way this command can't read.
125The `hooks:` line lists the events the mod receives. The `calls:` line lists the mods API methods its code calls. The [mods API](/docs/en/plugins/mods/api.md), written `$` in a mod's code, is how a mod reaches files, processes, and the network. Claude Code refuses to load a mod that uses the mods API in a way this command can't read.
126126
127127Look at the `calls:` line for these:
128128
from line 136
136136| `$.mcp.call` | Calls a tool on a connected MCP server, under the session's permission rules |
137137| `$.model.complete` | Uses the user's plan or API key for model calls |
138138| `$.prompt.submit` | Submits a prompt, and can send it as the user's own words |
139| `$.session.send` | Sends a message that another session's, subagent's, or [teammate's](/docs/en/agent-teams) Claude reads |
139| `$.session.send` | Sends a message that another session's, subagent's, or [teammate's](/docs/en/agent-teams.md) Claude reads |
140140
141141In the `hooks:` line, [`tool.call`](/docs/en/plugins/mods/reference#tools) and [`prompt.submit`](/docs/en/plugins/mods/reference#prompts-and-what-claude-reads) mean the mod sees every tool call and every prompt, and can change them. [`session.append`](/docs/en/plugins/mods/reference#session) means the mod can rewrite each row of the conversation before it's stored. [`ui.render{component=AskUserQuestion}`](/docs/en/plugins/mods/interface#change-what-claude-code-already-draws) means the mod can redraw the dialog Claude uses to ask the user a question. `tool.check` means the mod can approve or deny a tool call before a permission prompt appears. [Know what happens by default](#know-what-happens-by-default) lists which of your rules and hooks take precedence over its answer.
142142
143143## Choose how much to allow
144144
145Mod policies range from no installed mods at all to any mod a user chooses, with your own mod checking the others, and each one is a few managed settings. Find the policy you want in the first column and set what the second column names. [Deploy managed settings](/docs/en/managed-settings) covers where managed settings live.
145Mod policies range from no installed mods at all to any mod a user chooses, with your own mod checking the others, and each one is a few managed settings. Find the policy you want in the first column and set what the second column names. [Deploy managed settings](/docs/en/managed-settings.md) covers where managed settings live.
146146
147147| What you want | Settings |
148148| :- | :- |
from line 149
149149| No installed mod runs, with settings hooks untouched | Set [`allowManagedModsOnly`](#set-options-on-the-built-in-guard) and deploy no mods of your own |
150150| No installed mods and no hooks at all, your managed hooks included | Set `disableAllHooks` to `true` |
151151| Only your organization's mods | Set the guard's [`allowManagedModsOnly` option](#stop-user-installed-mods-from-loading), and [install your mods](#install-your-organizations-mods) so that they count as yours |
152| Any mod from marketplaces you approve | Keep your [marketplace restrictions](/docs/en/plugins/org#restrict-what-users-can-install), and set `disableSideloadFlags` to `true` |
152| Any mod from marketplaces you approve | Keep your [marketplace restrictions](/docs/en/plugins/org.md#restrict-what-users-can-install), and set `disableSideloadFlags` to `true` |
153153| Any mod, with your own mod checking the others | [Install your mod](#install-your-organizations-mods), and list it with `sec-default@builtin` in `prependPlugins` |
154154
155155What each setting does:
from line 159
159159* **`disableAllHooks`**: the widest setting. In managed settings, it stops the mods in every installed plugin, yours included, and turns off every hook in settings files, so a `PreToolUse` hook in your managed settings no longer blocks anything. Custom status lines and `/goal` stop working too. Read [`disableAllHooks`](/docs/en/settings-reference#disableallhooks) before you set it.
160160* **`disableSideloadFlags`**: rejects `--plugin-dir` and `--plugin-url` at startup, and keeps mods Claude writes during a session from loading. The setting also rejects `--agents` and `--mcp-config`. Read [`disableSideloadFlags`](/docs/en/settings-reference#disablesideloadflags) before you set it.
161161
162Mods built into Claude Code, such as `AGENTS.md` support, aren't affected by these settings. Each has [its own switch](/docs/en/plugins/mods/overview#mods-built-into-claude-code).
162Mods built into Claude Code, such as `AGENTS.md` support, aren't affected by these settings. Each has [its own switch](/docs/en/plugins/mods/overview.md#mods-built-into-claude-code).
163163
164A user whose mod was refused or didn't load finds the reason in their debug log. [Refusal messages](/docs/en/plugins/mods/troubleshoot#refusal-messages) lists the lines for `allowManagedHooksOnly` and `disableAllHooks`, and [Messages from the built-in guard](/docs/en/plugins/mods/troubleshoot#messages-from-the-built-in-guard) has the line for `allowManagedModsOnly`.
164A user whose mod was refused or didn't load finds the reason in their debug log. [Refusal messages](/docs/en/plugins/mods/troubleshoot.md#refusal-messages) lists the lines for `allowManagedHooksOnly` and `disableAllHooks`, and [Messages from the built-in guard](/docs/en/plugins/mods/troubleshoot.md#messages-from-the-built-in-guard) has the line for `allowManagedModsOnly`.
165165
166166### Allow only your organization's mods
167167
from line 197
197197* **A mod the user installed**: a line reads `refused by cc-plugin-sec-default: mods are limited to your organization's by policy (allowManagedModsOnly)`. An earlier line says that mod's hooks module `loaded`, so look for the refusal.
198198* **A plugin directory**: `claude --plugin-dir ./any-mod` exits with a message that starts `--plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)`
199199
200To also limit which marketplaces users can add, combine this file with your [marketplace restrictions](/docs/en/plugins/org#restrict-what-users-can-install).
200To also limit which marketplaces users can add, combine this file with your [marketplace restrictions](/docs/en/plugins/org.md#restrict-what-users-can-install).
201201
202202### Apply your plugin controls to mods
203203
204A mod is a plugin, so the ways you [manage plugins for your organization](/docs/en/plugins/org) also apply to a plugin that holds a mod:
204A mod is a plugin, so the ways you [manage plugins for your organization](/docs/en/plugins/org.md) also apply to a plugin that holds a mod:
205205
206* **See which plugins load across your fleet**: [Audit and review](/docs/en/plugins/org#audit-and-review)
207* **Decide when a plugin you reviewed can update**: [Set update policy](/docs/en/plugins/org#set-update-policy)
208* **Give one group a different policy, such as a pilot**: [Plan for what managed settings can't enforce](/docs/en/plugins/org#plan-for-what-managed-settings-can’t-enforce)
209* **Check which apps and session kinds apply the plugin keys**: [When each surface applies the plugin keys](/docs/en/plugins/org#when-each-surface-applies-the-plugin-keys)
210* **Set up CI and containers**: [Seed containers and CI](/docs/en/plugins/org#seed-containers-and-ci)
211* **Offer mods your users may install**: [Host a marketplace](/docs/en/plugins/host-marketplace). A mod that Claude Code copies from a GitHub, git, URL, or npm source counts as a user's, not as [your organization's](#install-your-organizations-mods).
206* **See which plugins load across your fleet**: [Audit and review](/docs/en/plugins/org.md#audit-and-review)
207* **Decide when a plugin you reviewed can update**: [Set update policy](/docs/en/plugins/org.md#set-update-policy)
208* **Give one group a different policy, such as a pilot**: [Plan for what managed settings can't enforce](/docs/en/plugins/org.md#plan-for-what-managed-settings-can’t-enforce)
209* **Check which apps and session kinds apply the plugin keys**: [When each surface applies the plugin keys](/docs/en/plugins/org.md#when-each-surface-applies-the-plugin-keys)
210* **Set up CI and containers**: [Seed containers and CI](/docs/en/plugins/org.md#seed-containers-and-ci)
211* **Offer mods your users may install**: [Host a marketplace](/docs/en/plugins/host-marketplace.md). A mod that Claude Code copies from a GitHub, git, URL, or npm source counts as a user's, not as [your organization's](#install-your-organizations-mods).
212212
213213### Set options on the built-in guard
214214
from line 228
228228* **The guard has to load**: if you set `prependPlugins`, [name the guard in the list](#install-your-organizations-mods). Where the guard doesn't load, neither option applies.
229229* **The guard fails closed**: if the guard can't read managed settings, it refuses every user's mod at load. If it can't check the deny rules for a call that a user's mod approved, it refuses the call.
230230
231The [messages from the built-in guard](/docs/en/plugins/mods/troubleshoot#messages-from-the-built-in-guard) are what your users see when either option applies.
231The [messages from the built-in guard](/docs/en/plugins/mods/troubleshoot.md#messages-from-the-built-in-guard) are what your users see when either option applies.
232232
233233## Run your organization's own mods
234234
from line 239
239239Your organization's mods load where users' mods don't and can run ahead of them, so Claude Code has to be able to tell that a mod came from you. It treats a mod as your organization's only when all of these are true:
240240
241241* Managed `enabledPlugins` sets the mod's plugin to `true`
242* Managed settings name the plugin's [marketplace](/docs/en/plugins/create-marketplace) as a directory on the user's machine, by absolute path. An `extraKnownMarketplaces` entry does that and registers the marketplace for the user too.
243* The marketplace lists the plugin by a relative path, so Claude Code [loads it in place](/docs/en/plugins/loading#in-place-and-copied-plugins) from that directory
242* Managed settings name the plugin's [marketplace](/docs/en/plugins/create-marketplace.md) as a directory on the user's machine, by absolute path. An `extraKnownMarketplaces` entry does that and registers the marketplace for the user too.
243* The marketplace lists the plugin by a relative path, so Claude Code [loads it in place](/docs/en/plugins/loading.md#in-place-and-copied-plugins) from that directory
244244
245245To meet them, have your device management copy the marketplace directory to the same path on every machine. Make the directory and every directory above it writable only by an administrator, as the managed settings file is. Anyone who can write there can rewrite your mod. Managed settings you deliver from the claude.ai admin console can carry the keys, but they can't put the directory on a machine.
246246
from line 273
273273
274274A plugin that Claude Code copies into its cache counts as a user's, even when managed `enabledPlugins` enables it. That covers every plugin from a GitHub, git, URL, or npm source. Its mod runs among users' mods, `prependPlugins` and `appendPlugins` skip it, `allowManagedModsOnly` refuses it, and `allowManagedHooksOnly` keeps it from loading. The user's debug log has a line that starts with the plugin's id and `is enabled by managed settings, but`.
275275
276Claude Code fires an event each time it's about to act, such as run a tool, and passes it to each mod in turn. A mod that counts as yours [runs before users' mods](/docs/en/plugins/mods/events#the-order-mods-run-in) even when you list it nowhere. To set its place, list its id in one of two settings. The id is the plugin's name, `@`, and the marketplace's name, such as `acme-guard@acme-tools`.
276Claude Code fires an event each time it's about to act, such as run a tool, and passes it to each mod in turn. A mod that counts as yours [runs before users' mods](/docs/en/plugins/mods/events.md#the-order-mods-run-in) even when you list it nowhere. To set its place, list its id in one of two settings. The id is the plugin's name, `@`, and the marketplace's name, such as `acme-guard@acme-tools`.
277277
278278* **`prependPlugins`**: your mod sees every event before any user's mod and every result after. It can change the event, refuse it, or skip the users' mods.
279279* **`appendPlugins`**: your mod runs after every user's mod, so it sees only the events those mods pass on, in the form they pass them
from line 298
298298* **`enabledPlugins`**: turns `acme-guard` on for every user who receives these managed settings
299299* **`prependPlugins`**: puts `acme-guard` first and the built-in guard second, both ahead of any mod a user installs. Claude Code follows the order you list.
300300
301To confirm that a user's machine received the settings, see [Check that a policy is in force](/docs/en/managed-settings#check-that-a-policy-is-in-force).
301To confirm that a user's machine received the settings, see [Check that a policy is in force](/docs/en/managed-settings.md#check-that-a-policy-is-in-force).
302302
303To confirm where the mod runs, start a session on that machine with `claude --debug` and search the [debug log](/docs/en/plugins/mods/troubleshoot#read-the-debug-log) for the mod's id:
303To confirm where the mod runs, start a session on that machine with `claude --debug` and search the [debug log](/docs/en/plugins/mods/troubleshoot.md#read-the-debug-log) for the mod's id:
304304
305305* **`hooks module acme-guard@acme-tools loaded`, with `tier prepend`**: the mod counts as your organization's and runs first
306306* **The same line with `tier user`**: Claude Code treats it as a user's mod. A second line, `prependPlugins names acme-guard@acme-tools, which is not an enabled managed plugin with a hooks module; skipped`, says the list skipped it.
from line 315
315315
316316To keep every user's mod out, you don't need a mod of your own. Set [`allowManagedModsOnly`](#stop-user-installed-mods-from-loading). Write a policy mod when you want to allow some users' mods and refuse others, or to record what mods do.
317317
318Each time another mod is about to load, your mod receives the list that `claude plugin validate` prints, in an event named [`plugin.register`](/docs/en/plugins/mods/reference#other-mods). A mod in `prependPlugins` can read that list and refuse the mod. It can also [handle any mods API call by name](/docs/en/plugins/mods/api#reach-files-processes-and-the-network) to record or refuse that call for every other mod. The name is the method without the `$.`, so a hook on `fs.write` sees every `$.fs.write` call.
318Each time another mod is about to load, your mod receives the list that `claude plugin validate` prints, in an event named [`plugin.register`](/docs/en/plugins/mods/reference#other-mods). A mod in `prependPlugins` can read that list and refuse the mod. It can also [handle any mods API call by name](/docs/en/plugins/mods/api.md#reach-files-processes-and-the-network) to record or refuse that call for every other mod. The name is the method without the `$.`, so a hook on `fs.write` sees every `$.fs.write` call.
319319
320320This policy mod refuses any user's mod whose own code calls `$.process.run` or `$.process.spawn`. It also keeps an audit log, writing each tool call and each file a mod writes to the debug log. Because it runs first, the log records what was requested, before any user's mod changes it. Save it as `acme-guard/hooks/register.js`:
321321
from line 361
361361* **`e.tier`**: where the mod would run, one of `prepend`, `user`, `append`, or `builtin`. Every mod a person installs is `user`.
362362* **`e.uses.calls`**: the mods API methods the mod calls, each written `namespace.method` such as `process.run`, without the `$.` that `claude plugin validate` prints
363363
364When a user installs a mod that calls `$.process.run`, the mod doesn't load, and their debug log has a line that ends with `refused by acme-guard:` and your reason. The refusal also reaches the transcript in a [session that hot-reloads a plugin directory](/docs/en/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing). To block a call without refusing the whole mod, return `{ deny: 'your reason' }` from a hook on that call's name.
364When a user installs a mod that calls `$.process.run`, the mod doesn't load, and their debug log has a line that ends with `refused by acme-guard:` and your reason. The refusal also reaches the transcript in a [session that hot-reloads a plugin directory](/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing). To block a call without refusing the whole mod, return `{ deny: 'your reason' }` from a hook on that call's name.
365365
366366To send the audit lines somewhere other than the debug log, call `$.http.fetch` from the same hooks.
367367
368A session can run without your mod. If the worker thread that runs installed mods [crashes three times](/docs/en/plugins/mods/troubleshoot#mods-that-run-in-the-hooks-worker-are-off-for-this-session), Claude Code unloads every mod that isn't built in, including yours, until the user runs `/reload-plugins` or starts a new session. And a user who starts Claude Code with `--safe-mode` runs without installed mods, yours included.
368A session can run without your mod. If the worker thread that runs installed mods [crashes three times](/docs/en/plugins/mods/troubleshoot.md#mods-that-run-in-the-hooks-worker-are-off-for-this-session), Claude Code unloads every mod that isn't built in, including yours, until the user runs `/reload-plugins` or starts a new session. And a user who starts Claude Code with `--safe-mode` runs without installed mods, yours included.
369369
370[Create a mod](/docs/en/plugins/mods/create) covers the files a mod needs. [Test a policy mod](/docs/en/plugins/mods/test#test-a-mod-that-judges-other-mods) has a test file for this policy mod.
370[Create a mod](/docs/en/plugins/mods/create.md) covers the files a mod needs. [Test a policy mod](/docs/en/plugins/mods/test.md#test-a-mod-that-judges-other-mods) has a test file for this policy mod.
371371
372372#### Refuse mods when your check fails
373373
from line 396
396396}
397397```
398398
399With the handler in place, a mod that was being checked when the check threw or timed out doesn't load, and the refusal line carries the second reason, as in `refused by acme-guard: Acme policy check failed, so this mod was not loaded`. The handler passes every mod outside the `user` tier to `next(e)`, so a failed check doesn't stop the mods your organization lists. [Handle a hook that fails](/docs/en/plugins/mods/events#handle-a-hook-that-fails) covers `.catch` for other events.
399With the handler in place, a mod that was being checked when the check threw or timed out doesn't load, and the refusal line carries the second reason, as in `refused by acme-guard: Acme policy check failed, so this mod was not loaded`. The handler passes every mod outside the `user` tier to `next(e)`, so a failed check doesn't stop the mods your organization lists. [Handle a hook that fails](/docs/en/plugins/mods/events.md#handle-a-hook-that-fails) covers `.catch` for other events.
400400
401401## Next steps
402402
403* [Plugin security](/docs/en/plugins/security): what any plugin can do on a user's machine, and how to review one before it's installed
404* [Mods overview](/docs/en/plugins/mods/overview): what a mod is and how it compares to hooks, skills, and MCP servers
405* [The order mods run in](/docs/en/plugins/mods/events#the-order-mods-run-in): how `prependPlugins` and `appendPlugins` fit with users' mods
406* [Settings and environment variables](/docs/en/plugins/mods/reference#settings-and-environment-variables): every setting named on this page in one table
403* [Plugin security](/docs/en/plugins/security.md): what any plugin can do on a user's machine, and how to review one before it's installed
404* [Mods overview](/docs/en/plugins/mods/overview.md): what a mod is and how it compares to hooks, skills, and MCP servers
405* [The order mods run in](/docs/en/plugins/mods/events.md#the-order-mods-run-in): how `prependPlugins` and `appendPlugins` fit with users' mods
406* [Settings and environment variables](/docs/en/plugins/mods/reference.md#settings-and-environment-variables): every setting named on this page in one table
407407
No line in this hunk matches that.