Skip to main content
Secret protection blocks reads and writes of credential-bearing files — SSH keys, .env files, cloud credential stores, coding-agent auth tokens — before command analysis runs. It applies in every safety level and fails closed on inputs it cannot analyze. This page is the rule catalog: every built-in rule id, what it matches, and its default state. It is the reference for two questions the other pages defer: is this file protected? and which id turns that rule off? For the secret_protection configuration schema see Policy; for where the stage sits in the guard flow see Architecture; for command-level behavior and worked examples see Blocked commands. There are 132 registered rules. Most belong to generated families that share one id pattern, so the tables below list families with their id form rather than every id. Every rule is on by default except the ten-rule Coding CLI config tier.

Where it runs

Sensitive-path protection is a guard stage that runs before command analysis, across the supported command, path, search (grep/glob), and patch shapes. For a tool CC Safety Net does not recognize, it inspects both the command-candidate extraction and the path-like values — without ever treating that tool’s arbitrary text as a shell command. A match denies with intent hard_stop and carries the matched rule id, so the block message and the audit log name the exact rule. Reads are blocked, not just writes: cat .env, strings id_rsa, and dd if=.env all block. An expansion that assigns its fallback exposes that fallback as a path, unquoted or double-quoted alike: cat "${X:=.env}" and cat ${X=.env} both block under secret.basename.env. Single-quoted text stays inert, so cat '${X:=.env}' does not block.

Match order

Each candidate path goes through the checks below in order. The first match wins; the exemptions only apply to the rules that come after them.
  1. Configured deny paths — checked before every built-in rule and before every exemption. A hit attributes to secret.deny-path.
  2. Env-template exemption — the template basenames stay readable; see Exemptions.
  3. Home directory rules — whole protected directories such as ~/.ssh. These take priority over the public-key exemption, so ~/.ssh/id_rsa.pub still blocks.
  4. Coding CLI rules — the per-agent credential and config paths.
  5. Public-key exemptionid_rsa.pub, id_ed25519.pub, and id_ecdsa.pub are non-secret outside the protected directories.
  6. Basename rules, then the .env.* pattern, then the key-variant rules.
  7. Vendored-directory exemption — suppresses only the remaining two families; see Exemptions.
  8. The broad SSH basename pattern, then the extension rules.

Basename rules

Nine rules block an exact basename in any directory. Two boundaries worth knowing:
  • secret.basename.credentials matches the exact name credentials only. credentials.json does not match it — or any other built-in rule.
  • There is no id_dsa basename rule. An exact id_dsa still blocks, through the broad pattern secret.pattern.ssh-key-basename below.
One pattern rule extends the .env family: secret.pattern.env-variant blocks every basename starting with .env..env.local, .env.production, .env.template.local — except the exempt templates.

Home directory rules

These rules protect locations under the home directory: the directory itself and everything inside it. The two single-file rules (kube-config, docker-config) each have eight companion rules covering renamed backups, with the id form secret.home.<slug>.<suffix>: the suffixes are bak, backup, copy, disabled, old, orig, save, and tmp. So ~/.kube/config.bak blocks under secret.home.kube-config.bak, and ~/.docker/config.json.old under secret.home.docker-config.old. That is 16 generated rules, 23 in the family overall.

Key-variant rules

Rename-shielded copies of key and credential files are their own family, built from five protected prefixes: id_rsa, id_dsa, id_ed25519, id_ecdsa, and credentials. The slug in each id is the prefix with dashes (id-rsa, credentials, …).
  • Separator variantssecret.variant.<slug>.separator (5 rules). Blocks the prefix followed by - or _ and anything after it: id_rsa-old, id_rsa_backup, credentials_prod.
  • Dot-suffix variantssecret.variant.<slug>.<suffix> (50 rules). Blocks the prefix followed by exactly one of ten suffixes: .bak, .backup, .copy, .disabled, .key, .old, .orig, .pem, .save, .tmp. So id_rsa.bak blocks under secret.variant.id-rsa.bak, and credentials.pem under secret.variant.credentials.pem.
The family is deliberately exact, so lookalikes pass: id_rsafoo matches no separator, and credentials.json uses a suffix outside the list. One broad pattern closes the family: secret.pattern.ssh-key-basename blocks any extensionless basename ending in _rsa, _dsa, _ed25519, or _ecdsadeploy_key_rsa, github_ed25519. A name containing a dot never matches it.

Extension rules

Twenty-one rules with the id form secret.ext.<extension> block any file carrying that extension: .agilekeychain, .asc, .bek, .cscfg, .fve, .gnucash, .jks, .keychain, .kwallet, .mdf, .ovpn, .p12, .pcap, .pem, .pfx, .pkcs12, .psafe3, .rdp, .sdf, .tblk, .tpm Three extension-pattern rules cover extension families: An override must use the family id — secret.ext-pattern.key, not secret.ext.keypair. An id that is not registered is rejected with unknown secret protection rule id "<id>".

Coding CLI credential tier (on by default)

Nine rules protect the credential stores of supported coding agents. Like every other rule so far, they are on whenever secret protection is enabled. Antigravity has no credential rule — its only rule sits in the config tier below.

Coding CLI config tier (off by default)

Ten rules cover the settings and MCP configuration files of the same agents. Those files can carry credentials inline, but agents also edit them as routine work, so this tier ships off and each rule needs an explicit "on" in secret_protection.overrides to activate. <project> paths match at any repository root once the rule is on.

Deny paths

secret_protection.deny_paths adds your own protected locations. A hit is a hard stop attributed to secret.deny-path — an id that is not registered, so no override can disable it, and none of the exemptions on this page apply to it. Deny paths stop applying only when secret_protection.enabled is false, which turns off the whole stage. The accepted entry forms are in Policy.

Exemptions

Three exemptions bound the rules above. None of them relax a configured deny path.
  • Env templates. The exact basenames .env.example, .env.sample, .env.template, and .env.defaults — plus any name starting with .env.example. or .env.sample. — are exempted before every built-in rule, even inside a protected home directory. The prefix form does not extend further: .env.template.local blocks under secret.pattern.env-variant like any other .env.* name.
  • Public keys. id_rsa.pub, id_ed25519.pub, and id_ecdsa.pub are non-secret and exempt — but only outside the protected home directories, which are checked first. ./id_rsa.pub is allowed; ~/.ssh/id_rsa.pub blocks under secret.home.ssh.
  • Vendored directories. When any path segment is node_modules or __pycache__, or the adjacent pair vendor/bundle or vendor/cache appears, exactly two families are suppressed: the extension rules (plain and pattern) and the broad secret.pattern.ssh-key-basename rule. Every other rule still applies there — node_modules/x/.env and node_modules/x/id_rsa block as usual. .git is not in the skip set.

Configuration

All configuration lives in policy.json:
  • secret_protection.enabled: false turns the whole stage off — built-in rules and deny paths alike.
  • secret_protection.overrides sets per-rule state by registered id: "off" disables an on-by-default rule; "on" opts into a config-tier rule.
  • secret_protection.deny_paths adds your own protected locations.
Neither allow paths nor any standard-mode allowance ever relaxes secret protection. In strict mode, metadata-only discovery of these paths (test -f ~/.ssh/id_rsa, find ~/.ssh -type f) is blocked as well. The Dashboard edits the same settings through a UI.
Secret protection is a bounded pattern set, not a general read boundary. A credential in a file no rule recognizes is not protected — see vs. sandboxing for that boundary, and Known limitations for the tier caveats. Secret redaction — scrubbing credential values from logs and block messages — is a separate mechanism, documented in the Audit log reference and the Security model.
Last modified on August 6, 2026