Security model
mipo is designed for environments where every component must be auditable. This reference covers the scanner supply chain, the two authentication boundaries, access control, transport security, backups, and the audit guarantees.
Scanner supply chain
The scanner is a single statically-linked Go binary built entirely from the standard library — zero
third-party dependencies and no entries in go.mod. The whole source fits in one directory and
can be audited in a sitting. There is no auto-update channel and no telemetry: every binary on your network
was placed there deliberately, and upgrades are a manual operator action.
Releases are signed with Ed25519: the private key lives only in the builder's signing
environment — CI for mipo-built releases; organizations that build from source sign in their own build
process (never in the repo, never in a container) — and the public key (scanner.pub) is committed to the source
repository so hosts pin it from a channel the manager cannot touch. Signature verification is
mandatory by default (MIPO_REQUIRE_SIG=1): install.sh /
upgrade.sh exit with an error if mipo-scanner.sig or the pinned
/etc/mipo/scanner.pub is absent — fail-closed, not warn-and-continue. A compromised manager can
serve a tampered binary with a matching hash — it cannot forge the signature. For full protection against
a compromised manager, obtain install.sh and scanner.pub from an independent
channel — the mipo source checkout or the release bundle your operator received (public publication of the
repository is pending) — not from the manager, which serves both. Set MIPO_REQUIRE_SIG=0 only
in development or transition environments that have no signed artifacts. Organizations that build from
source sign with their own key and become their own signing authority.
Two authentication boundaries
Users authenticate to the manager with session cookies; scanners authenticate to ingest with a client
certificate (mutual TLS on :8443) plus a revocable API key. At provisioning the scanner host
generates the API key itself and sends only its hash, so the manager stores nothing that could be replayed.
At runtime the scanner presents the raw key to the mipo server in the X-API-Key header of each
request, inside the TLS connection; a key rotated later from the Scanners page is shown once, on the
success screen. Scanner keys can be bound to expected source IPs (address, CIDR, or ASN) and the ingest API
rejects and logs connections from unauthorized IPs.
Scanner identity (mTLS). Resolver identities (reverse-DNS workers) share this exact model —
the same token, key, certificate, binding and revocation path; only their work eligibility differs.
Scanners bootstrap on :443 with a one-time token plus
their API key, then run on :8443, a dedicated ingress that requires a client certificate on every
handshake. Each scanner generates its own private key on its host — the manager only signs a CSR — and its
30-day leaf renews in two phases without a restart. Revocation is application-layer (the certificate's status
and database validity window are checked per request; no CRL or OCSP), the signing CA is a numbered generation
with an orderly rollover and an emergency transition, and the fleet-wide policy moves one way from
migration to required behind a persisted readiness snapshot. See the
Scanners page and the
CA rollover guide.
Access control
RBAC is enforced at the API middleware layer using resource:action scopes — the GUI only
reflects what the API permits. A Day-0 owner account bootstraps the system and bypasses scope checks; every
user after that is least-privilege. External identity is supported via generic OIDC with an optional local
fallback.
Local accounts can enrol a TOTP second factor (six digits, 30-second step) with ten one-time recovery codes; repeated failures lock the challenge, and an admin can reset a user's MFA when a device is lost. The password policy is one rule set evaluated by the API and drawn as a live checklist under every new-password field (setup wizard, user creation, profile), so a password the checklist rejects is also rejected on the wire. Destructive, trust and credential endpoints — user and role changes, OIDC configuration, backup configuration, trigger and download, certificate activation, scanner creation, key rotation and deletion, the mTLS policy flip and CA rollover — additionally require step-up re-authentication: the caller re-proves their password and gains a ten-minute elevation window. This check is separate from RBAC and the owner's scope bypass does not apply to it.
Transport, backups, and audit
All external traffic is TLS-terminated at the edge, with self-signed certificates for day-one encryption and
optional ACME / Let's Encrypt issuance. Database backups can be encrypted at rest (AES-256, when an
encryption key is configured) and restore is an explicit, destructive operation run with the operator CLI
scripts/ops/restore.sh, which connects as the database owner; the setup-wizard restore exists
only where the manager is given owner credentials (development stacks) and is unavailable in the production
compose. A global interceptor records every state change to an append-only, tamper-evident audit
log with actor, timestamp, and field-level diffs.
Security properties
| Property | Detail |
|---|---|
| Stdlib-only scanner | The scanner is a Go static binary using only the standard library — a tiny, auditable supply chain. |
| Signed scanner binary | Release binaries are Ed25519-signed; the installer verifies the SHA-256 and signature and refuses to install on a mismatch. Build from source and sign with your own key if you prefer. |
| No auto-update | Scanners are deployed manually; there is no silent update channel to compromise. |
| No telemetry | mipo does not phone home; all data stays in your deployment. |
| Scanner mTLS identity | Every scanner presents a per-scanner client certificate on a dedicated :8443 ingress. The private key is generated on the scanner host (the manager only signs a CSR); 30-day leaves renew automatically, revocation is enforced at the application layer, the issuing CA can be rolled over, and each scanner can additionally be bound to a source IP, CIDR, or ASN. |
| RBAC + OIDC/SSO | Path-based scopes such as /scans:execute with four built-in roles; external IdP via generic OIDC with optional local fallback. |
| MFA + step-up | TOTP second factor with recovery codes for local accounts, enforceable deployment-wide. Destructive, trust, and credential endpoints additionally require a fresh re-authentication within the last 10 minutes — even for the owner. |
| Password policy + lockout | One enforced password policy drives the live checklist in every form and the API validation; 10 consecutive failures lock an account for 15 minutes. |
| Owner bootstrap | Day-0 setup creates a local owner that bypasses scope checks (but not step-up); everything after is least-privilege. |
| TLS everywhere | HTTPS at the edge with ACME/Let’s Encrypt issuance from certificate profiles, reusable DNS credential sets, an auditable issuance-run history, and alarms on renewal failure. |
| Encrypted backups | Database backups can be AES-256-encrypted at rest. Restore is an explicit, destructive operation run with the operator CLI scripts/ops/restore.sh, which connects as the database owner; the setup-wizard restore exists only where the manager holds owner credentials (development stacks) and is unavailable in the production compose. |
| Signed execution receipts | Every scan and DNS job ends with a receipt signed by the scanner that ran it, so "we scanned and nothing changed" is distinguishable from "we never scanned". |
| Append-only evidence | Audit events, scan results, job receipts, and DNS observations live in six tables no application role can update or delete; a database trigger blocks mutation even on a privileged path. |
| Audit logs | A global interceptor records every state change to an append-only, hash-chained log with a built-in integrity check. |
What mipo does not do
- No compliance guarantee — mipo collects evidence; auditors determine control satisfaction.
- No auto-patching — mipo reports exposure, it does not remediate hosts.
- No silent scanner updates — scanner upgrades are a deliberate, manual operator action.