usestrix/strix · error · ValueError

Refusing to mount '{resolved}' into the sandbox: '{credentia

Error message

Refusing to mount '{resolved}' into the sandbox: '{credential}' holds credentials, not code.

What it means

The second half of the mount guard: even outside system trees, the path is rejected if ANY path component matches a credential-directory name (.ssh, .gnupg, .aws, .azure, .kube, .docker, .config, etc., case-insensitive). Mounting such directories would hand the sandboxed scanner the user's private keys and cloud credentials.

Source

Thrown at strix/interface/utils.py:1416

        tree_roots |= {str(drive / name) for name in _FORBIDDEN_WINDOWS_TREE_NAMES}
        exact.add(str(drive / "Users").casefold())
    trees = [Path(root) for root in tree_roots] + [Path(root).resolve() for root in tree_roots]
    if (
        str(resolved).casefold() in exact
        or resolved.parent == resolved
        or any(_is_within(resolved, tree) for tree in trees)
    ):
        raise ValueError(
            f"Refusing to mount '{resolved}' into the sandbox: it is a system "
            "or home directory, not a codebase. Point the target at the "
            "project directory you want tested."
        )

    credential = next(
        (part for part in resolved.parts if part.casefold() in _FORBIDDEN_MOUNT_DIR_NAMES), None
    )
    if credential is not None:
        raise ValueError(
            f"Refusing to mount '{resolved}' into the sandbox: '{credential}' "
            "holds credentials, not code."
        )


def dedupe_local_targets(targets_info: list[dict[str, Any]]) -> list[dict[str, Any]]:
    result: list[dict[str, Any]] = []
    seen_paths: set[str] = set()
    for target in targets_info:
        details = target.get("details") or {}
        path = details.get("target_path")
        if target.get("type") != "local_code" or not path:
            result.append(target)
            continue
        if path not in seen_paths:
            seen_paths.add(path)
            result.append(target)
    return result

View on GitHub (pinned to 8551339130)

Solutions

  1. Move the code out of any directory named like .ssh, .aws, .kube, .docker, .gnupg, .config, .azure into a normal project directory.
  2. If the name collides with a legitimate project dir, rename the component (e.g. 'ssh-studies' instead of '.ssh').
  3. Keep secrets outside the scanned tree and pass access via environment configuration instead of mounting.

Example fix

# before
strix -n -t ~/.config/my-app   # '.config' component refused

# after
mv ~/.config/my-app ~/projects/my-app
strix -n -t ~/projects/my-app
Defensive patterns

Strategy: validation

Validate before calling

FORBIDDEN_COMPONENTS = {".ssh", ".tsh", ".brev", ".gnupg", ".aws", ".azure",
                         ".kube", ".docker", ".config", ".git-credentials"}

def has_credential_component(path: str) -> bool:
    return any(part.casefold() in FORBIDDEN_COMPONENTS for part in Path(path).parts)

if has_credential_component(target):
    raise SystemExit(f"{target} sits inside a credential directory; move the project out")

Type guard

def is_free_of_credential_dirs(path: str) -> bool:
    return all(p.casefold() not in {".ssh", ".aws", ".kube", ".docker", ".gnupg", ".config", ".azure"} for p in Path(path).parts)

Try / catch

try:
    check_mountable_dir(Path(target))
except ValueError as e:
    if "holds credentials" in str(e):
        raise SystemExit("Rename/move the project out of the credential directory before scanning.") from e
    raise

Prevention

When it happens

Trigger: A target path like ~/.ssh/project, /backups/.aws/credentials-workdir, or any project nested under a directory named .ssh/.aws/.kube/.docker/.gnupg/.config/.azure/.tsh/.brev; also case variants like /data/SSH/ or /data/.AWS/ (compared casefolded).

Common situations: Users creating scratch dirs inside dotfile dirs; repos checked out under ~/.config (some tooling does this); deliberately putting test fixtures under a folder named .ssh.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/04e53d6003fe3d2e. Report an issue: GitHub.