Add scripts/gen-api-key.py to generate/rotate the served-API bearer key - #37
Conversation
`CULTURE_VLLM_API_KEY` gates the vLLM API (and is mandatory before exposing it via `model tunnel`), but there was no first-class way to mint it. This adds a small, stdlib-only generator that: - creates the key with `secrets.token_urlsafe` and NEVER hardcodes a secret, so the script is safe in the open-source repo; the key only lands in the gitignored deployment `.env` (written 0o600); - hides the key by default (no echo into logs/scrollback); `--show` prints it, `--force` rotates an existing key; - resolves the deployment dir like the `model` CLI (`--dir` > $MODEL_GEAR_DIR > ~/.model-gear), and runs from a wheel install (no model_gear import). Tests cover set/rotate/refuse-overwrite/missing-dir/show/no-leak/0o600. README "Expose the API" section now points at it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
/agentic_review |
Code Review by Qodo
Context used✅ Compliance rules (platform):
35 rules 1.
|
Triage of Qodo findings on #37: - #1 (rule 796119): CHANGELOG `~/.model-gear` → `$HOME/.model-gear`. (The .py --help/docstring keep `~/.model-gear` to match the repo-wide CLI help text; Qodo's docs/config rule only flags the markdown.) - #2 (unreadable/dir .env crash): main() preflights that .env is a regular file and wraps the read/update/write in try/except OSError -> EXIT_ENV_ERROR, matching _read_key()'s graceful degradation. - #3 (under-scoped bump): a new documented capability is a minor, not a patch — 0.18.1 -> 0.19.0. - #4 (unhandled chmod): os.chmod is now best-effort (try/except OSError with a note), so a chmod-unsupported FS doesn't crash after a successful write. - #5 (unvalidated --bytes): reject `< 16` (128-bit floor) with a user error before generating, so no weak key or token_urlsafe stack trace. New tests: too-few-bytes and non-regular-file .env. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed the summary-only findings in 154b0bb: #3 — version bump under-scoped. Agreed: a new documented capability is a minor, not a patch. Bumped 0.18.1 → 0.19.0 (pyproject + CHANGELOG + uv.lock). #4 — unhandled chmod failure. #5 — unvalidated Gate after the fixes: 263 tests pass, black/isort/flake8 clean, bandit 0/0/0, markdownlint 0,
|
|



PR Summary by Qodo
Add gen-api-key script to mint/rotate CULTURE_VLLM_API_KEY safely
✨ Enhancement🧪 Tests📝 Documentation⚙️ Configuration changes🕐 20-40 MinutesWalkthroughs
User Description
What
Adds
scripts/gen-api-key.py— generate or rotate the bearer key(
CULTURE_VLLM_API_KEY) that gates the served vLLM API.Why
CULTURE_VLLM_API_KEYis the gate for exposing the API publicly viamodel tunnel(#35), but there was no first-class, repeatable way to mint it — leavingad-hoc
openssl randone-liners that risk leaking the secret into shell historyor committed config.
Open-source-safe by construction
secretsmodule and is neverhardcoded — the script carries no secret, so it's safe in this public repo.
.env, written0o600.--showprints it,--forcerotates an existing key.
modelCLI (--dir→$MODEL_GEAR_DIR→~/.model-gear); stdlib-only, nomodel_gearimport, so it runs from a wheelinstall too.
Tests
tests/test_gen_api_key.pycovers set-when-absent, refuse-overwrite-without-force,--forcerotate, missing-dir env error,--showmatches.env, no-leak bydefault, and
0o600perms.Docs
README "Expose the API from anywhere" section now points at the script. Version
bumped 0.18.0 → 0.18.1.
AI Description
Diagram
graph TD U["Operator"] --> S["scripts/gen-api-key.py"] --> E[("Deployment .env")] E --> M["model serve --apply"] --> V["vLLM API"] V --> T["model tunnel"] --> C["Public client"]High-Level Assessment
The following are alternative approaches to this PR:
1. Add a first-class `model api-key` subcommand
2. Generate the key during `model init --apply` (opt-in)
model tunnelinitmay be undesirable to mutate secrets automatically without explicit intent3. Reuse `model_gear.runtime._compose.resolve_deployment_dir` in the script
Recommendation: The standalone stdlib-only script is a good fit for a public repo and wheel installs: it keeps secret generation isolated, avoids accidental printing, and writes only into the gitignored
.envwith0600. If this workflow becomes central for operators, consider later adding amodel api-keysubcommand that wraps the same logic for better discoverability and consistent CLI ergonomics, while keeping the script as a thin shim (or documented fallback).File Changes
Enhancement (1)
Tests (1)
Documentation (2)
Other (1)