Security Controls #
The controls that bound what a mistake or a compromise can reach. Each is summarized here with the record that decided or built it; the design itself lives in those records.
Network segmentation #
The site network is split into zones by trust — management, trusted, platform, storage, tenant transit, IoT, IoT vendor and guest ( Network Segmentation).
- Default deny between zones. The core router allows only the inter-zone flows that are declared in inventory, and removes anything it did not declare ( CHG-0007)
- Joining a network is not authorization. A device on the IoT network still needs a credential for every service it uses ( ADR-0020)
- Guest is internet-only; IoT reaches the broker and the internet, not tenant workloads or management
Tenant isolation #
- A routing domain per tenant. Tenants are separated by VRF, not by a firewall rule — there is no route between them to filter ( ADR-0001)
- Every tenant-facing service is partitioned by the platform, not by the tenant. DNS updates are bound to the tenant’s own zone by server-side key metadata; MQTT topics are prefixed by the API; log partitions are selected by the proxy from routes the API wrote. A tenant cannot claim another tenant’s identity in a payload
- Tenants hold no substrate credential — one API token, nothing else ( ADR-0015)
Encryption #
| In transit | At rest | |
|---|---|---|
| The Deevnet API | TLS, site CA | registry secrets in OpenBao |
| MQTT broker | TLS only; no plaintext listener | — |
| Log store | TLS through an authenticating proxy | on the observability VM’s disk |
| Substrate secrets | — | ansible-vault in the inventory; OpenBao for runtime secrets ( ADR-0016) |
| Build secrets (the Proxmox token for Packer and the fabric) | TLS to OpenBao | OpenBao’s runtime copy; the inventory vault is authoritative. Never on disk on the Builder |
| Terraform state store | plain HTTP today — see the register | on one disk |
| Wi-Fi | WPA2 with a per-tenant key (PPSK) on the IoT SSID | — |
The site runs its own certificate authority; clients trust site-ca.pem rather than a public CA,
because nothing Deevnet serves is public.
Credentials #
- Automation uses one account, by key.
a_autoprov, SSH key only, passwordless sudo, provisioned by the image factory. No passwords in playbooks or inventory - Secrets are encrypted before they are committed, and a pre-commit hook refuses a plaintext vault
- A credential a change generates is encrypted, committed and pushed before its source is deleted. Losing one has cost a rebuild ( INC-0003)
- Build and deploy secrets are fetched per run, never rendered to a file. Packer and the substrate’s Terraform get their credentials from OpenBao, under a read-only identity with minute-long tokens. They go into the build’s own process environment, never onto a command line ( Build-Time Secrets, CHG-0026)
- Tenant credentials are issued, not chosen, and the tenant’s own state is their authoritative copy; the API keeps hashes where it can
- The long-term direction — short-lived credentials, identity held by the client — is the Secure Identity Standard