Skip to content

Security: akadeepesh/contextzip

Security

SECURITY.md

Security Policy

Supported versions

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 ❌

Reporting a vulnerability

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.

What contextzip does with your code

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.

Network access

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".

Secrets

contextzip protects secrets in three layers:

  1. Secret files are excluded by default. .env and .env.*, private keys (*.pem, *.key, id_rsa, id_ed25519, …), keystores, .npmrc / .netrc / .pypirc / .pgpass, Docker auth config, AWS credentials, service-account and *credentials*.json files, 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.

  2. 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 under always_include in .contextzip/config.json, or ticking it in contextzip 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 .env files 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 .p12 or .jks) can't be redacted, so it is left out and listed in the report.
  3. 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 and password = "…"-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.

Other safeguards

  • Path handling. Files outside the project directory are never included, and dangling or looping symlinks are skipped.
  • Local manifests. The hashes apply-zip uses are stored next to the ZIP on your machine, never inside it.
  • apply-zip removes 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 --yes alone. 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 --ui binds to 127.0.0.1 only, 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 --review uses the same model: 127.0.0.1 only, 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-zip never writes a [REDACTED] placeholder over a real value. Entries in a returned ZIP that point outside the project (absolute paths, drive letters, ..) make apply-zip refuse the whole ZIP.
  • API key storage. Your Gemini key is stored in your personal config (~/.config/contextzip/config.json, or %APPDATA%\contextzip\config.json on Windows), never in the project. You can provide it with the GEMINI_API_KEY environment variable instead.

Scope

In scope:

  • secrets ending up in an archive despite the rules above,
  • path traversal or symlink escapes when packaging or applying a ZIP,
  • apply-zip writing 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.

There aren't any published security advisories