mitmania is the data plane: a fleet of interchangeable nodes that carry and enforce traffic. It has no opinion about why a rule says what it says, and no built-in notion of who's allowed to change one — that's a control plane's job, and mitmania doesn't ship one. Anything that can write to Storage or call the control socket qualifies: a human with curl, a GitOps reconciler, a CMDB exporter, a Terraform provider.
Why this split is real, not aspirational¶
- Rule selection is a pure function of network facts. Which file governs a connection depends only on the client's address — never on an authenticated principal or any application-layer identity.
auth.http_proxyattributes a connection (the principal is logged) but never selects its rules. See identity, rules & phases. - Zero per-node state. A node's entire input is
{storage URL, clusterKey, listener addresses}. Rule files are just blobs inStorage; nothing is baked into a node beyond that. - Convergence without a sync protocol. Nodes pick up new state through
Storage's own change-versioning — no gossip, no leader, no bespoke RPC a control plane has to speak. Write the state; the fleet converges. See distributed operation. - One narrow, stable interface. The
Storagekeyspace (ca/,leaf/,rules/) and the control socket (PUT /rules/{ip},PUT /rules/default,DELETE /cache) are the whole surface. Nothing else needs to know mitmania exists.
The one deferral seam¶
Outcalls (webhook, header.fetch) let a rule ask an external broker for a per-request decision or credential — the single place mitmania defers a real-time decision to something else, and it's deliberately bounded: no retries, fail-closed by default, validated by actually calling the broker at load time. This is the data plane calling out to a policy control plane mid-request, not a backdoor into rule selection. See outcalls (brokers).
Next: drive a broker as your policy control plane, or the rule-file schema if you're the one writing the state.