diff --git a/README.md b/README.md index c460f2d..b727cf5 100644 --- a/README.md +++ b/README.md @@ -40,14 +40,31 @@ Then add `inputs.claudebox.packages.${system}.default` to your `environment.syst | `--gc` | Remove stale per-project instance dirs and exit | | `--` | Pass remaining args to Claude Code | -## Extra env vars +## Env vars -Pass additional host variables into the sandbox: +**Env files (preferred)** — define vars without polluting your shell: +`~/.claudebox/env` — global, loaded on every launch: +```bash +ANTHROPIC_API_KEY=sk-ant-... +MY_GLOBAL_VAR=value +``` + +`/.claudebox.env` — per-project, loaded when present: +```bash +DATABASE_URL=postgres://localhost/myapp +SOME_PROJECT_VAR=value +``` + +Add `.claudebox.env` to your `.gitignore` if it contains secrets. + +**Pass-through** — inject host vars already set in your shell: ```bash CLAUDEBOX_EXTRA_ENV=MY_VAR,OTHER_VAR claudebox ``` +All injected vars appear in the `[+]` section of the env audit. + ## How it works ``` diff --git a/claudebox.sh b/claudebox.sh index 73d1535..0b578fb 100644 --- a/claudebox.sh +++ b/claudebox.sh @@ -253,20 +253,29 @@ ENV_ARGS=( --setenv SHELL "$SANDBOX_BASH" --setenv TMPDIR /tmp --setenv XDG_RUNTIME_DIR /tmp - --setenv NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt - --setenv SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt ) # Populate sandbox audit data -AUDIT_SANDBOX_KEYS=(HOME USER PATH SHELL TMPDIR XDG_RUNTIME_DIR NIX_SSL_CERT_FILE SSL_CERT_FILE) +AUDIT_SANDBOX_KEYS=(HOME USER PATH SHELL TMPDIR XDG_RUNTIME_DIR) AUDIT_SANDBOX_VALS[HOME]="$HOME" AUDIT_SANDBOX_VALS[USER]="$USER" AUDIT_SANDBOX_VALS[PATH]="$SANDBOX_PATH" AUDIT_SANDBOX_VALS[SHELL]="$SANDBOX_BASH" AUDIT_SANDBOX_VALS[TMPDIR]="/tmp" AUDIT_SANDBOX_VALS[XDG_RUNTIME_DIR]="/tmp" -AUDIT_SANDBOX_VALS[NIX_SSL_CERT_FILE]="/etc/ssl/certs/ca-certificates.crt" -AUDIT_SANDBOX_VALS[SSL_CERT_FILE]="/etc/ssl/certs/ca-certificates.crt" + +# SSL cert path: prefer host NIX_SSL_CERT_FILE (NixOS sets this to a nix store path); +# fall back to /etc/ssl/certs/ca-certificates.crt for non-NixOS hosts. +_SSL_CERT_DEFAULT="/etc/ssl/certs/ca-certificates.crt" +_NIX_SSL_CERT="${NIX_SSL_CERT_FILE:-$_SSL_CERT_DEFAULT}" +_SSL_CERT="${SSL_CERT_FILE:-$_NIX_SSL_CERT}" +ENV_ARGS+=( + --setenv NIX_SSL_CERT_FILE "$_NIX_SSL_CERT" + --setenv SSL_CERT_FILE "$_SSL_CERT" +) +AUDIT_SANDBOX_KEYS+=(NIX_SSL_CERT_FILE SSL_CERT_FILE) +AUDIT_SANDBOX_VALS[NIX_SSL_CERT_FILE]="$_NIX_SSL_CERT" +AUDIT_SANDBOX_VALS[SSL_CERT_FILE]="$_SSL_CERT" # Allowlisted host vars -- only pass if set on host HOST_ALLOWLIST=(TERM EDITOR LANG LC_ALL ANTHROPIC_API_KEY) @@ -291,6 +300,32 @@ if [[ -v CLAUDEBOX_EXTRA_ENV ]]; then done fi +# Env files: ~/.claudebox/env (global) and /.claudebox.env (per-project) +# Format: KEY=VALUE lines; blank lines and lines starting with # are ignored. +load_env_file() { + local file="$1" + [[ -f "$file" ]] || return 0 + while IFS= read -r line || [[ -n "$line" ]]; do + # strip leading whitespace, skip blanks and comments + line="${line#"${line%%[! ]*}"}" + [[ -z "$line" || "$line" == '#'* ]] && continue + # require KEY=VALUE form + [[ "$line" != *=* ]] && continue + local key="${line%%=*}" + local val="${line#*=}" + # strip optional surrounding quotes from value + if [[ "$val" == '"'*'"' || "$val" == "'"*"'" ]]; then + val="${val:1:${#val}-2}" + fi + ENV_ARGS+=(--setenv "$key" "$val") + AUDIT_EXTRA_KEYS+=("$key") + AUDIT_EXTRA_VALS[$key]="$val" + done < "$file" +} + +load_env_file "$HOME/.claudebox/env" +load_env_file "$CANONICAL_ROOT/.claudebox.env" + # Env audit display (D-01, D-02, D-03, D-04, D-07, UX-01) print_audit() { echo "${BOLD}${CYAN}=== Sandbox Environment ===${RESET}" >&2