Skip to main content
CID222 Docs

Bring Claude Code under policy

Distribute the CID222 plugin to Claude Code users, route provider traffic through the gateway, and verify that a session is inspected.

  • Version: 0.4
  • Role: admin_user
  • Type: task

Claude Code runs in a terminal, so neither a browser extension nor a reverse proxy in front of your own applications sees it. Two independent layers bring it under policy: a plugin whose hooks inspect prompts and tool output, and a base URL that routes the provider traffic itself through the gateway so a prompt can be masked in path.

What do I need?

Licence
Any
Role
admin_user

Prerequisites

  • Claude Code is installed on the developers' machines and they can already use it.
  • You can push a file to those machines with Intune, Group Policy, Jamf or a configuration-management tool — or you hold the Owner role in a Claude Team or Enterprise organisation.
  • The appliance's API host is reachable from the developers' machines.
  • A tenant group exists for Claude Code users, so the filter profile that governs coding traffic is separate from the chat profile.
  • The passthrough proxy is enabled on the appliance, if you want prompts masked rather than only recorded.

The two layers, and what each can do

LayerMechanismCan it record?Can it block a prompt?Can it mask a prompt?
Plugin hooksRuns inside Claude Code on the developer's machineYesYesNo — the hook protocol allows a refusal, not a rewrite
Base URL routingProvider traffic flows through the gateway's Anthropic passthroughYesYesYes, in path

The plugin also redacts tool output before the model sees it, which the base URL cannot do, because a file the tool read never crosses the network as a prompt. Use both.

Warning

This is client-side control on a cooperative managed device, not a security boundary. A determined user on an unmanaged machine can run a different build of the tool. The residual bypasses and what closes each are listed at the end of this page.

Generate the settings for your appliance

Produce the bundle

In the setup wizard, complete the Connect Claude Code step.

The appliance creates a tenant group named Claude Code if it does not exist, mints an inspection key scoped to that group, and returns the complete managed-settings JSON with its own hostnames already filled in. The key is shown once.

Check the hostnames came out real

Read the JSON before you distribute it.

When the appliance does not know its own external names, the values read https://api.YOUR-DOMAIN and https://proxy.YOUR-DOMAIN. Fix the appliance's hostnames and generate again rather than editing the JSON by hand.

Understand what the settings enforce

The generated JSON does five things:

  1. Registers the plugin marketplace, so the client knows where the plugin comes from.
  2. Force-enables the plugin for every user, re-applied at every start and on the hourly poll.
  3. Restricts which marketplaces a user may add at all.
  4. Rejects the command-line flags that would sideload a different plugin, and refuses to load a user's own hooks alongside the managed ones.
  5. Sets the gateway URL, the inspection key and the provider base URL in the environment Claude Code runs with.

Choose one delivery channel

Managed sources do not merge. If one channel delivers any key at all, the other is ignored entirely. Pick one and put everything in it.

Push the JSON as a root-owned file:

PlatformPath
WindowsC:\Program Files\ClaudeCode\managed-settings.json
macOS/Library/Application Support/ClaudeCode/managed-settings.json
Linux and WSL/etc/claude-code/managed-settings.json

Ready-made scripts render and install the file idempotently, validating the input and refusing to write malformed JSON: a PowerShell script for a Group Policy startup script or an Intune device script, a shell script for a Jamf policy or a single Linux host, and an Ansible playbook for a Linux fleet.

This is the only channel that survives base-URL routing, and the only one that reaches users on personal Claude accounts. Choose it unless you have a reason not to.

Enable in-path masking

Routing alone changes nothing: the passthrough proxy must be told to call the inspection endpoint. On the appliance, set the proxy's inspection URL to the full path including the surface name, its key to a rotated key belonging to the Claude Code group, and turn masking on:

CID_INSPECT_URL=http://nestjs-core:3000/inspect/v1/claude-code
CID_INSPECT_KEY=<rotated cid_key_…>
CID_PASSTHROUGH_MASK=true

Then recreate the proxy service alone and confirm the variables landed. A bare /inspect/v1 returns 404, and the proxy's fail-open posture then skips inspection silently — the single most expensive mistake on this path.

Leave CID_PASSTHROUGH_FAIL_OPEN at its default unless you accept an inspection outage becoming a Claude Code outage.

Set the filter profile

Claude Code is a coding surface. It legitimately reads and writes text that a chat-tuned toxicity or jailbreak model flags, and its payload is source code rather than prose. Configure the profile accordingly, on the tenant group the inspection key resolves to:

  • Log-first. Most rules record only.
  • A small number of secret and credential rules block or redact.
  • Toxicity and jailbreak detection off for this group.

This is expressed as filter overrides on the tenant group — the same mechanism the browser and API surfaces use. No separate configuration path exists or is needed.

Install on one machine for a pilot

For a single developer's laptop, before any fleet work:

curl -fsSL https://<appliance-fqdn>/claude/install.sh | CID_HOST=https://<appliance-fqdn> bash

Then export the inspection key, and the base URL if the appliance runs the passthrough proxy:

export CID_INSPECT_KEY=cid_key_0123…
export ANTHROPIC_BASE_URL=https://proxy.<appliance-domain>

Start a new session. The first one asks for a one-time security approval, because the plugin ships hooks; approve it.

Warning

The gateway host is baked into the plugin, but the inspection key is not — it was removed deliberately, because the marketplace repository is public. Without a key the hooks send no authorization header, the gateway refuses them, and inspection fails open silently. The observable state is identical to the plugin not being installed.

Verify

  1. Start a new session and read the opening lines. CID inspection is active for this Claude Code session confirms the hooks reached the gateway; a line naming HTTP 401, 403 or 404 names the failure instead.
  2. When routing is on, a second line reads Provider traffic is ROUTED through the CID gateway and echoes the base URL in force.
  3. Run /cid:status. It reports both layers separately — whether prompts and tool output are inspected, and whether provider traffic is routed.
  4. Submit a prompt containing test personal data. Open All Detections, set Source to Claude Code, and confirm the row.
  5. Open Claude Code Activity. Sessions appear per developer and per repository, as metadata only — the page stores no prompt or file content. Activity is written as CLAUDE_CODE_ACTIVITY and CLAUDE_CODE_USAGE events.
  6. Confirm the passthrough proxy is actually inspecting: a prompt heavy with personal data should cost measurably more than a clean one of the same size. Before inspection is enabled the difference is a few milliseconds; afterwards it is tens of milliseconds.

If it fails

  • The installer stops with a message that the host is not set — run it with the host prefix exactly as written above.
  • The session reports that the gateway rejected the inspection key — the key is wrong, expired, or was not delivered. Check it in the dashboard and start a new session; the key is read at session start.
  • The session reports a 404 from the inspect endpoint — the gateway URL points at a host that serves no inspection endpoint. This is usually a front proxy that answers only its own health check. Nothing is being inspected in this state.
  • There is no routing line — the base URL is not exported in the shell that started Claude Code. Check it, then start the tool from the same shell.
  • Requests fail with a model error — the proxy is not in passthrough mode. Its health endpoint reports the mode; a translation-mode proxy drops tool calls and breaks Claude Code.
  • The plugin never appears in the command-line tool — the marketplace was not registered. An enabled-plugins entry naming a marketplace the client has never heard of installs nothing, and this is the usual cause.
  • Managed settings appear to be ignored — you are delivering through both channels, or you are on the console channel with a non-default base URL set. Both make the console channel silently skip.

Known gaps

  • Enforcement hooks are POSIX shell. Full coverage on macOS, Linux and the Windows Subsystem for Linux. Native-Windows enforcement is a follow-up; the session-start posture reporting is cross-platform.

  • A prompt cannot be masked by the plugin. The hook protocol allows a refusal, not a rewrite. Masking requires the base-URL path.

  • The plugin marketplace cannot be served over plain static HTTP. Claude Code clones shallowly and static file serving cannot answer a shallow clone. An appliance-served marketplace needs a real git HTTP handler; a marketplace published as a bare JSON file registers but cannot install.

  • The plugin's own heartbeat has no receiver. Each session start posts a small fail-silent heartbeat carrying the tool, the version, the user, the host and whether the session is routed or bypassing. The gateway endpoint that would collect it is not built, so the post 404s and is dropped. Per-developer visibility today comes from the inspection calls the hooks make.

  • Residual bypasses. Every one below is closed by a setting in the generated JSON except the last:

    BypassClosed by
    Sideloading a different plugin from the command lineThe sideload-flag restriction
    Editing the user's own settings fileNothing needed — managed settings outrank user and project settings absolutely
    Exporting a different provider base URLFile delivery only; the console channel is skipped
    Skipping the permission promptsThe bypass-permissions restriction
    A modified build, or installing the tool another wayNothing client-side. This needs device management and egress control

Next steps

  • Claude Code Activity — the dashboard page: who worked on which repository, and which filters fired.
  • Access keys — issuing and revoking the inspection key this page depends on.
  • Endpoint agent — coverage for coding tools other than Claude Code, at the network layer rather than inside the tool.

Last updated on

On this page

Download PDF