Only the latest release receives security fixes. Run contextzip update (or pip install --upgrade contextzip) to get it.
| Version | Supported |
|---|---|
| Latest 0.4.x | ✅ |
| Older | ❌ |
Please do not report security vulnerabilities through public GitHub issues.
Email akadeepesh@gmail.com with:
- a description of the vulnerability,
- steps to reproduce it,
- the potential impact,
- a suggested fix (optional).
You can expect an acknowledgement within 48 hours and a full response within 7 days. If the vulnerability is confirmed, a fix will be released as soon as possible and you will be credited in the release notes, unless you'd rather stay anonymous.
contextzip is a local CLI tool. It reads your project and writes ZIP archives that you then choose to upload to an AI tool. contextzip never uploads the archive itself.
Packaging, apply-zip, watch and the config UI work entirely offline. Only two features make network requests, and only when you use them:
| Feature | What is sent | Where |
|---|---|---|
contextzip --prompt "…" |
Your prompt, plus the paths and sizes of files that already passed the exclusion rules. File contents are never sent. | Google Gemini API (generativelanguage.googleapis.com) |
contextzip update |
A request for the latest version number | PyPI (pypi.org) |
There is no telemetry, analytics or background "phone home".
contextzip protects secrets in three layers:
-
Secret files are excluded by default.
.envand.env.*, private keys (*.pem,*.key,id_rsa,id_ed25519, …), keystores,.npmrc/.netrc/.pypirc/.pgpass, Docker auth config, AWS credentials, service-account and*credentials*.jsonfiles, kubeconfigs and Terraform state are left out of every run, including--git-changes. Including a folder (contextzip include src/) doesn't bring back the secret files inside it. -
Secret files you include on purpose are always redacted. You can bring one of these files back by naming it explicitly (
contextzip include .env), listing it underalways_includein.contextzip/config.json, or ticking it incontextzip config --ui. This is useful when you want the AI to see which environment variables your app expects. Such a file is never zipped as-is, whatever your other settings say:- In
.envfiles every key, comment and blank line is kept, and every value is replaced with[REDACTED]. - Other secret files are scanned for private-key blocks, API keys, tokens and similar values, and the matches are replaced with
[REDACTED]. - A secret file that isn't text (for example
.p12or.jks) can't be redacted, so it is left out and listed in the report.
- In
-
Optional scanning of ordinary files. Set
"limits": {"redact_secrets": true}to scan every included text file for hardcoded secrets (AWS, Google, GitHub, Slack, Stripe, Anthropic and OpenAI keys, JWTs, private-key blocks andpassword = "…"-style assignments) and mask them in the ZIP copy. Your files on disk are never modified.
Every run writes a report next to the ZIP listing what was redacted and what was left out.
Redaction is best-effort. It catches known formats, not every possible secret. A file other than .env, such as a private key in an unusual format, can still slip through the pattern scan. Before uploading an archive from a sensitive project, preview it with contextzip --dry-run --verbose and check the report.
- Path handling. Files outside the project directory are never included, and dangling or looping symlinks are skipped.
- Local manifests. The hashes
apply-zipuses are stored next to the ZIP on your machine, never inside it. apply-zipremoves files only with your explicit OK — the old copy of a moved file, or a deletion the AI requested — never one you've changed since the snapshot, and never because of--yesalone. It asks before overwriting anything you've changed since the ZIP was made.- Snapshots stay local.
.contextzip/snapshots/keeps copies of the ZIPs you sent (already filtered and redacted, exactly as uploaded) so replies can be merged; it's gitignored and pruned automatically. - Config UI.
contextzip config --uibinds to127.0.0.1only, requires a random one-time session token on every request and shuts itself down after saving or after a period of inactivity. - Review page.
contextzip apply-zip --reviewuses the same model:127.0.0.1only, a random session token on every request, no outbound requests, and it shuts down when you apply, cancel or leave it idle. The page only sends your decisions back; the CLI does the writing. - Secrets on the way back. Files that were redacted when packaged are merged against the redacted copy when an AI returns them, so
apply-zipnever writes a[REDACTED]placeholder over a real value. Entries in a returned ZIP that point outside the project (absolute paths, drive letters,..) makeapply-ziprefuse the whole ZIP. - API key storage. Your Gemini key is stored in your personal config (
~/.config/contextzip/config.json, or%APPDATA%\contextzip\config.jsonon Windows), never in the project. You can provide it with theGEMINI_API_KEYenvironment variable instead.
In scope:
- secrets ending up in an archive despite the rules above,
- path traversal or symlink escapes when packaging or applying a ZIP,
apply-zipwriting outside the project directory,- the config UI or review page being reachable or controllable by another process or site,
- network requests beyond those listed above.
Out of scope: what an AI tool does with an archive after you upload it, and secrets inside files you have chosen to include that the redaction patterns don't recognise. Please still report the second kind if you think a common format should be covered.