Repository navigation
Contributing
git clone https://github.com/metalayerlab/mitm-proxy && cd mitm-proxy
uv sync # Python >= 3.13: uv fetches it if needed
uv tool install pre-commit && pre-commit install -t pre-commit -t commit-msg
uv run pytest # all green before you start- Branch from
main:feat/<topic>ordev/<topic>. Pushes build:<branch>images. - Non-trivial change (a new feature or dependency, or a change to a public interface): write a design record first, and get it approved.
- Open a PR against
mainwith a Conventional Commit title (feat: add retry to uploads). It becomes the squash commit and the CHANGELOG line: see Release Process. - CI must be green: tests, lint, types, secret scan, manifests, and the wiki checks.
- A code owner reviews (review checklist), then squash-merge.
Never edit CHANGELOG.md or the version, and never push tags: release-please does that.
- ruff (lint + format, line length 100) and mypy
--strictdecide formatting and typing. Don't argue with them in review. - Comments explain why. Logging goes through
logging; only the CLI prints. - Settings go through
config.SETTINGS. Secrets come from_FILE, and are never logged. - Prefer the standard library and existing dependencies. Justify every new one in the PR.
- One event loop, no threads. Everything is asyncio. Work that blocks the loop (CPU-heavy code, blocking I/O) stalls the whole proxy, in middleware too.
-
Never background a middleware hook. The pipeline awaits each hook in line;
asyncio.create_taskaround one breaks backpressure. A test enforces it. -
Protocol layers stay protocol layers.
h1.pyandh2.pyproduceIncomingRequests andResponders; onlyexchange.pybuilds flows, runs middleware and picks framing. -
Errors: raise the types in
errors.py. Upstream failures become 502/504 responses, never exceptions out of a connection. Noassertinsrc/(ruff S101). -
Read the snapshot once. A connection uses the configuration snapshot current when it arrived; don't cache fields of
Configelsewhere. -
Never weaken verification or the allowlist "for testing": use
upstream.extra_ca_fileand test CAs instead.
AI assistants are welcome and expected, under the same rules as anyone else:
- They follow AGENTS.md. Each tool's own file (
CLAUDE.md,GEMINI.md,.github/copilot-instructions.md,.cursor/rules/) points there. - Kick-off prompts: docs/ai/prompts.md.
- The PR template asks how much was generated. Say so honestly: it tells the reviewer how closely to read.
- A human who understands the change approves every PR. "The AI wrote it" is never a reason to merge.
This wiki's source is docs/wiki/, in the repository. It's published to the GitHub wiki from main, so never edit the GitHub wiki directly: the next publish overwrites it.
- Code and docs change in the same PR. AGENTS.md's "Docs map" says which page goes with which code, and CI fails a PR that changes watched paths without touching
docs/wiki/. A reviewer, never the author, can add theno-docs-neededlabel when nothing user-visible changed. - The required pages and headings are in
docs/wiki/.standard.toml(template-owned). Add pages freely, and link each one from_Sidebar.md. - Tables between
<!-- generated:start/end -->markers come from the code: runuv run scripts/gen-wiki.py. - Link pages by name (
[Quick Start](Quick-Start)), and repo files by full URL. - Check locally:
python3 scripts/check-wiki.py.
Assistants pay for what they read in every session, so the instruction files are written for that:
-
AGENTS.mdholds the rules, tersely. The reasons live on these wiki pages. CI fails if AGENTS.md or a tool pointer file (CLAUDE.md,GEMINI.md, Copilot, Cursor) exceeds[context_budget]indocs/wiki/.standard.toml. That budget is template-owned: if it's genuinely too small, change it in project-template. - AGENTS.md's "Don't read" list (and the
Readdenies in.claude/settings.json) keep lock files, caches and generated output out of context. Add any large or generated path the project introduces. -
docs/design/README.mdindexes every design record, so an assistant reads one line per record instead of every record. CI checks the index is complete. - Pointer files only point: don't copy AGENTS.md content into them.
mitm-proxy | Async Python MITM proxy with a self-signed CA — HTTP/1.1 & HTTP/2, pluggable middleware for inspecting and rewriting traffic in flight.
GitHub • Releases • Issues • Changelog • Contributing
This wiki is generated from docs/wiki/ on every push to main: edits made here are overwritten. Change it with a pull request.
- 🔍 Intercept only the hosts you list; tunnel the rest untouched
- 🔀 HTTP/1.1 and HTTP/2 on both sides, bridged
- 🧩 Python middleware: inspect, rewrite, answer or deny
- 🔐 Its own root CA; origins always verified
- 📈 Prometheus metrics and a read-only status API