spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / mods / sec-default / README.md
55 lines · 3.6 KBPreviewCodeRaw
1# sec-default
2
3The security default for organizations. Function hooks give every plugin a
4say on every event, in chain order, and the plugins a person installs sit
5in the user tier, beneath the organization's prepend tier and above its
6append tier. Some of what an organization sets today (its classic hooks,
7its managed CLAUDE.md and rules, its settings, its MCP allowlist) was never
8within a person's reach before function hooks; seated outermost, this
9plugin keeps exactly those out of the user tier's reach and adds no policy
10of its own. Everything else passes through untouched.
11
12It has three moves and nothing else: continue past the user tier
13(`next.to(e, "append")`), refuse a user-tier caller by name (`{ deny }`
14when `next.origin.tier` is `user`), or pass (`next(e)`). A subject's
15provenance is the event's pinned `e.provider`; policy is read through
16`$.settings.read({ source: "policy" })`, one read serving a burst; both
17fail closed, so an unreadable policy counts as a policy in force.
18
19`hooks/register.ts` is the module; `hooks/policy/` reads the managed
20settings it decides by.
21
22## The rows
23
24| event | from the outermost seat |
25| --- | --- |
26| `classic.*` | Continue past the user tier: the organization's settings hooks see the engine's input and their answer stands. |
27| `prompt.section`, `prompt.context`, `skill.prompt`, `attribution.text` | Continue past the user tier: managed CLAUDE.md, rules and policy skills reach the model as written. A person's plugins keep `prompt.submit` and its additive context. |
28| `settings.read` | Continue past the user tier: no user hook rewrites what any caller reads as settings, this plugin's own policy reads included. |
29| `tool.describe`, `command.describe`, `agent.offer`, `agent.spawn` | When the subject's pinned `e.provider.tier` is `prepend` or `append` (a policy-installed plugin, the managed folder, a policy MCP server), continue past the user tier; a subject provided by `user`, `builtin` or `core` passes. |
30| `tool.register` | A caller in `prepend` or `append` continues past the user tier. A `user`-tier caller is refused by name while managed settings hold `allowedMcpServers` (set at all, empty included); otherwise it passes. |
31| `tool.list` | The tools of the organization's managed MCP servers are listed as the organization's tiers listed them; every other tool as the user tier left it. With no policy to read, or a refusal from either listing, the organization's listing stands whole. |
32| everything else | Passes: `prompt.submit`, `turn.*`, `tool.call`, `tool.check`, `command.run`, `command.register`, `session.*`, `ui.*`, `fs.*`, `http.fetch`, `process.run`, `store.*`, `clock.*`, `model.*`, `mcp.call`, `audio.*`, `agent.list`, `engine.create`. |
33
34## What it hooks
35
36`classic.*`, `prompt.section`, `prompt.context`, `skill.prompt`,
37`attribution.text`, `settings.read`, `tool.describe`, `command.describe`,
38`agent.offer`, `agent.spawn`, `tool.register`, `tool.list`.
39
40## What it calls on `$`
41
42`settings.read`. It continues to the `append` tier with `next.to`, which
43only a plugin in a managed tier may do.
44
45## Where it is seated
46
47The CLI seats it first in the prepend tier wherever hooks modules load on a
48machine with managed settings or for a Team or Enterprise organization,
49unless managed settings define `prependPlugins`: then that list is the
50whole prepend tier, and the organization names `sec-default@builtin` in it
51at the position it wants, e.g. `"prependPlugins": ["acme-guard@acme-tools",
52"sec-default@builtin"]`, or leaves it out. It is a plugin folder like any
53other, but its one move that matters, `next.to`, is refused outside a
54managed tier, so loading it with `--plugin-dir` seats a plugin that can
55only pass.