1. Docs
  2. Security model
GitHub

Security model

The trust model as this release implements it, and what is not built yet.

Reporting a vulnerability

Email security@innerwall.dev with reproduction steps, the affected component and the impact as you understand it. Do not open a public issue for a vulnerability before a fix is released. The full policy is in SECURITY.md.

The agent

  • The agent runs as root because programming the host firewall requires it. Everything else is minimized: a static binary, no listening ports (it only dials out), no runtime downloads and no self-update (ADR-0011).
  • Losing the control plane never changes enforcement on any host. See Fail static.
  • Host operators outrank the platform: root on the host can always remove enforcement with the local kill switch. Root on that host is inside the trust boundary, so reports that assume its compromise are outside the model.

Workload identity

  • Enrollment is token-gated, with no trust-on-first-use window (ADR-0004, ADR-0016). Provisioning tokens are scoped to labels, expire, can be revoked, and are stored only as hashes.
  • The agent generates its keypair on the host, and the private key never leaves it. A signing request contributes only its public key.
  • A workload’s identity is one URI SAN, innerwall://workload/<uuid>, with a UUID the control plane assigns. Labels and other mutable facts live in the registry, never in the certificate.
  • Credentials live 24 hours by default and are renewed automatically, over mutual TLS, when less than a third of their lifetime remains (ADR-0016).

The operator surface

  • The operator surface is one TLS-only listener, separate from the agent listener (ADR-0021).
  • This release has one operator. The password is set only from the command line on the host and stored as an argon2id hash.
  • A browser session is a cookie that is HttpOnly, Secure and SameSite=Lax. Automation uses operator tokens, stored only as digests.
  • A request that is not a read is refused when the browser marks it cross-origin; that is the cross-site write defense. Login attempts are throttled per source address.

The control plane

  • Every authored policy object is versioned, and every write is conditioned on the version its author read. Enforcement-mode changes are recorded as intents.
  • The signing key is not stored in Postgres. The authority directory is configuration, provisioned identically on every replica (ADR-0017).

Revocation in this release

Revocation is short-lived credentials and token revocation. A revoked provisioning token enrolls nothing further, and an enrolled workload is locked out when its credential lapses. Immediate lockout of an enrolled workload (a deny-list of workload identities) and detection of one identity presented by two hosts are not built; both are on the roadmap.

Supply chain

Builds are static. Each release checksums every archive, and the release workflow signs the checksum file and the control-plane image keyless: no signing key exists, and the certificate names that workflow, at the release’s tag, as the signer. Versioning and install shows how to verify both with cosign before installing. Every authored commit carries a DCO sign-off (ADR-0013), and third-party code bundled in the console ships with its license texts.