docs(security): refine local secret management guidance
Supersedes: #406 Co-authored-by: Gabriel Nahum <gnahum12345@users.noreply.github.com>
This commit is contained in:
parent
8371f412f8
commit
23db125971
4 changed files with 157 additions and 11 deletions
59
.env.example
59
.env.example
|
|
@ -1,26 +1,65 @@
|
||||||
# ZeroClaw Environment Variables
|
# ZeroClaw Environment Variables
|
||||||
# Copy this file to .env and fill in your values.
|
# Copy this file to `.env` and fill in your local values.
|
||||||
# NEVER commit .env — it is listed in .gitignore.
|
# Never commit `.env` or any real secrets.
|
||||||
|
|
||||||
# ── Required ──────────────────────────────────────────────────
|
# ── Core Runtime ──────────────────────────────────────────────
|
||||||
# Your LLM provider API key
|
# Provider key resolution at runtime:
|
||||||
# ZEROCLAW_API_KEY=sk-your-key-here
|
# 1) explicit key passed from config/CLI
|
||||||
|
# 2) provider-specific env var (OPENROUTER_API_KEY, OPENAI_API_KEY, ...)
|
||||||
|
# 3) generic fallback env vars below
|
||||||
|
|
||||||
|
# Generic fallback API key (used when provider-specific key is absent)
|
||||||
API_KEY=your-api-key-here
|
API_KEY=your-api-key-here
|
||||||
|
# ZEROCLAW_API_KEY=your-api-key-here
|
||||||
|
|
||||||
# ── Provider & Model ─────────────────────────────────────────
|
# Default provider/model (can be overridden by CLI flags)
|
||||||
# LLM provider: openrouter, openai, anthropic, ollama, glm
|
|
||||||
PROVIDER=openrouter
|
PROVIDER=openrouter
|
||||||
|
# ZEROCLAW_PROVIDER=openrouter
|
||||||
# ZEROCLAW_MODEL=anthropic/claude-sonnet-4-20250514
|
# ZEROCLAW_MODEL=anthropic/claude-sonnet-4-20250514
|
||||||
# ZEROCLAW_TEMPERATURE=0.7
|
# ZEROCLAW_TEMPERATURE=0.7
|
||||||
|
|
||||||
|
# Workspace directory override
|
||||||
|
# ZEROCLAW_WORKSPACE=/path/to/workspace
|
||||||
|
|
||||||
|
# ── Provider-Specific API Keys ────────────────────────────────
|
||||||
|
# OpenRouter
|
||||||
|
# OPENROUTER_API_KEY=sk-or-v1-...
|
||||||
|
|
||||||
|
# Anthropic
|
||||||
|
# ANTHROPIC_OAUTH_TOKEN=...
|
||||||
|
# ANTHROPIC_API_KEY=sk-ant-...
|
||||||
|
|
||||||
|
# OpenAI / Gemini
|
||||||
|
# OPENAI_API_KEY=sk-...
|
||||||
|
# GEMINI_API_KEY=...
|
||||||
|
# GOOGLE_API_KEY=...
|
||||||
|
|
||||||
|
# Other supported providers
|
||||||
|
# VENICE_API_KEY=...
|
||||||
|
# GROQ_API_KEY=...
|
||||||
|
# MISTRAL_API_KEY=...
|
||||||
|
# DEEPSEEK_API_KEY=...
|
||||||
|
# XAI_API_KEY=...
|
||||||
|
# TOGETHER_API_KEY=...
|
||||||
|
# FIREWORKS_API_KEY=...
|
||||||
|
# PERPLEXITY_API_KEY=...
|
||||||
|
# COHERE_API_KEY=...
|
||||||
|
# MOONSHOT_API_KEY=...
|
||||||
|
# GLM_API_KEY=...
|
||||||
|
# MINIMAX_API_KEY=...
|
||||||
|
# QIANFAN_API_KEY=...
|
||||||
|
# DASHSCOPE_API_KEY=...
|
||||||
|
# ZAI_API_KEY=...
|
||||||
|
# SYNTHETIC_API_KEY=...
|
||||||
|
# OPENCODE_API_KEY=...
|
||||||
|
# VERCEL_API_KEY=...
|
||||||
|
# CLOUDFLARE_API_KEY=...
|
||||||
|
|
||||||
# ── Gateway ──────────────────────────────────────────────────
|
# ── Gateway ──────────────────────────────────────────────────
|
||||||
# ZEROCLAW_GATEWAY_PORT=3000
|
# ZEROCLAW_GATEWAY_PORT=3000
|
||||||
# ZEROCLAW_GATEWAY_HOST=127.0.0.1
|
# ZEROCLAW_GATEWAY_HOST=127.0.0.1
|
||||||
# ZEROCLAW_ALLOW_PUBLIC_BIND=false
|
# ZEROCLAW_ALLOW_PUBLIC_BIND=false
|
||||||
|
|
||||||
# ── Workspace ────────────────────────────────────────────────
|
|
||||||
# ZEROCLAW_WORKSPACE=/path/to/workspace
|
|
||||||
|
|
||||||
# ── Docker Compose ───────────────────────────────────────────
|
# ── Docker Compose ───────────────────────────────────────────
|
||||||
# Host port mapping (used by docker-compose.yml)
|
# Host port mapping (used by docker-compose.yml)
|
||||||
# HOST_PORT=3000
|
# HOST_PORT=3000
|
||||||
|
|
|
||||||
8
.githooks/pre-commit
Executable file
8
.githooks/pre-commit
Executable file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if command -v gitleaks >/dev/null 2>&1; then
|
||||||
|
gitleaks protect --staged --redact
|
||||||
|
else
|
||||||
|
echo "warning: gitleaks not found; skipping staged secret scan" >&2
|
||||||
|
fi
|
||||||
13
.gitignore
vendored
13
.gitignore
vendored
|
|
@ -4,6 +4,17 @@ firmware/*/target
|
||||||
*.db-journal
|
*.db-journal
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.wt-pr37/
|
.wt-pr37/
|
||||||
.env
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
# Environment files (may contain secrets)
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Secret keys and credentials
|
||||||
|
.secret_key
|
||||||
|
*.key
|
||||||
|
*.pem
|
||||||
|
credentials.json
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,94 @@ git push --no-verify
|
||||||
|
|
||||||
> **Note:** CI runs the same checks, so skipped hooks will be caught on the PR.
|
> **Note:** CI runs the same checks, so skipped hooks will be caught on the PR.
|
||||||
|
|
||||||
|
## Local Secret Management (Required)
|
||||||
|
|
||||||
|
ZeroClaw supports layered secret management for local development and CI hygiene.
|
||||||
|
|
||||||
|
### Secret Storage Options
|
||||||
|
|
||||||
|
1. **Environment variables** (recommended for local development)
|
||||||
|
- Copy `.env.example` to `.env` and fill in values
|
||||||
|
- `.env` files are Git-ignored and should stay local
|
||||||
|
- Best for temporary/local API keys
|
||||||
|
|
||||||
|
2. **Config file** (`~/.zeroclaw/config.toml`)
|
||||||
|
- Persistent setup for long-term use
|
||||||
|
- When `secrets.encrypt = true` (default), secret values are encrypted before save
|
||||||
|
- Secret key is stored at `~/.zeroclaw/.secret_key` with restricted permissions
|
||||||
|
- Use `zeroclaw onboard` for guided setup
|
||||||
|
|
||||||
|
### Runtime Resolution Rules
|
||||||
|
|
||||||
|
API key resolution follows this order:
|
||||||
|
|
||||||
|
1. Explicit key passed from config/CLI
|
||||||
|
2. Provider-specific env vars (`OPENROUTER_API_KEY`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, ...)
|
||||||
|
3. Generic env vars (`ZEROCLAW_API_KEY`, `API_KEY`)
|
||||||
|
|
||||||
|
Provider/model config overrides:
|
||||||
|
|
||||||
|
- `ZEROCLAW_PROVIDER` / `PROVIDER`
|
||||||
|
- `ZEROCLAW_MODEL`
|
||||||
|
|
||||||
|
See `.env.example` for practical examples and currently supported provider key env vars.
|
||||||
|
|
||||||
|
### Pre-Commit Secret Hygiene (Mandatory)
|
||||||
|
|
||||||
|
Before every commit, verify:
|
||||||
|
|
||||||
|
- [ ] No `.env` files are staged (`.env.example` only)
|
||||||
|
- [ ] No raw API keys/tokens in code, tests, fixtures, examples, logs, or commit messages
|
||||||
|
- [ ] No credentials in debug output or error payloads
|
||||||
|
- [ ] `git diff --cached` has no accidental secret-like strings
|
||||||
|
|
||||||
|
Quick local audit:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Search staged diff for common secret markers
|
||||||
|
git diff --cached | grep -iE '(api[_-]?key|secret|token|password|bearer|sk-)'
|
||||||
|
|
||||||
|
# Confirm no .env file is staged
|
||||||
|
git status --short | grep -E '\.env$'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional Local Secret Scanning
|
||||||
|
|
||||||
|
For extra guardrails, install one of:
|
||||||
|
|
||||||
|
- **gitleaks**: [GitHub - gitleaks/gitleaks](https://github.com/gitleaks/gitleaks)
|
||||||
|
- **truffleHog**: [GitHub - trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog)
|
||||||
|
- **git-secrets**: [GitHub - awslabs/git-secrets](https://github.com/awslabs/git-secrets)
|
||||||
|
|
||||||
|
This repo includes `.githooks/pre-commit` to run `gitleaks protect --staged --redact` when gitleaks is installed.
|
||||||
|
|
||||||
|
Enable hooks with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
```
|
||||||
|
|
||||||
|
If gitleaks is not installed, the pre-commit hook prints a warning and continues.
|
||||||
|
|
||||||
|
### What Must Never Be Committed
|
||||||
|
|
||||||
|
- `.env` files (use `.env.example` only)
|
||||||
|
- API keys, tokens, passwords, or credentials (plain or encrypted)
|
||||||
|
- OAuth tokens or session identifiers
|
||||||
|
- Webhook signing secrets
|
||||||
|
- `~/.zeroclaw/.secret_key` or similar key files
|
||||||
|
- Personal identifiers or real user data in tests/fixtures
|
||||||
|
|
||||||
|
### If a Secret Is Committed Accidentally
|
||||||
|
|
||||||
|
1. Revoke/rotate the credential immediately
|
||||||
|
2. Do not rely only on `git revert` (history still contains the secret)
|
||||||
|
3. Purge history with `git filter-repo` or BFG
|
||||||
|
4. Force-push cleaned history (coordinate with maintainers)
|
||||||
|
5. Ensure the leaked value is removed from PR/issue/discussion/comment history
|
||||||
|
|
||||||
|
Reference: [GitHub guide: removing sensitive data from a repository](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository)
|
||||||
|
|
||||||
## Collaboration Tracks (Risk-Based)
|
## Collaboration Tracks (Risk-Based)
|
||||||
|
|
||||||
To keep review throughput high without lowering quality, every PR should map to one track:
|
To keep review throughput high without lowering quality, every PR should map to one track:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue