Skip to content

check-security-binding: directory --credential-roots accept a directory-read failure as credential-absence evidence #967

Description

@kyle-sexton

Lane: merge-drive (deferred finding from PR #947, branch fix/549-credential-roots-allowlist).

Source. Codex P2 thread "Require credential probes below directory roots" on plugins/autonomy/skills/setup/scripts/check-security-binding.mjspathUnderConfiguredRoot equality case plus the credentials_absent grading (~L1340-1370).

Finding. When an operator configures a directory as a --credential-roots entry (e.g. /home/runner/.aws), a transcript whose probed path/host_expanded equals that directory passes containment via the equality case (normCandidate === normRoot). A directory reliably satisfies every downstream check: the outer existence probe succeeds (outer_exit_code "0"), the inner file-read fails with a directory-read error (non-zero exit_code, transport_outcome "read-denied"). The checker therefore grants L2 credential-absence even though real credential files beneath the directory (e.g. /home/runner/.aws/credentials) remain readable and were never probed.

Classification. Over-permissive edge in the deny-by-default credential allowlist (accepts non-probative evidence, feeding an autonomy-binding grant). Not the vacuous-root class already fixed on-branch for POSIX / and bare drive roots: a directory root still genuinely constrains the allowlist and requires the operator to have configured that exact directory, so this is a narrower hardening refinement, not a fail-open that makes the allowlist vacuous. Deferred rather than point-fixed, consistent with #549's ratified anti-enumeration posture (operator-configured roots are the convergence mechanism; do not re-enter open-ended structural recognition).

Why not point-fixed on-branch. The static transcript checker cannot stat the probing host, and the transcript records no errno/file-type — transport_outcome is coarse ("read-denied") and cannot distinguish an EISDIR directory-read from a credential-file read failure. So no clean generic fix exists: (a) structural file-vs-directory heuristics on the path string are exactly the open-ended structural recognition #549 closed; (b) dropping the equality case would deny the legitimate config where an operator configures an exact credential file as a root and the probe targets that file, with regression-test blast radius.

Fix direction (for #549 follow-up design). Decide whether directory roots should require strict-descendant containment (equality reserved for exact credential-file roots), and add a file-type/errno signal to the probe transcript contract (templates/isolation-probe.md) so a directory-read (EISDIR) is rejected as non-probative. Both are contract/design changes, not point-fixes.

Related. #549 (ratified Option A — deny-by-default --credential-roots), PR #947.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: mediumReal value, no hard deadline; normal backlog flow.

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions