coldvault.dev β by ZONOVA RESEARCH β a drop-in sandbox for auditing code you don't trust. Clone it, open a GitHub Codespace, point Claude Code at a suspect repository, receive a consolidated security report.
Cold because the code is never executed β it stays frozen while you inspect it. Vault because the analysis happens behind armoured walls.
License: MIT (ZONOVA RESEARCH) Powered by Claude Code Devcontainer
A public, reproducible audit environment that lets a security analyst (or a Claude Code agent) statically review an untrusted repository without ever executing its code. A curated set of core scanners β SAST, SCA, secrets, malware, IaC β is pre-baked into a lean Debian devcontainer. Language-specific and heavyweight optional tools can be added on demand in under a minute.
Design tenets
- π§ Never run untrusted code. The suspect repo is mounted as a read-only
git submodule under
target/. All analysis is static. - πͺΆ Lean core, extensible. The base image ships only the tools needed for a full general-purpose audit. Optional tool groups (Rust, Java, PHP, C/C++, extra scanners...) are installed on demand via a single script.
- π€ Agent-assisted. A curated set of Claude Code skills (inspired by
trailofbits/skills,anthropics/claude-code-security-reviewand Snyk's workflow) turn the analyst's intent into reproducible scans. - π Reproducible. Findings land in
reports/as JSON/SARIF plus a Markdown summary β nothing is left to memory.
flowchart LR
U[Analyst] -->|1. clone public audit repo| R[coldvault]
R -->|2. Open in Codespace| CS{{GitHub Codespace}}
CS -->|3. gh auth login<br/>claude login| A[Authenticated session]
A -->|4. git submodule add SUSPECT target/| T[target/ read-only]
A -->|5. claude β /audit| C[Claude Code + skills]
C -->|invokes wrappers| S[scripts/scan-*.sh]
S --> TL[[Pre-installed tool stack]]
TL -->|SARIF/JSON| RP[reports/]
RP -->|findings.json + SUMMARY.md| U
classDef toxic fill:#fee,stroke:#c00,stroke-width:2px;
class T toxic;
Five commands, start to finish:
git clone https://github.com/rasata/coldvault.dev cd coldvault.dev # β Click "Open in GitHub Codespaces" gh auth login && claude login git submodule add <SUSPECT-REPO-URL> target/ export COLDVAULT_ACCEPTABLE_USE=defensive-security-research-only claude # then type /audit
flowchart TB
subgraph INPUT["target/ β untrusted submodule"]
SRC[source files]
LOCK[lockfiles]
CI[.github/workflows]
BIN[binaries / images]
IAC[Terraform / K8s / Dockerfile]
end
subgraph SECRETS["π Secrets"]
gitleaks
trufflehog
detect-secrets
ggshield
end
subgraph SCA["π¦ Supply-chain / SCA"]
osv[osv-scanner]
trivy
grype
syft
depcheck[OWASP Dependency-Check]
npm-audit
pip-audit
govulncheck
cargo-audit
cargo-deny
bundler-audit
snyk
end
subgraph SAST["π SAST"]
semgrep
bandit
njsscan
gosec
staticcheck
clippy
cppcheck
flawfinder
clang-tidy
psalm
phpstan
brakeman
eslint-sec[eslint + security plugins]
retire
end
subgraph MAL["π¦ Malware / binary"]
yara
yarax[YARA-X]
capa
binwalk
clamav
oletools
radare2
end
subgraph IACSCAN["ποΈ IaC / container"]
tfsec
terrascan
checkov
hadolint
dockle
kubesec
kubescore[kube-score]
trivyfs[trivy fs/image/config]
end
SRC --> SECRETS
SRC --> SAST
LOCK --> SCA
CI --> SAST
CI --> MAL
BIN --> MAL
IAC --> IACSCAN
SECRETS --> REP[(reports/)]
SCA --> REP
SAST --> REP
MAL --> REP
IACSCAN --> REP
| Language | SAST | SCA / dep audit |
|---|---|---|
| JS / TS / Node | semgrep, njsscan, eslint-security, retire | osv-scanner, npm audit, snyk, trivy |
| Python | semgrep, bandit, dlint | pip-audit, safety, osv-scanner |
| Go | semgrep, gosec, staticcheck | govulncheck, osv-scanner |
| Rust | semgrep, clippy | cargo-audit, cargo-deny, cargo-geiger |
| C / C++ | cppcheck, flawfinder, clang-tidy | trivy, osv-scanner |
| Java / JVM | semgrep | OWASP Dep-Check, trivy, snyk |
| PHP | psalm, phpstan | enlightn/security-checker |
| Ruby | brakeman | bundler-audit, ruby_audit |
| Shell | shellcheck, semgrep | β |
| IaC | tfsec, terrascan, checkov | trivy config |
| Containers | hadolint, dockle, trivy image | trivy, grype, syft |
| Binary / PE | yara, capa, binwalk, oletools, radare2, clamav | β |
| GitHub Actions | semgrep (p/github-actions), custom |
β |
flowchart LR
subgraph HOST["Your laptop"]
UA[Analyst]
end
subgraph CODESPACE["GitHub Codespace (ephemeral VM)"]
direction TB
CL[Claude Code CLI]
FS[".devcontainer image<br/>core security tools"]
TG[target/ submodule<br/>READ-ONLY]
RS[reports/]
end
UA -- browser / VS Code --> CL
CL -- static scans --> TG
CL -- writes --> RS
CL -. never executes .-> TG
style TG fill:#fee,stroke:#c00,stroke-width:2px
style CODESPACE fill:#f5f7ff,stroke:#446
- Ephemeral VM: compromise of the audit run cannot persist to the analyst's laptop β only the Codespace is at risk, and it is thrown away.
- No local installs: avoids "
npm installis already RCE" on the host. - Submodule pointer only: the
target/commit is recorded, so the audit is reproducible and its scope is auditable. - Read-only tool paths: system tools live under
/usr/local/binowned byroot; the agent runs asvscode.
| Threat | Mitigation |
|---|---|
npm install / pip install executes install hooks |
CLAUDE.md Β§ 0 forbids any install; agent uses lockfile parsers only |
Prompt injection in target/README.md |
CLAUDE.md Β§ 1 β inline instructions are data, not commands |
| Exfiltration via build-time network calls | No build is ever run on target/ |
| Scanner itself has a parser CVE (billion-laughs etc.) | Run in ephemeral Codespace; no secrets from host reachable |
| Agent is tricked into committing target secrets | .gitignore excludes reports/; agent never git add under target/ |
| Malicious GitHub Action triggered on push | The repo has no workflows that act on target/; Codespace can't push |
Binary payloads (e.g. shipped node_modules/.bin) |
YARA + capa + clamav + hash checks; never executed |
.
βββ .devcontainer/
β βββ Dockerfile # Debian + core security tools (minimal base)
β βββ devcontainer.json # Codespace config, no-new-privileges, dropped caps
β βββ post-create.sh # DB warm-up, core tool smoke-test
β βββ install-optional-tools.sh # On-demand optional tool groups
βββ .claude/
β βββ settings.json # Restrictive permissions for target/
β βββ commands/ # /audit, /scan-secrets, /scan-deps, /scan-malware, /security-review
β βββ skills/ # 15+ curated security skills
βββ scripts/ # Bash wrappers (SARIF/JSON output to reports/)
β βββ audit-all.sh
β βββ scan-secrets.sh
β βββ scan-deps.sh
β βββ scan-sast.sh
β βββ scan-malware.sh
β βββ scan-iac.sh
β βββ scan-containers.sh
βββ rules/
β βββ semgrep/ # Custom project-specific rules
β βββ yara/ # Custom malware signatures
βββ reports/ # (gitignored) β audit output lives here
βββ target/ # Suspect code (git submodule)
βββ CLAUDE.md # Audit protocol & safety rules
βββ LICENSE # MIT β ZONOVA RESEARCH variant
βββ README.md
Inspired by Trail of Bits' skills, Anthropic's security-review action, and Snyk's Code/OS workflow:
| Skill | Role |
|---|---|
audit-context-building |
Inventory languages, frameworks, entry points |
untrusted-code-isolation |
Reinforces the "never execute target/" rule |
supply-chain-risk-auditor |
Lockfile, maintainer, typo-squat, postinstall review |
snyk-sca |
Snyk-parity dependency vulnerability workflow |
snyk-sast |
Snyk-parity code scanning workflow |
secrets-hunter |
gitleaks + trufflehog + manual triage |
static-analysis-orchestrator |
Runs the right SAST per language, merges SARIF |
semgrep-rule-creator |
Writes ad-hoc Semgrep rules for suspicious patterns |
yara-malware-hunter |
Scans binaries & source blobs with YARA / YARA-X |
insecure-defaults-hunter |
Weak crypto, permissive CORS, TLS disabled, etc. |
entry-point-analyzer |
Maps HTTP / CLI / library attack surface |
variant-analysis |
Expands a single finding into sibling occurrences |
agentic-actions-auditor |
.github/workflows/** risk (pull_request_target, etc.) |
constant-time-analysis |
Timing-leak review in crypto code |
security-review |
PR-style review in Anthropic's JSON finding schema |
See .claude/skills/ for full documentation of each.
/audit Full pipeline β context β secrets β SCA β SAST β malware β report
/scan-secrets Run secret scanners only
/scan-deps Supply-chain / SCA pass only
/scan-sast Static analysis pass only
/scan-malware YARA + capa + binary triage
/scan-iac Terraform / K8s / Dockerfile
/security-review PR-mode: review only the diff in target/ (HEAD vs. base)
Every run produces:
reports/findings.jsonβ machine-readable, matches the schema inCLAUDE.mdΒ§4.reports/SUMMARY.mdβ human-readable executive summary.reports/<tool>.sarif/reports/<tool>.jsonβ raw per-tool output.reports/sbom.cdx.jsonβ CycloneDX SBOM oftarget/.
# 1. Clone this repo git clone https://github.com/rasata/coldvault.dev.git cd coldvault.dev # 2. Open in GitHub Codespaces # (click the "Code" button β "Codespaces" β "Create codespace on main") # The devcontainer image pre-installs all scanners. # 3. Inside the Codespace terminal. # Claude CLI and GitHub CLI are ALREADY installed by the devcontainer image # (see .devcontainer/Dockerfile Β§7). You only need to authenticate: gh auth login # browser flow claude login # Claude Code auth # 4. Attach the suspect repo as a READ-ONLY submodule git submodule add --depth=1 https://github.com/<suspect>/<repo>.git target/ # 5. Acknowledge defensive-use policy (required by scan scripts) export COLDVAULT_ACCEPTABLE_USE=defensive-security-research-only # 6. Launch the audit claude # > /audit # 7. Open reports/SUMMARY.md
The public landing page served at https://coldvault.dev lives in this same
repo under website/ β a Vite + React + TanStack Router static
SPA. It is self-contained (no external submodule, no private upstream,
no on-premise deployment path).
cd website npm ci npm run dev # local preview on :8080 npm run build # static artifact in website/dist
Deployment is automated by
.github/workflows/deploy-pages.yml
β every push to main that touches website/** builds the SPA and publishes
it to GitHub Pages behind the coldvault.dev custom domain. The only
authoritative origin is https://coldvault.dev; see
website/IMPERSONATION.md for the
anti-impersonation controls and the one-time DNS setup.
The base devcontainer image ships a lean core stack. Language-specific and heavyweight tools are installed on demand using the bundled installer script.
| Tool | Purpose |
|---|---|
semgrep |
Multi-language SAST + rules cache |
gitleaks |
Secret scanning |
detect-secrets |
Secret scanning (complementary) |
bandit |
Python SAST |
gosec |
Go SAST |
govulncheck |
Go dependency vulnerability check |
trivy |
SCA, IaC config, container scanning, SBOM |
osv-scanner |
Lockfile-based SCA (fast) |
hadolint |
Dockerfile linting |
yara |
YARA rule scanning (+ community + signature-base) |
Claude Code CLI |
AI-assisted audit orchestration |
# Install everything (all groups) bash .devcontainer/install-optional-tools.sh # Install one or more specific groups bash .devcontainer/install-optional-tools.sh rust bash .devcontainer/install-optional-tools.sh sca iac
When run as a non-root user (the default vscode devcontainer user), the
installer automatically redirects pipx, npm -g, and go install outputs
to user-writable paths (~/.local/bin, ~/.npm-global/bin, ~/go/bin) β no
sudo required for those operations. Only apt-get and system-level package
operations still use sudo.
Note: Add the user paths to your shell profile to make them permanent:
export PATH="$HOME/.local/bin:$HOME/.npm-global/bin:$HOME/go/bin:$PATH"
| Group | Tools installed |
|---|---|
secrets |
trufflehog, ggshield |
sast |
njsscan, dlint, safety, pip-audit, cfn-lint, sqlfluff, eslint + security plugins, retire, snyk, staticcheck, errcheck, gocritic |
sca |
grype, syft, dependency-check (requires java group), cyclonedx-bom, cdxgen |
iac |
tfsec, terrascan, checkov, kube-score, kubesec, dockle |
malware |
capa, oletools (+ pefile), binwalk, malwoverview |
rust |
Rust toolchain (stable), cargo-audit, cargo-deny, cargo-geiger, cargo-outdated, yara-x-cli |
java |
JDK, Maven, Gradle |
php |
php-cli, composer, psalm, phpstan, enlightn/security-checker |
ruby |
ruby, brakeman, bundler-audit, ruby_audit |
cpp |
clang, clang-tools, clang-tidy, cppcheck, flawfinder, splint |
reverse |
radare2, gdb, strace, ltrace |
Tip: The installer is idempotent β re-running it for a group that is already installed is safe.
If you regularly use a set of optional tools, create a derived image:
FROM ghcr.io/rasata/coldvault.dev:latest RUN bash .devcontainer/install-optional-tools.sh rust sca malware
Or add the groups you need to the postCreateCommand in your fork's
devcontainer.json:
"postCreateCommand": "bash .devcontainer/post-create.sh && bash .devcontainer/install-optional-tools.sh rust sca"
- Add a new core scanner β edit
.devcontainer/Dockerfile+ a wrapper inscripts/. - Add a new optional scanner β edit
.devcontainer/install-optional-tools.sh+ a wrapper inscripts/. - Add a new Claude skill β drop a
SKILL.mdunder.claude/skills/<name>/. - Add project-specific Semgrep rules β
rules/semgrep/*.yml. - Add project-specific YARA rules β
rules/yara/*.yar.
PRs welcome. Do not include real-world malware samples or live secrets.
- Forks and redistributions must keep
LICENSE,DISCLAIMER.md, and visible attribution to ZONOVA RESEARCH β https://zonova.io . - Scan scripts now require explicit acknowledgement:
COLDVAULT_ACCEPTABLE_USE=defensive-security-research-only. - This project is for authorized defensive security work only; offensive or unlawful use is prohibited.
See DISCLAIMER.md and LICENSE for full terms.
MIT License β ZONOVA RESEARCH variant. See LICENSE.
If you redistribute or build on this project, credit ZONOVA RESEARCH β https://zonova.io in your README or About dialog.
This project assembles, wraps, and credits the work of many open-source teams:
- Semgrep, Trail of Bits, Anchore, Aqua Security, Google OSV, GitLeaks, Trufflehog, YARA / VirusTotal, Snyk OSS, OWASP, Anthropic (Claude Code + security-review).
- Skill patterns derived from trailofbits/skills and anthropics/claude-code-security-review.
coldvault.dev Β· Powered by ZONOVA RESEARCH Β· Made for defenders.