Beyond the exam · reinforces TS 1.2 · 2.4 · 3.1 · 3.6 · 5.5 · ~6 hrs · Skip to quiz →
.claudeThe through line for the whole module: a five consultant team at a regional health plan shares one repository, and inside it one .claude folder. On a Tuesday in March that folder holds one person's permission rules, another person's hooks, a CLAUDE.md three people have edited, and an MCP server entry nobody remembers adding. Every question in this chapter is a version of the same question: who is allowed to change what in that folder, what actually stops them, and who finds out when it changes. The first three sections answer it for a team. The next three answer it for an enterprise. The last two answer it for the people who have to live with the answer.
A PreToolUse hook exits with code 2. What happens to the tool call it was checking?
Blocked. Exit code 2 from a PreToolUse hook stops the call and hands Claude the reason. Hold onto that: this module puts the same mechanism on settings changes, so a team can log or refuse an edit to the rules while a session is running.
A project's .mcp.json lists a server. A teammate clones the repo and opens Claude Code. What happens?
A trust prompt, then approval. A project-scoped server is shared on purpose, and the prompt exists because the server is a program that will run on the teammate's machine. This module is about what that means with five people committing to the same folder.
▶ Watch: five people, one folder · 4 min
Two consultants run Claude Code in the same repository on the same afternoon. One adds a rule to .claude/settings.json allowing git push without a prompt and commits it. The other pulls the commit the next morning. Whose rule is in force on the second machine now?
The first consultant's. .claude/settings.json is the shared project file; it is checked into source control on purpose, and everyone who pulls it gets its rules. A rule meant for one person belongs in .claude/settings.local.json, which Claude Code adds to your global git excludes file so it never travels.
First, the words. A repository (repo) is the folder a team shares through source control, usually git, so every change to it has an author and a date. Inside it, the .claude folder holds everything that shapes how Claude Code behaves in that repo: instruction files, permission rules, hooks, agent definitions, skills. With one person, that folder is a private workspace. With five, it is a shared configuration that five people can change and everyone inherits.
Three things break, and each one has a specific mechanism behind it.
Claude Code keeps two settings files in the project's .claude folder, and the difference between them is the difference between a personal preference and a team policy:
| File | Who it is for | Travels through git? |
|---|---|---|
.claude/settings.json | Everyone in the project | Yes, checked in on purpose |
.claude/settings.local.json | You, this project only | No, added to your global git excludes file automatically (a per-user git setting, so the repo's own .gitignore never changes) |
A consultant who wants Claude to stop asking before running the test suite, and puts Bash(npm test *) in the shared file, has made a team decision without a meeting. A consultant who puts a secret-path deny rule in the local file, meaning it to protect the team, has protected one laptop. The rule for the shared file, in a sentence a teammate can repeat: anything in settings.json is a policy statement, and it gets a commit message that says so.
Anthropic's own team describes the upside of getting this right. Cat Wu, on the Claude Code team, in a recorded conversation: "having settings JSON that you check into the codebase is really important because you can use this to pre-allow certain commands so you don't get permission prompted every time and also to block certain commands... I can check this in and share it with the whole team so everyone gets to use." (Flagged as field experience: "The Secrets of Claude Code From the Engineers Who Built It," 2026.) Write one allow rule for the build command once and five people stop being interrupted. Write one deny rule for git push once and five people stop being able to push by accident.
The second break is quieter. The team's CLAUDE.md says "never read files in the secrets folder." Two months later a consultant notices Claude reading one. Nobody edited the line. The instruction was always advice.
The documentation states the distinction in one sentence: "Permission rules are enforced by Claude Code, not by the model. Instructions in your prompt or CLAUDE.md shape what Claude tries to do, but they don't change what Claude Code allows." So a team .claude has two layers that look alike and behave differently:
| Layer | File | What it does | What enforces it |
|---|---|---|---|
| Instructions | CLAUDE.md | Tells the model what the team wants: architecture, conventions, how to phrase a commit | The model, as best it can, each turn |
| Rules | .claude/settings.json | Says what Claude Code will allow, ask about, or refuse | Claude Code itself, before any tool runs |
Drift is what happens when a team writes a policy into the instruction layer and expects it to hold like a rule. The fix is mechanical: every "never" in CLAUDE.md that matters gets a matching deny rule in settings. The sentence stays, because it tells the model why. The rule is what stops the action.
The third break is the one most teams find last. When you open a repository in Claude Code for the first time, it asks whether you trust the folder, and the reason is that a project's .claude/settings.json can contain hooks (scripts Claude Code runs at fixed moments, like before a tool call) and its .mcp.json can list MCP servers (external programs Claude can call as tools). Pull a teammate's commit and you have pulled their hooks and their servers. In a shared repo, that is the point. In a repo where anyone can commit, it is an attack surface.
The security docs are plain about the limit: Anthropic "does not security-audit or manage any MCP server," and the team is told to write its own or use ones from providers it trusts. Note one more thing for anyone running Claude Code from a script: with the -p flag (non-interactive mode, used in automation), "trust verification is disabled," so a scripted run in a folder executes that folder's hooks and connects its servers without asking.
The practical consequence for a five person team: .claude/settings.json and .mcp.json get reviewed like code, because they are code that runs on every teammate's laptop.
Two consultants running Claude Code in the same checked-out folder at the same time will overwrite each other's edits, because both sessions write to the same files. The documented answer is a git worktree: a second checkout of the same repository in a separate folder, sharing history, so two sessions never touch the same file by accident. Boris Cherny, who created Claude Code, describes power users at Anthropic doing exactly this: "a bunch of checkouts of the same repo... or they're using git work trees to have some kind of isolation." (Flagged as field experience: "Mastering Claude Code in 30 minutes," Anthropic, 2026.) The prompt is one line: "start this work in its own worktree."
What this changes from your chair: the first week a client team shares a repo, the questions that arrive are "why did your rule change my setup," "why did Claude ignore the rule in CLAUDE.md," and "what is this hook." All three have the same shape, and the opening walkthrough linked at the top of this section shows the folder, the two settings files, and the trust prompt in order.
A teammate wants Claude to stop asking before it runs the build. Where does the allow rule go?
The shared file. The build command is the same for everyone, so pre-allowing it once removes the interruption for five people; the commit message is what makes it a reviewed team decision. The CLAUDE.md sentence would shape what Claude tries and would still prompt, because instructions do not change what Claude Code allows.
An organization deploys a policy that denies reading .env files. A developer adds Read(./.env) to the allow list in their personal settings. Which wins?
The organization's deny. Managed settings sit above every other level, and within any level a deny rule is checked before an allow rule. The developer's allow never gets a turn.
Claude Code reads settings from five places and resolves conflicts in a fixed order. The order is the governance model. Read it top to bottom as "who can overrule whom":
| Rank | Level | Where it lives | Who owns it |
|---|---|---|---|
| 1 | Managed settings | managed-settings.json at a system path, an MDM profile, or the claude.ai admin console | The organization |
| 2 | Command line | claude --settings <file or json> | You, this session |
| 3 | Project local | .claude/settings.local.json | You, this project |
| 4 | Shared project | .claude/settings.json | Everyone in the project |
| 5 | User | ~/.claude/settings.json | You, every project |
A key set higher overrides the same key set lower, with two refinements that matter for governance. First, list-shaped keys merge instead of replacing: permissions.allow and permissions.deny collect entries from every level, "so developers can extend managed lists but not remove from them." Second, a few keys take the managed value whole, with lower entries ignored: availableModels, fallbackModel, and modelPicker. For a handful of security keys, a stricter value from a lower level still counts even against managed settings; the settings page lists them under "Exceptions to managed settings precedence."
Managed settings are the organization's policy. The documentation's own description: Claude Code "applies them above every other level, so no user, project, local, or --settings value overrides them." The file has the same shape as settings.json. What changes is where it sits and who can write there:
| Platform | Path |
|---|---|
| macOS | /Library/Application Support/ClaudeCode/managed-settings.json |
| Linux and WSL | /etc/claude-code/managed-settings.json |
| Windows | C:\Program Files\ClaudeCode\managed-settings.json |
Those paths need administrator rights to write, and that is the enforcement. A developer cannot edit a file they cannot write to. An organization can also deliver the same keys through a device management profile (a macOS plist or a Windows registry policy) or, on a Teams or Enterprise plan, from the claude.ai admin console, which Claude Code fetches at startup and refreshes hourly. When more than one of those sources is present, the console wins, then the device profile, then the file. By default only the highest source that carries a policy applies; since version 2.1.242 an administrator can set managedSourcesBehavior to "merge" so every source contributes, with lists unioned and lock-type keys taking the strictest value.
A minimal policy, straight from the documentation's example, blocks two secret paths and removes the mode that skips every prompt:
{
"permissions": {
"deny": ["Read(./.env)", "Read(./secrets/**)"],
"disableBypassPermissionsMode": "disable"
},
"allowManagedPermissionRulesOnly": true
}
The last key is the strong form. With allowManagedPermissionRulesOnly set, a developer's own allow rules stop applying entirely: only the managed rules count. To confirm it landed, a developer runs /status inside Claude Code and reads the Setting sources line, which shows Enterprise managed settings with the winning source in parentheses.
Settings are the rules layer. CLAUDE.md is the instruction layer, and it stacks the same way, with one difference: every level loads and the contents add up, since an instruction file has nothing to override. Four levels, from the widest reach to the narrowest:
| Level | Where it lives | Reach |
|---|---|---|
| Organization | The managed path: /Library/Application Support/ClaudeCode/CLAUDE.md on macOS, /etc/claude-code/CLAUDE.md on Linux, C:\Program Files\ClaudeCode\CLAUDE.md on Windows | Every session on the machine, and it cannot be excluded |
| User | ~/.claude/CLAUDE.md | Every project you open; never shared through git |
| Project | CLAUDE.md at the repository root | Everyone who clones the repo; checked in on purpose |
| Directory | A CLAUDE.md inside a subfolder | Loaded when Claude reads a file in that folder |
The governance reading of the table: a company standard ("dates as YYYY-MM-DD; member names stay out of commit messages") belongs at the organization level, where a developer cannot leave it out. A project's architecture and build commands belong at the project root. A personal preference for how Claude phrases things belongs in the user file. And a folder with its own conventions (the billing module, the test suite) gets a directory file that only loads when work happens there. A team that puts a company standard in one repo's CLAUDE.md has protected one repo.
The precedence order tells you what wins. It does not tell you what belongs where. This table is the working answer, and the closing demo builds a governance document around it:
| Layer | Owns | Example |
|---|---|---|
| Managed | Things that must hold on every machine regardless of what anyone types | Secret-path denies, bypass mode lock, sandbox on, minimum version, allowed MCP servers |
| Shared project | Things every teammate on this repo should get, reviewed like code | Build and test commands pre-allowed, git push denied, the project's hooks, the project's .mcp.json |
| Project local | One person's convenience in one repo | A sandbox mode picked from the /sandbox panel, an extra allowed directory |
| User | One person's habits everywhere | Preferred model, editor, a personal deny for a folder outside any project |
Two keys deserve their own line because they change what a whole organization can do at once. permissions.defaultMode sets which permission mode sessions start in (the mode decides how much Claude does without asking). permissions.disableAutoMode set to "disable" removes auto mode entirely, so nobody can select it. The modes, in the order most organizations will meet them:
| Mode | What runs without asking | Where it fits |
|---|---|---|
default (labeled Manual) | Reads only; everything else prompts | Sensitive work, and the starting mode on Enterprise plans and Console API keys |
acceptEdits | Reads, file edits, common filesystem commands | Iterating on code you are reviewing |
plan | Reads and exploration, no edits | Understanding before changing |
auto | Everything, with a separate classifier model reviewing each action | Long tasks; the starting mode on Pro, Max, and Team plans |
dontAsk | Only tools pre-approved by rule; everything else is denied | Locked-down scripts and CI |
bypassPermissions | Everything, no prompts, including writes to .git and .claude | Isolated containers or VMs only |
The row to hold onto is auto. On Pro, Max, and Team plans, sessions now start there by default, which means the approval step a governance document assumes ("a person approves each command") is being done by a classifier unless the organization says otherwise. An Enterprise plan starts in Manual. A governance document that does not name the starting mode is describing a machine it has not looked at.
When a client asks "can our developers turn this off," the answer is a rank number. Managed is rank one, and the only way around it is administrator access to the machine. Everything below it is advice with a file extension.
A client on a Team plan says "a person approves every command, so we are covered." What do you check first?
The starting mode. On Pro, Max, and Team plans the built-in starting mode is auto, so the approving is done by a classifier unless the organization sets permissions.defaultMode or disables auto mode in managed settings. A governance document that does not name the starting mode is describing a machine nobody has looked at.
A team denies the WebFetch tool for every domain except the company wiki. Claude runs curl from the shell and downloads a page from anywhere. What went wrong?
Nothing in the rule. WebFetch is one tool; curl is a shell command under the Bash tool. The documentation says it directly: "if Bash is allowed, curl and wget can still reach any URL." Closing the gap takes the sandbox (an operating system boundary around every shell command Claude runs) and its list of allowed domains.
A permission rule names a tool and, optionally, what the tool is allowed to touch. Rules live in permissions.allow, permissions.ask, and permissions.deny, and they are checked in that order reversed: "deny, then ask, then allow. The first match in that order determines the outcome." The syntax that carries most of a team's policy:
| Rule | Meaning |
|---|---|
Read(./.env) | Deny or allow reading the .env file in the project |
Read(./secrets/**) | Every file under secrets, at any depth |
Edit(docs/**) | File edits under docs |
Bash(git push *) | Any shell command starting with git push (the space before * matters) |
WebFetch(domain:example.com) | Fetches to one domain |
mcp__* | Every MCP tool from every server (deny only) |
Agent(isolation:worktree) | Subagent calls that request a worktree |
One trap in that table: file rules are checked against Read and Edit only. A rule written for Write or Glob is accepted and never consulted, and Claude Code warns at startup. Write Edit(docs/**) where you meant Write(docs/**).
Deny rules on secret paths. The two-line example in the managed policy above is the baseline: .env and the secrets folder. Anything Claude cannot read cannot leak into a transcript, a summary, or a log.
The bypass lock. bypassPermissions mode skips every prompt, including writes to .git and .claude. The documentation's guidance: "Only use this mode in isolated environments like containers or VMs where Claude Code can't cause damage." Setting permissions.disableBypassPermissionsMode to "disable" in managed settings removes the mode from every machine.
The next part is about the people who use the tool. In a recorded conversation between two Anthropic staff, one says of permission prompts: "I get around that by just using dangerous[ly] skip permissions." The other, from the Claude Code team, answers: "we kind of have this here but we don't, you know, we don't recommend it. It's like, you know, it can do weird stuff." (Flagged as field experience: "The Secrets of Claude Code," 2026.) The people who build the tool reach for the escape hatch on their own machines. The organization's written guidance says to close it. That gap is the whole argument for the managed tier: a policy that depends on each developer's discipline is a policy that a Thursday deadline will override. The lock costs one line.
The sandbox. Permission rules run inside Claude Code and decide what Claude attempts. The sandbox is different: it wraps the Bash tool so that "the operating system enforces that boundary for every Bash command and its child processes." On macOS it uses the built-in Seatbelt framework; on Linux, bubblewrap. It has a filesystem side (denyRead, denyWrite, allowRead) and a network side (sandbox.network.allowedDomains). This is what closes the curl gap from the section opener. Two managed keys turn it from a convenience into a gate: sandbox.enabled set to true, and sandbox.failIfUnavailable set to true, which the documentation describes as "intended for managed deployments that require sandboxing as a security gate." Without the second key, a machine that cannot start the sandbox warns and runs unsandboxed. sandbox.network.allowManagedDomainsOnly stops a developer widening the domain list.
The audit hook. A hook is a script Claude Code runs at a fixed moment. The ConfigChange hook fires "when a configuration file changes during a session," with a matcher for which source changed (user_settings, project_settings, local_settings, policy_settings). Exit code 2 from the hook "blocks the configuration change from taking effect," except for policy settings, which a hook cannot veto. So a team can log every settings edit to a file, or refuse one that adds an allow rule mid-session. The security page lists this as a team practice: "Audit or block settings changes during sessions with ConfigChange hooks."
Where the login lives: on macOS, Claude Code stores API keys and tokens in the Keychain; on Windows and Linux, in files protected by file permissions. Two managed keys govern how people log in at all: forceLoginMethod restricts sessions to one method, and forceLoginOrgUUID pins them to one Anthropic organization, so a developer cannot quietly run the company's code through a personal account. When either is set, a session authenticated by a raw ANTHROPIC_API_KEY in the environment "is blocked at startup."
For automation (TS 3.6): a scripted run uses claude -p "<prompt>", and the documentation now recommends --bare for CI, which skips loading hooks, skills, MCP servers, memory, and CLAUDE.md so "you need the same result on every machine." Bare mode never reads the keychain; the pipeline supplies ANTHROPIC_API_KEY from its own secret store, scoped to that job, and pre-approves only the tools the job needs with --allowedTools. For a locked-down run, --permission-mode dontAsk denies anything not on the list. The governance consequence: a CI key is a separate credential with a separate lifetime, and the job's allow list is the policy for that key.
Flagged as field experience, and a distinction the reader must keep. A July 2026 academic evaluation of five commercial agent products (arXiv 2607.13718) found that under the consumer Claude app's "Needs approval" setting, the assistant sometimes approved an action itself, tagging its own request approvalRequired: false. The authors disclosed it to Anthropic on July 2, 2026. That finding describes the chat product's connector integrations. It was not a test of Claude Code's rule engine, which the documentation describes as enforced by Claude Code rather than the model. Keep the two apart, and take the general lesson: a label in a settings screen and an enforced boundary can drift, so verify with /status and claude doctor rather than trusting the label.
Flagged as field experience. Boris Cherny, asked why Claude Code searches a codebase with grep instead of a vector index: "as we thought about what does it feel like for an external enterprise to adopt it, we realized that this exposes a lot more surface area and like security risk," specifically "how exactly is the index permissions... how do we make sure that if there's a rogue IT person within the company they can't access someone else's data." (The Pragmatic Engineer podcast, 2026.) The lesson generalizes past search: every persistent artifact a tool creates (an index, a cache, a transcript export) is a second copy of the data with its own access question, and a design that creates none has one fewer thing to govern.
The client's security team will ask four questions, and this section is the answer sheet. What can it read? (Deny rules.) What can it run? (Modes and the bypass lock.) What can it reach? (The sandbox.) Who changed the rules? (The ConfigChange hook and git history.) Each has a one-line answer and a file it lives in.
The client's security lead asks: "who changed the permission rules last Tuesday?" What answers that?
The hook and the git log. The ConfigChange hook fires when a settings file changes during a session and can log which source changed and who was logged in; the shared file's commits carry the rest. The dashboard shows adoption and spend, and a session has no memory of last Tuesday.
A consultant writes a nine line markdown file in .claude/agents/ describing a "release notes" subagent that reads merged pull requests and drafts a summary. The client's IT governance board asks whether it needs to be registered as an AI system. Does it?
Ask four questions about what it can do, and ignore what it is made of. A subagent that only reads and drafts for a person to review is configuration. The same file with standing write access to a production system, or that sends external messages with nobody in the loop, is a system, and gets a system's governance.
The words first. A subagent is a separate Claude instance that the main session (the coordinator) hands a task to; it works in its own context window and returns a result. In Claude Code a subagent is defined by a markdown file with a small frontmatter block (name, description, allowed tools, model) and a body of instructions. That file is the whole "deployment." There is no server, no container, no registration step. So when an enterprise asks "which of these are AI systems we need to inventory," the honest first answer is that the file format cannot tell you.
The line between "govern as code" (review the file in a pull request, like any other config) and "register as a system" (inventory it, assign an owner, monitor it, attach it to the compliance process) flips on what the agent can do without a person:
| Question | If yes | Example |
|---|---|---|
| Does it hold standing permissions beyond reading? | Toward system | An agent whose definition pre-allows Bash(psql *) against a live database |
| Does it run without a person starting it? | Toward system | A scheduled job that runs claude -p with the agent nightly |
| Does it produce external effects? | Toward system | It sends email, opens tickets, posts to a channel, calls a vendor API |
| Does anyone need to reconstruct what it did afterward? | Toward system | Its output feeds a regulated decision |
Four no's: it is a file, and it gets code review. One yes: it gets an owner, a log, and a line in the inventory. Two or more: it is a system with a markdown front end, and the client's existing controls for automated systems apply.
This is the framework Gartner is now recommending from the other direction. Its May 2026 analysis argues that "applying uniform governance across all agents regardless of autonomy and scope will itself cause enterprise agent failure," and predicts 40 percent of enterprises will demote or decommission autonomous agents by 2027 after governance gaps surface in production. (Flagged as analyst forecast: Gartner, press release, 2026-05-26.) A governance maturity paper on arXiv (Acharya, 2604.16338, April 2026) draws the same line with the same tests: persistent decision authority, multiple business processes, independent monitoring, material compliance exposure. (Flagged as field experience: a structured position paper, no sample.)
Claude Code's documentation now carries limits that answer the same question from inside the product. By default, 20 subagents can run at once in a session, and "spawning another with the Agent tool fails with Concurrent subagent limit reached." A subagent can spawn its own subagents "up to three layers below the main conversation." Both are adjustable through environment variables (CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS, CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH), setting the depth to 1 turns nesting off, and the limits need Claude Code v2.1.217 or later.
A subagent also inherits the permission posture of its parent: "If the parent uses bypassPermissions or acceptEdits, this takes precedence and can't be overridden." So a coordinator running in bypass mode has, in effect, registered every worker it spawns into the same trust level. The governance consequence: the coordinator's mode is the agent's mode, and a review of one subagent file is incomplete without the mode of the session that will run it.
A second coordinator pattern is now in the documentation and marked experimental: agent teams, where several full Claude Code sessions share a task list and message each other directly, instead of subagents reporting back to one coordinator. It is off unless CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS is set to 1, it does not run under -p, and two rules in its permission section belong in any governance document that mentions it: "Teammates start with the lead's permission settings," and "A teammate can't approve a permission prompt or supply consent on your behalf." The feature is worth watching. The rules are worth adopting now for any multi-agent pattern: the coordinator's trust level is the ceiling, and an agent's claim that something was approved is untrusted input.
One measured data point for the stakes. METR's frontier risk pilot with four labs, covering February and March 2026, found internal agents "often worked autonomously on real research and engineering projects with permissions and oversight comparable to human employees," and the labs were "not aware of any company imposing strict requirements about human oversight of agents." (Flagged as field experience: METR, Frontier Risk Report, 2026-05-19, self-reported by participants.) The organizations closest to the technology are running agents at employee-level trust. A client's governance board will ask whether that is the plan. The four questions are the answer.
You will be asked to draw this line for a client, and "it is just a markdown file" is the wrong answer in both directions. The four questions give you a defensible one, and the closing demo writes them into the governance document.
A compliance reviewer asks what Claude did last Tuesday between 2pm and 3pm on one developer's machine: which prompts, which tools, which files. The team has the claude.ai analytics dashboard. Can they answer?
Not from the dashboard, which shows adoption and spend. Answering "what did it do and why" takes OpenTelemetry export to infrastructure the organization runs, where every event carries a prompt.id that ties a prompt to the API calls and tool calls it caused.
Three surfaces, three questions they can answer:
| Surface | Answers | Where |
|---|---|---|
| Analytics dashboard | Who is using it, how much, what it costs | claude.ai/analytics on Teams and Enterprise; platform.claude.com on Console |
| Analytics API | The same numbers, per user, pulled programmatically | Enterprise Analytics API, Claude Code Analytics API |
| OpenTelemetry export | What happened inside a session: prompts, API calls, tool decisions, results, in order | Your own collector: Datadog, Splunk, a SIEM, anything that speaks OTLP |
OpenTelemetry (OTel) is an open standard for sending metrics and event logs from a program to a collector you control. Claude Code speaks it natively. The configuration is five environment variables, and the documentation's guidance is to deliver them through the env block of managed settings so no developer has to remember, and none can quietly change the endpoint:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317"
}
}
When an OTEL_EXPORTER_OTLP_* variable is set in managed settings, "Claude Code removes conflicting developer-set variables at startup and logs a warning." The endpoint is the organization's, by rank.
Every session emits metrics (session count, lines of code changed, commits, pull requests, cost in dollars, tokens, active time) and events. The events are the audit trail:
| Event | When | What it carries |
|---|---|---|
claude_code.user_prompt | A person submits a prompt | prompt.id, session.id, user.id, prompt length; the text itself is redacted unless enabled |
claude_code.api_request | Each call to the model | Model, cost, input and output tokens, prompt.id |
claude_code.tool_decision | A permission decision is made | Tool name, accept or reject, and the source of the decision |
claude_code.tool_result | A tool finishes | Tool name, success, duration, prompt.id |
claude_code.api_error | A model call fails | Status code, attempt number |
claude_code.mcp_server_connection | An MCP server connects or fails to | Server status |
The key that makes it reviewable is prompt.id: "When a user submits a prompt, Claude Code may make multiple API calls and run several tools. The prompt.id attribute lets you tie all of those events back to the single prompt that triggered them." That is the Tuesday-afternoon answer: filter to one prompt.id, read the prompt, the calls, the decisions, and the results in order.
Content is redacted by default and turned on deliberately, one category at a time: OTEL_LOG_USER_PROMPTS=1 for prompt text, OTEL_LOG_ASSISTANT_RESPONSES=1 for responses, OTEL_LOG_TOOL_DETAILS=1 for tool arguments. The default is the right starting point for a health plan: the trail shows that a file was read and a command was run, without copying patient data into the log system.
Human review at scale, the subject of TS 5.5, needs a sample to review. The tool_decision event is that sample. A team that exports it can answer, weekly: how many actions were auto-approved versus prompted, which tools got rejected and by whom, and whether the auto mode classifier is approving things a person would have stopped.
Boris Cherny describes the practice Anthropic uses on its own code review: several parallel review agents, then "deduping agents" whose only job is to strip false positives, and when a review catches something a linter could catch, "ask Claude to write the lint rule for it inside that PR," so the next occurrence is caught by a deterministic tool instead of a model's judgment. (Flagged as field experience: The Pragmatic Engineer podcast, 2026.) The telemetry tells you which findings are recurring; the lint rule retires them from the review queue.
Two more things an enterprise can see. On the deployment side, a self-hosted Claude apps gateway (a service the organization runs between developers and the model provider) "records a per-request audit log with IdP identity," which is the request-level record a compliance program usually asks for. And spend: Teams and Enterprise admins set spend and rate limits in admin settings; on a cloud provider, the cloud's own budget tools apply.
"Can we audit it" is the question that decides whether a rollout gets approved. The answer is yes, with one JSON block in managed settings and a collector the client already has, and the answer to "what does the log contain" is the events table.
A privacy officer at a health plan asks whether turning on telemetry sends patient data to the log system. What is the accurate answer?
Redacted by default. The events carry lengths, identifiers, tool names, and decisions; the content fields stay empty until someone sets OTEL_LOG_USER_PROMPTS, OTEL_LOG_ASSISTANT_RESPONSES, or OTEL_LOG_TOOL_DETAILS. The default is the right starting point for a regulated client: the trail shows that a file was read and a command was run, without copying the file into the log.
A health plan already runs its data platform on AWS with CloudTrail auditing and IAM policies reviewed quarterly. It wants Claude Code for forty developers. Which deployment path should the consultant recommend first?
Start from what the client's compliance program already trusts. Claude for Enterprise is the documentation's default recommendation (one subscription, SSO, admin console, no infrastructure). Amazon Bedrock lets the client inherit the IAM and CloudTrail controls it already audits. The choice is a compliance decision before it is a technical one, and the two can coexist.
Where the model runs decides billing, login, and which compliance posture the organization inherits. The documentation's comparison, condensed:
| Path | Best for | Login | Enterprise controls you inherit |
|---|---|---|---|
| Claude for Teams / Enterprise | Most organizations (recommended) | Claude.ai SSO or email | Team management, SSO, usage monitoring, managed policy from the admin console (Enterprise) |
| Anthropic Console | Individual developers, API-first teams | API key | None |
| Amazon Bedrock | AWS-native shops | API key or AWS credentials | IAM policies, CloudTrail |
| Claude Platform on AWS | AWS Marketplace billing with full API features | API key or AWS credentials | IAM policies, CloudTrail |
| Google Cloud's Agent Platform (formerly Vertex AI) | GCP-native shops | GCP credentials | IAM roles, Cloud Audit Logs |
| Microsoft Foundry | Azure-native shops | API key or Microsoft Entra ID | RBAC policies, Azure Monitor |
Two facts change the recommendation in practice. First, some features need a claude.ai account and are unavailable on a Console key or cloud credentials alone: Claude Code on the web, Routines, Code Review, Remote Control, and the Chrome extension. A cloud deployment may still need Enterprise seats for those. Second, on any cloud path, pin the model version: ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL, and their siblings. Without pinning, "model aliases resolve to Claude Code's built-in default for that provider, which can lag the newest release and may not yet be enabled in your account." Pinning "lets you control when your users move to a new model." A model change is a change to the system, and an enterprise wants to schedule it.
SSO (single sign-on: your company login opens Claude), SCIM (automatic provisioning and removal of accounts from the company directory), and seat assignment are configured at the Claude account level, in the Enterprise admin console, and documented in the Claude Enterprise Administrator Guide rather than in the Claude Code docs. On the Claude Code side, two managed keys make sure the login used is the company's: forceLoginMethod restricts sessions to one login method, and forceLoginOrgUUID pins them to one Anthropic organization. When a developer leaves, SCIM removes the seat, and a session that tries to authenticate with a leftover personal key is blocked at startup by the org pin.
"On Team, Enterprise, Claude API, and cloud provider plans, Anthropic doesn't train models on your code or prompts. Your API provider determines retention and compliance posture." Zero Data Retention (nothing stored after the request completes) "is available to qualified accounts on Claude for Enterprise." For a health plan, the third line is the one the privacy officer asks about: a Business Associate Agreement and HIPAA-ready configuration are Enterprise-tier conversations with Anthropic, or inherited from the cloud provider's existing agreement on a Bedrock or Foundry path. (Flagged as field experience: no official Claude Code page states HIPAA terms; the general Claude Enterprise compliance material and the cloud providers' own agreements cover it.)
The honest limits, from the documentation. Organization-wide model restrictions, default model, and effort limits are enforced server-side for claude.ai and API users, and "none of these controls reach sessions on Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or Claude Platform on AWS"; on those paths the availableModels managed key does the job instead. So a mixed deployment (some seats on Enterprise, some on Bedrock) needs the file-based or device-profile policy as a fallback, because the console only reaches the seats that log in through claude.ai.
The client's first question is "cloud or direct," and the right answer starts with "what does your compliance program already audit." The table gives the options; the pinning rule and the feature list keep the recommendation from surprising anyone in month two.
A client deploys through Amazon Bedrock. Six weeks in, a developer says Claude "got worse overnight." What is the first thing you check?
Pinning. On any cloud path, ANTHROPIC_DEFAULT_OPUS_MODEL and its siblings fix the exact model version, and without them the alias can move when Claude Code updates its default. The docs' phrasing: pinning lets you control when your users move to a new model. A model change is a change to the system, and an enterprise wants to schedule it.
A client wants to be "AI-first" by the end of the quarter. The CIO's plan is to give every developer Claude Code on Monday with the default settings and see what happens. What is the first thing you say?
That the default settings differ by plan, and on a Team plan the default means a classifier approves most actions instead of a person. Then propose the sequence: a managed baseline first, a pilot team second, champions third, the fleet fourth. Governance before scale, because the alternative is governance after an incident.
The numbers first, because a rollout plan is an argument and the argument needs them. Deloitte's April 2026 survey of 3,235 leaders across 24 countries found 21 percent of organizations have a mature governance model for agentic AI, while 74 percent expect at least moderate agent usage by 2027. (Flagged as field experience: Deloitte, 2026-04-24, survey with stated method.) Gartner predicts 40 percent of enterprises will demote or decommission autonomous agents by 2027 because the governance gaps showed up only after a production incident. (Flagged as analyst forecast: Gartner, 2026-05-26.) Between those two figures is the gap a consultant is hired to close.
Anthropic's own rollout guidance is short, and it matches the managed baseline and the reviewed shared settings file described above: invest in CLAUDE.md files at the organization level (a system path, /Library/Application Support/ClaudeCode/CLAUDE.md on macOS, loads in every session) and the repository level; make installation "one click" because that is "key to growing adoption"; and "start with guided usage," meaning codebase questions and small fixes first, with a plan reviewed before code runs, "as users understand this new paradigm better, then they'll be more effective at letting Claude Code run more agentically."
Put into an order a client can put on a slide:
| Phase | What ships | What it proves |
|---|---|---|
| 1. Baseline | Managed settings: secret-path denies, bypass lock, sandbox on, allowed MCP servers, telemetry endpoint, minimum version | The floor exists before anyone stands on it |
| 2. Pilot | One team, one repo, a shared settings.json and CLAUDE.md reviewed like code, worktrees for parallel work | The team-level rules (shared file reviewed like code, personal file ignored by git, one worktree per parallel session) work in practice |
| 3. Champions | The pilot's two most fluent people write the prompt patterns and the "what to ask for" guide; office hours weekly | Adoption spreads by example, and the guide is written by people who used it |
| 4. Fleet | Everyone, with the baseline unchanged and the pilot's repo config as the template | Scale changes nothing about the floor |
| Ongoing | Weekly tool_decision review, monthly policy review, a named owner per registered agent | Governance happens on a calendar, with names attached |
The opposite failure costs as much. A governance board that treats every nine line subagent as a system to be registered, reviewed, and monitored will produce a team that stops writing subagents, or writes them and stops telling anyone. Gartner's phrasing is that uniform governance across agents of different autonomy "will itself cause enterprise agent failure." The four questions (standing permissions, runs without a person, external effects, needs a reconstructable trail) are the fix: a fast path for configuration, a full path for systems, and a rule for telling them apart that a developer can apply in a minute without a meeting.
Boris Cherny's word for what happens when the shared layer is done well is "network effect": "have a batch command that you would run for all your employees... you can actually just check it into this enterprise policies file and then any employee when they run this command, it will be auto approved." (Flagged as field experience: "Mastering Claude Code in 30 minutes," Anthropic, 2026.) One person's afternoon writing the allow list is every developer's removed interruption. The same file that blocks git push is the file that pre-approves the test suite. A developer who stops getting interrupted by the test command, and gets stopped once from force-pushing over a colleague, keeps both rules. A developer who only ever sees denials starts asking Claude to work around the settings file instead of through it.
This section is the deck. The numbers open it, the sequence is the plan, the four questions are how the client avoids both failure modes, and the closing demo produces the document the plan refers to.
A client's CIO says: "Let's just turn it on for everyone Monday and add governance once we see how people use it." Answer in two or three sentences, out loud or in the box, then compare.
Something like: "The defaults differ by plan, and on a Team plan the default means a classifier approves most actions instead of a person, so 'see how people use it' starts with nobody watching. A managed baseline takes an afternoon: secret-path denies, the bypass lock, the sandbox, and a telemetry endpoint. Ship that first, pilot one team, then widen. Gartner's forecast is that 40 percent of enterprises pull agents back by 2027 because the gaps showed up after an incident; the baseline is how you avoid being the incident." The idea to keep: the floor exists before anyone stands on it.
The five consultant team at the regional health plan had been working in one shared repository for six weeks: a modernization assessment, with Claude Code doing most of the code reading and drafting. The .claude folder had grown the way a shared drive grows. Nobody owned it.
The Friday it broke. One consultant, tired of approving the test command, added Bash(npm test *) to .claude/settings.json and, while there, added Bash(git push *) so an end-of-day push would not need a prompt either. Commit message: "settings." Monday morning a second consultant pulled it, asked Claude to "clean up the branch and push," and Claude force-pushed over a colleague's unmerged work. The push was allowed by rule. Nobody had been asked.
The same week, the quieter one. The team's CLAUDE.md had said for a month: "Never read the files in the config/secrets folder." A third consultant asked Claude to "figure out why the staging connection fails," and Claude, doing exactly what was asked, read config/secrets/staging.env to check the connection string. The credential went into the transcript. The instruction had been advice, and the model had weighed it against a direct request and chosen the request.
The fix took one afternoon, and nobody touched the codebase. The team changed three things: which file each kind of rule lived in, what enforced the rules that mattered, and who found out when the rules changed.
Which file. The shared settings.json was rewritten with a comment block at the top and a review requirement in the pull request template. Personal conveniences moved to each person's settings.local.json, which git ignores on that machine. The git push allow came out.
| Rule | Before | After |
|---|---|---|
Bash(npm test *) | Shared file, uncommented | Shared file, under "Team allows: build and test only" |
Bash(git push *) | Shared file, allowed | Shared file, denied; pushes prompt every time |
Read(./config/secrets/**) | A sentence in CLAUDE.md | Shared file, denied, and the CLAUDE.md sentence kept as the reason |
What enforced it. The health plan's IT group deployed a managed policy file to every consultant laptop, the same three lines the documentation uses as its example, plus the sandbox: deny .env and the secrets folder, disable bypass mode, sandbox on with failIfUnavailable. Each consultant ran /status and read the Setting sources line back to the team lead. Four said Enterprise managed settings (file). One said nothing, and that laptop turned out to have the file at the wrong path.
Who found out. A ConfigChange hook in the shared settings appends one line to governance/settings-log.md every time a settings file changes during a session: timestamp, which source, who. The log is committed with the work.
Replay Monday morning through both worlds.
| "clean up the branch and push" | |
|---|---|
| Before | Claude runs git push --force, allowed by the shared rule. The colleague's branch is overwritten. Discovered Tuesday. |
| After | Claude runs the cleanup, reaches the push, and stops: "This will push to origin. Approve?" The consultant reads the command, sees --force, and says no. |
And the staging question:
| "figure out why the staging connection fails" | |
|---|---|
| Before | Claude reads config/secrets/staging.env; the credential lands in the transcript. |
| After | Claude tries the read, is refused by the deny rule, and reports: "I can't read the secrets folder. Tell me which variable to check and I'll trace where it's consumed." |
Week eight. A consultant drafts a nine line "ticket triage" subagent: it reads new tickets from the client's tracker through an MCP server, classifies them, and posts the classification back as a comment. It works. The consultant says: "It's a markdown file; I'll commit it with the other agents." Pick your move, then read what follows from it. Try all three.
What the working practice looks like now. The shared settings file is reviewed like code. The managed policy is the floor, and /status is how a new laptop proves it is standing on it. Every "never" in CLAUDE.md has a deny rule next to it. Every settings change has a log line. Every new subagent answers four questions before it is committed, and the ones that answer yes get an owner. The assessment shipped, and the governance document the team wrote for itself became the first deliverable the health plan asked to keep.
▶ Watch the demo: the governance model · 5 min
The prompt pack: every demo prompt, cleaned and explained
The closing demo builds the governance model the case study ends with, on the client-project repo, from the user's chair, in three parts. Sort the folder: split the shared settings from the personal ones, move every "never" in CLAUDE.md into a deny rule, and write the shared file's header so the next person knows what they are editing. Set the floor: write the managed policy file, verify it with /status, add the ConfigChange audit hook, and prove the bypass lock by trying to turn it on. Draw the line: write the four-question check into a governance document, run the ticket triage subagent through it, and watch it fail question three and get registered instead of committed.
Then run the pack in your own repo. The prompt pack linked above holds every prompt from the demo, cleaned up and explained. Copied as is or rephrased in your own words, check what the demo checked as you go:
settings.json carries a header and only team rules; personal conveniences sit in settings.local.json, and git ignores it./status shows Enterprise managed settings on the first line, and a request to start bypass mode is refused by policy.governance/settings-log.md.governance/model.md, comes back as a system with a list of what has to change.WebFetch does not stop curl, and what closes the gapprompt.id lets an auditor doTake the Module 09 quiz → then reread the governance model you wrote with the four questions next to you.