Skip to content

Security — nanoclaw-extras

Secrets handling

This repo has no secrets to manage. The only two configuration values (OLLAMA_HOST, DEFAULT_MODEL) are a local URL and a model name — neither is sensitive, and Ollama's default HTTP API has no authentication. There is no API key, token, or credential anywhere in this codebase.

.env.example exists anyway for consistency with the rest of the house tool fleet (every repo documents its configuration surface the same way), and .gitignore excludes any local .env a developer might create.

Scan results summary

  • Secret-pattern grep (hard gate, run at ship time and again in CI):
    grep -rInE "council_[a-z0-9]{20,}|Bearer [A-Za-z0-9._-]{12,}|AKIA[0-9A-Z]{16}|sk-[A-Za-z0-9]{20,}|gh[pousr]_[A-Za-z0-9]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|-----BEGIN [A-Z ]*PRIVATE KEY-----" . --exclude-dir=.git
    
    Result: empty, both over the working tree and over full git history (Codex re-ran the same class of regex against git rev-list --all). Nothing to scrub.
  • Codex security review (codex exec "Security review this repository for: hardcoded secrets, injection, unsafe download/exec, CI supply-chain issues..."), run from repo root after the initial commit. Verdict: no hardcoded secrets, no command injection (group IDs are quoted at every call site in wire-ollama.sh). Three cheap findings, all hardened in the same pass:
  • HIGHpull_request on a persistent self-hosted Windows runner is a generic supply-chain risk if an untrusted PR could reach the workflow. Accepted, same as the house pilot repo: this is a private repo with a closed set of trusted PR authors, and the ci.yml header comment says so explicitly.
  • MEDIUM — the Semgrep Docker image was referenced by a floating tag. Fixed: pinned to semgrep/semgrep@sha256:06938c1f365d3f67b8cedd8bc117607ae64253f88a0e768e9da9408548927dd6.
  • MEDIUMwire-ollama.sh's default npx tsx src/cli/client.ts can fetch tsx from npm on first run if it isn't already resolvable locally. This script is meant to be dropped into an existing NanoClaw checkout, which is expected to already pin tsx as a devDependency (so npx resolves the local, lockfile-pinned copy rather than reaching out to the registry) — documented here rather than changed in the script, since hardcoding a different invocation would diverge from how NanoClaw's own CLI is normally run.
  • Semgrep (semgrep/semgrep Docker image, digest-pinned, --config auto --error): runs in the security CI job on every push/PR.

Attack-surface notes

  • extras/ollama-mcp.mjs only issues outbound GET/POST requests to OLLAMA_HOST (defaults to http://host.docker.internal:11434, i.e. the local host machine from inside the container — never an arbitrary or attacker-controlled host, since the URL is fixed at MCP-server-registration time by wire-ollama.sh, not read from a request).
  • It does not execute shell commands, read arbitrary files, or evaluate untrusted input — the only inputs are the two Ollama HTTP responses and newline-delimited JSON-RPC frames on stdin, both parsed with JSON.parse inside a try/catch that drops malformed lines rather than throwing.
  • extras/wire-ollama.sh shells out to NanoClaw's own CLI (src/cli/client.ts) and to cp; it takes an optional group-id argument but does not eval or otherwise execute attacker-controlled strings. NCL_OVERRIDE is a test-only hook (see TESTING.md) — it is read from the environment, not from any external/network input, so it is not an injection vector in normal use.
  • CI's security job is SHA-pinned (actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683) per the house supply-chain policy, and Semgrep runs via the official Docker image (no native Windows Semgrep binary exists).

Archive policy and secrets

Files moved to archive/ are never deleted and still obey the secret-pattern grep gate — there is currently nothing archived in this repo.