mirror of
https://github.com/akadeepesh/contextzip.git
synced 2026-10-20 08:36:20 +02:00
docs: document secret-file redaction and refresh security policy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
550c5462a1
commit
8052318063
@@ -921,3 +921,39 @@ This project uses [Semantic Versioning](https://semver.org/).
|
||||
clipboard through, which GNOME and KDE do. A Wayland-only setup without
|
||||
XWayland needs `wl-clipboard` (`wl-copy`) installed; otherwise contextzip
|
||||
opens the folder and tells you what to install.
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- **A `.env` you deliberately include now has every value redacted.**
|
||||
Secret files (`.env`, private keys, credential files, Terraform state and
|
||||
so on) are still left out by default. You can still bring one back with
|
||||
`always_include` in `.contextzip/config.json` or with
|
||||
`contextzip config --ui`, so the AI can see which variables your app
|
||||
expects. It is now never zipped as-is:
|
||||
- `.env` / `.env.*` files keep every key, comment and blank line, but
|
||||
every value becomes `[REDACTED]`. Multi-line quoted values collapse to
|
||||
one redacted line, and any line that isn't `KEY=value` is redacted
|
||||
whole.
|
||||
- Any other secret file gets the secret-pattern scan (private-key blocks,
|
||||
API keys, tokens and so on).
|
||||
- A secret file that isn't text (`.p12`, `.jks` and so on) can't be
|
||||
redacted, so it is left out and listed in the report.
|
||||
- This happens whatever `limits.redact_secrets` says and whatever the
|
||||
file's size. It applies to normal runs, `--git-changes`, `--prompt`,
|
||||
the `source-files.zip` inside `contextzip watch`'s debug package, and
|
||||
the Python API.
|
||||
- The scan report now groups repeated redactions (`.env value x3`).
|
||||
|
||||
### Fixed
|
||||
- **The report didn't list files that couldn't be written to the ZIP**,
|
||||
even though the CLI said "see report". They now appear under "Left out
|
||||
of the ZIP" with the reason.
|
||||
|
||||
### Developer notes
|
||||
- `rules/base.py` has a new `SECRET_PATTERNS` list. `PATTERNS` still
|
||||
contains it, so the default exclusions are unchanged.
|
||||
- New in `contextzip.redact`: `is_sensitive_path()`, `is_env_file()`,
|
||||
`redact_env()` and `redact_sensitive_file()`.
|
||||
|
||||
@@ -28,7 +28,7 @@ contextzip does all of that for you. Run it from your project root and it:
|
||||
|
||||
1. **Detects your stack** (Node.js, Next.js, Python, Django, FastAPI, Rust, Go, Ruby, monorepos included).
|
||||
2. **Excludes the noise**: dependencies, build output, caches, binaries, logs, and anything in your `.gitignore`.
|
||||
3. **Never packages secrets**: `.env` files, private keys, cloud credentials and Terraform state are always left out.
|
||||
3. **Keeps secrets out**: `.env` files, private keys, cloud credentials and Terraform state are left out by default. If you include your `.env` on purpose, its values are redacted.
|
||||
4. **Puts the ZIP on your clipboard** as a real file, so you can paste it straight into Claude, ChatGPT, Gemini or any other upload box.
|
||||
|
||||
When the AI sends changed files back, `contextzip apply-zip` writes them into your project safely, and warns you before touching anything you've edited since.
|
||||
@@ -271,7 +271,19 @@ These patterns apply to **every** project, whatever its stack or `.gitignore` sa
|
||||
- **Binaries & media:** executables, shared libraries, images, video, audio and archives
|
||||
- **Project boilerplate:** `CHANGELOG`, `LICENSE`, `CONTRIBUTING`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, GitHub issue/PR templates
|
||||
|
||||
The only way to bring one of these back is to list it explicitly under `always_include` in the project config. CLI flags and `.gitignore` can't override them. For extra safety, set `limits.redact_secrets: true` to mask API keys, tokens, JWTs and private-key blocks that are hardcoded inside files that *do* get included.
|
||||
CLI flags and `.gitignore` can't override these. To bring one back, list it under `always_include` in the project config or tick it in `contextzip config --ui`.
|
||||
|
||||
**Secret files you include on purpose are always redacted.** If you include your `.env` so the AI can see which variables your app expects, every key and comment is kept but every value becomes `[REDACTED]`:
|
||||
|
||||
```bash
|
||||
# .env on disk # .env in the ZIP
|
||||
DATABASE_URL=postgres://u:pw@db/app DATABASE_URL=[REDACTED]
|
||||
export API_KEY="sk-live-…" # prod export API_KEY="[REDACTED]" # prod
|
||||
```
|
||||
|
||||
Other secret files (private keys, credential files) get a secret-pattern scan. Binary ones like `.p12` can't be redacted, so they're left out. All of this happens whatever your other settings say.
|
||||
|
||||
For extra safety, set `limits.redact_secrets: true` to also mask API keys, tokens, JWTs and private-key blocks hardcoded inside ordinary files that get included. Every run's report lists what was redacted.
|
||||
|
||||
> **Tip:** before sharing a sensitive project, run `contextzip --dry-run --verbose` to see exactly what will go into the ZIP.
|
||||
|
||||
@@ -333,6 +345,7 @@ For full signatures, see [contextzip.vercel.app/cli#python-api](https://contextz
|
||||
- `contextzip update` asks PyPI for the latest version number.
|
||||
- **No telemetry.** Nothing is collected or phoned home.
|
||||
- **Manifests stay local.** `apply-zip` manifests are written next to the ZIP and never inside it.
|
||||
- **Secrets are excluded or redacted.** See [What is always excluded](#what-is-always-excluded).
|
||||
|
||||
Found a vulnerability? Please follow [SECURITY.md](https://github.com/akadeepesh/contextzip/blob/main/SECURITY.md) and report it privately rather than in a public issue.
|
||||
|
||||
|
||||
+59
-16
@@ -1,32 +1,75 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
## Supported versions
|
||||
|
||||
Only the latest release receives security fixes. Run `contextzip update` (or `pip install --upgrade contextzip`) to get it.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | --------- |
|
||||
| 0.1.x | ✅ |
|
||||
| Latest 0.4.x | ✅ |
|
||||
| Older | ❌ |
|
||||
|
||||
Older versions will not receive security patches. Always use the latest release.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
## Reporting a vulnerability
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
If you discover a security vulnerability, email **akadeepesh@gmail.com** with:
|
||||
Email **akadeepesh@gmail.com** with:
|
||||
|
||||
- A description of the vulnerability
|
||||
- Steps to reproduce it
|
||||
- The potential impact
|
||||
- Any suggested fix (optional)
|
||||
- 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**.
|
||||
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.
|
||||
|
||||
If the vulnerability is confirmed, a patch will be released as soon as possible and you will be credited in the release notes (unless you prefer to remain 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`. CLI flags and `.gitignore` can't bring them back.
|
||||
|
||||
2. **Secret files you include on purpose are always redacted.** You can bring one of these files back by 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` never deletes files** and asks before overwriting anything you've changed since the ZIP was made.
|
||||
- **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.
|
||||
- **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
|
||||
|
||||
contextzip is a local CLI tool that reads your filesystem and creates ZIP archives. It does not make network requests, collect data, or transmit anything anywhere. The primary security considerations are:
|
||||
In scope:
|
||||
|
||||
- **Path traversal** — ensuring files outside the project directory are not included
|
||||
- **Symlink handling** — dangling or malicious symlinks are skipped, not followed blindly
|
||||
- **Secrets in archives** — `.env` and key files are excluded by default, but users should always run `--dry-run` before sharing archives containing sensitive projects
|
||||
- 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 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.
|
||||
|
||||
Reference in New Issue
Block a user