<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Substrate on Deevnet IoTaaS</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/</link><description>Recent content in Substrate on Deevnet IoTaaS</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/index.xml" rel="self" type="application/rss+xml"/><item><title>ADR-0037: Tenant Service Certificates</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0037-tenant-service-certificates/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0037-tenant-service-certificates/</guid><description>&lt;h1 id="adr-0037-a-tenant-service-ca-issues-server-certificates-for-names-in-a-tenants-own-zone">
 ADR-0037: A Tenant Service CA Issues Server Certificates for Names in a Tenant&amp;rsquo;s Own Zone
 &lt;a class="anchor" href="#adr-0037-a-tenant-service-ca-issues-server-certificates-for-names-in-a-tenants-own-zone">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted (2026-10-11): built by 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0047-tenant-service-certificates/">CHG-0047&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-10-11&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Where a tenant workload&amp;rsquo;s own service gets a server certificate that chains to the Deevnet Root CA: which CA signs it, who may ask, for which names, and what the certificate says. Not device identity (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0031-deevnet-pki/">ADR-0031&lt;/a> §6, unchanged), not who may reach a tenant&amp;rsquo;s service, and not revocation, which stays open.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0031-deevnet-pki/">ADR-0031&lt;/a>: answers its open question 2, and adds a third issuing CA to §3&amp;rsquo;s two.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Amends&lt;/strong>&lt;/td>
 &lt;td>ADR-0031 §3 (&amp;ldquo;Two issuing CAs per site&amp;rdquo;) and §4 (&amp;ldquo;ADR-0016 §3&amp;rsquo;s &lt;code>pki/&lt;/code> row becomes: issues tenant device certificates only&amp;rdquo;): OpenBao also issues tenant service certificates. 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/standards/certificates/">Certificates standard&lt;/a> 1.2 and the tables of §1, §2, §4, §5 and §6.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0012-iot-platform-api/">ADR-0012&lt;/a> (the Deevnet API), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0015-tenant-onboarding-through-api/">ADR-0015&lt;/a> §13 (a tenant&amp;rsquo;s names), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0016-substrate-secrets-openbao/">ADR-0016&lt;/a> (OpenBao), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0030-site-certificate-hierarchy/">ADR-0030&lt;/a> §5–§6 (lifetimes and renewal), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/platform-services/0036-service-proxy/">ADR-0036&lt;/a> (the substrate&amp;rsquo;s own services on 443)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>&lt;strong>A tenant workload cannot serve HTTPS that the site trusts.&lt;/strong> The two issuing CAs each have one
job, and neither is this one:&lt;/p></description></item><item><title>ADR-0031: Deevnet PKI</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0031-deevnet-pki/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0031-deevnet-pki/</guid><description>&lt;h1 id="adr-0031-an-offline-deevnet-root-offline-site-cas-and-separate-substrate-and-tenant-device-identity">
 ADR-0031: An Offline Deevnet Root, Offline Site CAs, and Separate Substrate and Tenant Device Identity
 &lt;a class="anchor" href="#adr-0031-an-offline-deevnet-root-offline-site-cas-and-separate-substrate-and-tenant-device-identity">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted (2026-10-05): built by 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0033-deevnet-pki/">CHG-0033&lt;/a>. §6, device identity (mTLS), is decided and not yet built: CHG-0034.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-10-03&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>The certificate hierarchy for every Deevnet site: the root and each site&amp;rsquo;s CA and who holds them, the issuing CAs and what each may issue, subject names, and the target for tenant device identity (mTLS). Not automatic renewal or expiry alerting (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0030-site-certificate-hierarchy/">ADR-0030&lt;/a> open questions 1–2, unchanged).&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Supersedes&lt;/strong>&lt;/td>
 &lt;td>ADR-0030 §1–§4&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Amends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0016-substrate-secrets-openbao/">ADR-0016&lt;/a> §3 (the &lt;code>pki/&lt;/code> row)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0037-tenant-service-certificates/">ADR-0037&lt;/a>: a third issuing CA per site, the Tenant Service CA, for server certificates in a tenant&amp;rsquo;s own zone. It answers open question 2 and amends §3 and §4.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/edge-devices/0011-edge-devices-application-owned/">ADR-0011&lt;/a> §4, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0012-iot-platform-api/">ADR-0012&lt;/a> §8, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/edge-devices/0020-direct-device-access-to-tenant-services/">ADR-0020&lt;/a> §2, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0021-tenant-secrets/">ADR-0021&lt;/a> §8, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0031-site-root-ca/">CHG-0031&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0032-appliance-certificates/">CHG-0032&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>ADR-0030 gave the site a certificate hierarchy, and CHG-0031 and CHG-0032 built it:&lt;/p></description></item><item><title>ADR-0030: Site Certificate Hierarchy</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0030-site-certificate-hierarchy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0030-site-certificate-hierarchy/</guid><description>&lt;h1 id="adr-0030-an-offline-site-root-an-openbao-intermediate-and-certificates-laid-down-by-the-build">
 ADR-0030: An Offline Site Root, an OpenBao Intermediate, and Certificates Laid Down by the Build
 &lt;a class="anchor" href="#adr-0030-an-offline-site-root-an-openbao-intermediate-and-certificates-laid-down-by-the-build">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted (2026-10-05) for §5–§8, built by 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0033-deevnet-pki/">CHG-0033&lt;/a> with &amp;ldquo;issued by OpenBao&amp;rdquo; read as &amp;ldquo;issued by the Substrate CA&amp;rdquo; (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0031-deevnet-pki/">ADR-0031&lt;/a> §7). &lt;strong>§1–§4 superseded by ADR-0031&lt;/strong> (an offline Deevnet root and Site CAs; the substrate issued by Ansible, not OpenBao).&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-10-02&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Where the site&amp;rsquo;s root of trust lives, what issues TLS certificates, how long they last, how a build or repave puts certificates and trust on substrate hosts, appliances, images and the operator&amp;rsquo;s computer, and how tenants keep trusting it. Not automatic renewal, not expiry alerting, not client certificates.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0016-substrate-secrets-openbao/">ADR-0016&lt;/a> §3 (the &lt;code>pki/&lt;/code> row) and §6 (rebuild order); answers its open question 1&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0003-openbao-credential-loss/">INC-0003&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0030-state-store-tls/">CHG-0030&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/platform-services/0023-metrics-and-alerting/">ADR-0023&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>OpenBao&amp;rsquo;s &lt;code>pki/&lt;/code> mount is the site&amp;rsquo;s certificate authority (ADR-0016 §3). It holds a self-generated
root, &lt;code>CN=Deevnet mobile internal CA&lt;/code>, valid ten years, and one role, &lt;code>platform&lt;/code>, that issues 90-day
leaves. Ansible issues six of them as it builds each service: the Deevnet API, the state store, the
broker, the log store&amp;rsquo;s proxy, Grafana and tenant downloads. Tenants, the provider and the scripts that
check the site trust that root as &lt;code>site-ca.pem&lt;/code>, passed to each tool by file.&lt;/p></description></item><item><title>ADR-0016: Substrate Secrets in OpenBao</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0016-substrate-secrets-openbao/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0016-substrate-secrets-openbao/</guid><description>&lt;h1 id="adr-0016-the-substrate-keeps-its-runtime-secrets-in-openbao">
 ADR-0016: The Substrate Keeps Its Runtime Secrets in OpenBao
 &lt;a class="anchor" href="#adr-0016-the-substrate-keeps-its-runtime-secrets-in-openbao">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>In conflict with&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0033-code-is-the-state/">ADR-0033: Code Is the State&lt;/a> &lt;em>(Proposed)&lt;/em>: OpenBao&amp;rsquo;s data as kept data (§1, Consequences). To be revisited; the open part is the Tenant Device CA&amp;rsquo;s key&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-19, recording what 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0010-tenant-api-cutover/">CHG-0010&lt;/a> built on 2026-09-17. The record&amp;rsquo;s own Current state already read &lt;em>&amp;ldquo;Proposed, and deployed&amp;rdquo;&lt;/em>; the status field had simply not caught up.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Where the credentials substrate services use at runtime are kept, how tenant secrets are protected at rest and in transit, and where the internal certificate authority lives&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0015-tenant-onboarding-through-api/">ADR-0015: Tenants Are Built Through the Deevnet API&lt;/a>, whose API holds credentials for PowerDNS, the core router, the state store and the tenant hypervisor, and stores tenant secrets&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0021-tenant-secrets/">ADR-0021: Tenant Secrets&lt;/a> (Proposed), the record §8 asked for on tenant namespaces&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a> §9 (credential delivery), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0013-management-services-domain-vms/">ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="how-the-apis-credentials-are-handled-in-adr-0015s-first-slice">
 How the API&amp;rsquo;s credentials are handled in ADR-0015&amp;rsquo;s first slice
 &lt;a class="anchor" href="#how-the-apis-credentials-are-handled-in-adr-0015s-first-slice">#&lt;/a>
&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Credential&lt;/th>
 &lt;th>Kept in&lt;/th>
 &lt;th>Reaches the API as&lt;/th>
 &lt;th>Can do&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Operator token, database password&lt;/td>
 &lt;td>inventory vault&lt;/td>
 &lt;td>a root-only env file, then container environment&lt;/td>
 &lt;td>the whole API; its database&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PowerDNS HTTP API key&lt;/td>
 &lt;td>inventory vault; also in &lt;code>pdns.conf&lt;/code> on the DNS host&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>every zone and key on the server&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Core router API key&lt;/td>
 &lt;td>the router automation user&amp;rsquo;s vault entry&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>everything that user may do on the router&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>State-store admin&lt;/td>
 &lt;td>inventory vault&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>user and policy administration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Proxmox token&lt;/td>
 &lt;td>inventory vault&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>what ADR-0015 grants it on the tenant hypervisor&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>And for what is handed to tenants:&lt;/p></description></item><item><title>ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0013-management-services-domain-vms/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0013-management-services-domain-vms/</guid><description>&lt;h1 id="adr-0013-management-hypervisor-services-run-as-containers-on-domain-vms">
 ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs
 &lt;a class="anchor" href="#adr-0013-management-hypervisor-services-run-as-containers-on-domain-vms">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-16, once 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0008-domain-vms-build-out/">CHG-0008&lt;/a> built all six domain VMs and moved the controller, tenant DNS and the tenant state store onto them&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-14&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How services on the management hypervisor are grouped into VMs and named, where the site&amp;rsquo;s Omada controller officially runs, and the order a rebuild uses them in&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0009-network-device-config-ownership/">ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied&lt;/a>, which decided that the controller is the actuator for switch and AP configuration, but not where it runs&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a> — the provisioning VM holds both the state store and the API&amp;rsquo;s database, so their data needs a data disk and a copy on separate hardware &lt;em>(Superseded by ADR-0033)&lt;/em>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/platform-services/0025-identity-directory/">ADR-0025: Identity Directory&lt;/a> — Keycloak in the identity VM, with a realm per tenant &lt;em>(Proposed)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Superseded in part by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/platform-services/0022-central-logging/">ADR-0022: Central Logging&lt;/a> — §5, for logs only: one log store on Platform instead of one per audience &lt;em>(Accepted)&lt;/em>. The two observability VMs are replaced as a result, &lt;code>sob&lt;/code> by &lt;code>dv02col001v01&lt;/code> (collector) and &lt;code>tob&lt;/code> by &lt;code>dv02obs001v01&lt;/code> (store), in 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0018-central-log-store/">CHG-0018&lt;/a> &lt;em>(Planned)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/naming-and-dns/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/naming-and-dns/0008-host-naming-site-codes/">ADR-0008: Host Naming and Site Codes&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/tenant-model/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a> (its Open questions 2, 5 and 6), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/">CHG-0005&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="one-vm-per-function-is-where-things-were-heading">
 One VM per function is where things were heading
 &lt;a class="anchor" href="#one-vm-per-function-is-where-things-were-heading">#&lt;/a>
&lt;/h3>
&lt;p>The management hypervisor, &lt;code>dv02hyp001p01&lt;/code>, runs one VM per service today:&lt;/p></description></item><item><title>ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0009-network-device-config-ownership/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/substrate/0009-network-device-config-ownership/</guid><description>&lt;h1 id="adr-0009-network-device-configuration-is-inventory-owned-and-controller-applied">
 ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied
 &lt;a class="anchor" href="#adr-0009-network-device-configuration-is-inventory-owned-and-controller-applied">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-10&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-10&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Who owns, and who applies, the configuration of controller-managed network devices — the access switch and the AP — and how automation talks to the Omada controller&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/substrate/0013-management-services-domain-vms/">ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs&lt;/a> — where the controller runs (a container in the network management VM, &lt;code>nms&lt;/code>), and the order a rebuild uses it in&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0004-omada-controller-upgrade/">CHG-0004&lt;/a> — brings the controller current; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/">CHG-0005&lt;/a> — the AP, the first device adopted under this record; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0006-access-switch-firmware-upgrade/">CHG-0006&lt;/a> — the switch&amp;rsquo;s firmware; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0001-firewall-policy-deletion/">INC-0001&lt;/a> — the guards any reconciling role now carries&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>The mobile site&amp;rsquo;s network devices are configured three different ways today:&lt;/p></description></item></channel></rss>