GitGuardian (ggshield) secret scanning as a Docker Sandboxes kit
204
Installs the GitGuardian CLI (ggshield) with proxy-injected API-key auth for api.gitguardian.com and wires it in as an AI hook for every coding assistant ggshield supports, so the agent's own actions are scanned for hardcoded secrets automatically - the real key never enters the sandbox.
| Name | Service | Required | Description |
|---|---|---|---|
GITGUARDIAN_API_KEY | gitguardian | Required | GitGuardian API key (from a Personal or Service Account, "scan" scope). Stored on the host; the sandbox only sees a placeholder and the proxy injects the real value on requests to api.gitguardian.com. |
github.com
objects.githubusercontent.com
release-assets.githubusercontent.com
api.gitguardian.com
sbx run <agent> --kit docker.io/gghh1/ggshield-kit:latestRun the following command to install sbx on your machine.
brew install docker/tap/sbxwinget install Docker.sbxA Docker Sandboxes mixin that adds
GitGuardian's
ggshield secret scanner to an AI
coding-agent sandbox, and wires it in as the agent's own AI hook so the
agent's actions are scanned for hardcoded secrets automatically.
Source, issues, and full docs: https://github.com/GitGuardian/sbx-kits-gitguardian
ggshield inside the microVM only ever holds a placeholder value for
GITGUARDIAN_API_KEY. When it calls the GitGuardian API, the sbx proxy rewrites
the Authorization: Token … header with the real key (sourced from the host) on
the wire. The real key never enters the sandbox — not in the environment,
shell history, or ps output.
Egress is proxy-mediated too, but the kit's four allowed hosts are added to
the host's sbx policy — they do not narrow it. Use
sbx policy init deny-all if you want the kit's entries to be the entire
allowlist.
ggshield's AI hook is agent-specific (each assistant reads a different hook
file), but this repo ships one artifact under :latest that covers them all:
the kit configures the hook for every assistant ggshield supports, and each
assistant reads only its own file, so the rest are inert. Consumers pin by
digest (sbx rejects OCI tags at consume time) — the tag is just a label
pointing at the digest to copy.
| Agent | Hook file the kit writes |
|---|---|
| claude | ~/.claude/settings.json |
| codex | ~/.codex/hooks.json |
| copilot | ~/.copilot/hooks/hooks.json |
| cursor | ~/.cursor/hooks.json |
The pinned ggshield (1.53.0) supports AI hooks for claude-code, codex,
copilot, cursor and vscode. Other sbx agents (gemini,
droid, kiro, opencode) have no ggshield AI hook — layer the kit onto them
for the ggshield CLI + manual scanning, but there is no automatic enforcement
hook.
Pin by digest (get the current digest from the repo Tags or the GitHub README) — the same digest works for every agent:
sbx run claude --kit "oci://docker.io/gitguardian/ggshield-kit@sha256:<digest>" .
sbx run codex --kit "oci://docker.io/gitguardian/ggshield-kit@sha256:<digest>" .
Requires a GitGuardian API key (Personal or Service Account, scan scope) bound
on the host as the gitguardian credential; the sandbox only ever sees a
proxy-managed placeholder.
ggshield from a pinned, digest-verified GitHub release.ggshield machine setup --agent <each one> --no-git-hooks --no-honeytokens, run as the agent user,
registering PreToolUse / PostToolUse / UserPromptSubmit handlers that
run ggshield secret scan ai-hook inside the agent's own tool loop.A blocked action means a real secret was detected — remove and rotate it, don't
retry or bypass. Manual scans (ggshield secret scan path -r .,
ggshield secret scan repo .) remain available as an escape hatch.
Licensed under the terms in the GitHub repository.