Skip to content

safety-guardrails.py: secrets?\.(json|ya?ml|toml) regex blocks legitimate infra paths containing 'secret'/'secrets' in directory names #321

Description

@azalio

Summary

.claude/hooks/safety-guardrails.py (PreToolUse guardrail, mapify_version 3.20.0) blocks Edit/Write on legitimate, non-credential files whenever any path segment matches secrets? and the file has a .json/.yaml/.yml/.toml extension — even when the "secret" match comes from a directory/component name (e.g. secrets-injector, stackland-secrets-webhook) rather than an actual credentials file.

Observed

Working in azalio/quantum (Stackland platform monorepo), branch caldera-firestorm, on a MAP subtask (ST-001) whose entire job is to add a skipTLSVerify Helm value/env var to a component literally named "secrets injector" / "stackland-secrets-webhook" (a legitimate webhook that injects secrets into pods — the name itself, not a credential file).

All four target Edit calls were denied with File is in a directory that is denied by your permission settings.:

  • secrets-injector/deploy/webhook/helm/stackland-secrets-webhook/values.yaml
  • secrets-injector/deploy/webhook/helm/stackland-secrets-webhook/templates/deployment.yaml
  • helm-charts/stackland-secrets/charts/stackland-secrets-webhook/values.yaml
  • helm-charts/stackland-secrets/charts/stackland-secrets-webhook/templates/deployment.yaml

Root cause traced to .claude/hooks/safety-guardrails.py:

  • _DEFAULT_DANGEROUS_FILE_MARKERS includes the bare substring "secret", so the fast pre-check any(marker in path_lower for marker in _DEFAULT_DANGEROUS_FILE_MARKERS) is true for any path containing "secret"/"secrets" ANYWHERE (component name, directory name, chart name — not just the leaf filename).
  • Once that pre-check trips, DANGEROUS_FILE_PATTERNS regex r"secrets?\.(json|ya?ml|toml)" is evaluated against the full lowercased path (not just the basename), so .../stackland-secrets-webhook/values.yaml matches because the substring secrets-webhook/values.yaml — wait, actually more precisely .../stackland-secrets-webhook/... contains secrets immediately followed eventually by a yaml extension path; the regex is unanchored and scans the whole path string, so any directory literally named ...secrets... combined with a .yaml/.json/.toml file ANYWHERE later in the path can match, independent of directory/file semantics.
  • This combination affects an entire class of legitimate Kubernetes/Helm assets: any secrets-management operator/webhook/controller chart (external-secrets, secrets-store-csi-driver, HashiCorp Vault integrations, custom secrets-injector components, etc.) that stores its config in values.yaml/Chart.yaml under a directory containing "secret(s)" in the name.

This is a project (host-repo) .claude/settings.json + hook combo that mapify generated/manages (_map_managed.generated_by: mapify-cli, version 3.20.0), so it is a map-framework-shipped artifact, not a host-repo hand-written rule.

Expected

The dangerous-file heuristic should target actual credential/secret-value files (e.g. a literal secrets.yaml/secret.json file used to STORE secret material, or paths like **/secrets/*.yaml used as a secret-mount convention), not any path where a component/directory is merely named "secrets-" or "-secrets-*". Suggested improvches (not prescribing the fix, just observed signal):

  • Anchor the regex to the basename only (e.g. ^secrets?\.(json|ya?ml|toml)$ against os.path.basename(path)), not the full path.
  • Or require the "secret" token to be a whole path segment equal to secret/secrets (e.g. /secrets/foo.yaml) rather than a substring of a longer component name like stackland-secrets-webhook.
  • Consider allow-listing common non-secret-value file types even under secret-related directories: values.yaml, Chart.yaml, deployment.yaml, template files under templates/.

Environment

  • mapify_version: 3.20.0
  • File: .claude/hooks/safety-guardrails.py (function check_file_safety, lines ~126-149 in the affected checkout)
  • Host repo: azalio/quantum, branch caldera-firestorm

Impact

Blocks all Actor edits to a real (in-scope, approved) MAP subtask whose target files are Helm chart values/templates for a secrets-injector webhook component — a false positive that halts an otherwise-correct implementation with no safe workaround other than expanding safe_path_prefixes in .map/config.yaml (host-repo config change, out of scope for the current subtask) or disabling the hook (not appropriate to do unilaterally as an Actor).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions