Skip to content

ADR 0048 — ZTP-Prem compliance enforcement (machine-readable contract)

  • Status: Accepted (2026-05-14)
  • Date: 2026-05-14
  • Deciders: TLSStress.Art project (operator directive 2026-05-14)
  • Builds on: ADR 0043 (OOBI VLAN), 0044 (intrusion), 0045 (Hello mesh), 0046 (Hello encryption), 0047 (VXLAN test payload only)
  • Targets: v4.1.0+

Context

ZTP-Prem (Zero-Trust on Premises) was locked on 2026-05-11 as a 12-layer defence model against the insider-threat operator. Most of the cited layers exist piecewise in the codebase, but there is no machine-readable contract that says "this element implements this layer". Two consequences:

  1. Reviewers cannot tell, when accepting a new MÓDULO, whether it inherits the full ZTP-Prem perimeter.
  2. The operator cannot answer "where are we today?" with a single command — the posture is implicit in code instead of explicit in data.

The 2026-05-14 directive captured this explicitly:

Precisamos garantir que todos elementos, considerando elementos da Infra incluidos, modulos, kernel, runtimes, estejam conformes com a definição que tivemos sobre ZTP-Prem. Todos elementos do software devem estar protegidos contra insider threat bad actor.

Decision

Introduce a machine-readable compliance contract in pkg/oobi/ztp-compliance/:

The 12 layers (stable, ordered outermost → innermost)

ID Name Summary Source
L1 Network boundary TLS at every external surface + DSCP CS7 marking inside OOBI VLAN ADR 0038
L2 Bearer-token L2 auth OOBI_AUTH_TOKEN on every HTTP surface pkg/oobi/auth
L3 L3 intrusion filter Reject hosts outside /22, unknown slot, blacklisted ADR 0044 + pkg/oobi/intrusion
L4 Encrypted Hello mesh AES-256-GCM Hello over mcast+bcast ADR 0045+0046 + pkg/oobi/hello
L5 UTXO token vault Chained-transaction token ledger; provable revocation pkg/ztp-prem-signctl
L6 Tier A/B code partition Vendor-bypass primitives signed; operator can't redeploy Tier A platform/ztp-prem/tier-policy.yaml
L7 Confidential Computing AMD SEV-SNP / Intel TDX VM enclave (v6.0+) pkg/ztp-prem-tpm
L8 Admission control ValidatingAdmissionWebhook gates every pod creation pkg/ztp-prem-admission
L9 License enforcement Offline JWT entitlement check MÓDULO LICENSE.Art (planned)
L10 Sealed audit chain Append-only Merkle-chained log ADR 0029
L11 Image signing Sigstore/cosign + provenance verified at pull
L12 Host hardening seccomp/AppArmor + read-only root + CIS K8s

Element categories + their expected layers

Category Members Expected layers
module 15 first-party Go MÓDULOs (flow-art, api-infra-art, gateway-art, …, span-correlator) L1, L2, L3, L4, L10, L12
infra-vendored postgres, grafana, prometheus L1, L2, L3, L4 (via sidecar)
infra-first-party dashboard (Next.js) L1, L2, L3, L4
kernel kubelet, containerd, k3s control-plane L7, L11, L12
runtime oobi-vlan-host-iface DaemonSet, customer-mgmt-vlan-host-iface L1, L8, L9, L10

Layers outside an element's expected set return LayerStatusNotApplicable from the audit.

The audit pipeline

pkg/oobi/ztp-compliance/
├── layers.go          12-layer definitions, Registry of elements
├── audit.go           Auditor interface + StaticAuditor + report rendering
├── cmd/ztp-audit/     CLI: `go run … ztp-audit [--json] [--exit-on-fail]`

Auditor is the extension point:

  • StaticAuditor (this PR) returns the build-time-asserted status. Fast, deterministic, offline. Used for CI gating + Dashboard rendering.
  • KubernetesAuditor (next PR) probes live pods, Secrets, NetworkPolicies, image-digest signatures, host-kernel sysctls. Used for runtime compliance.

LayerStatus vocabulary

  • pass — implemented and verified
  • fail — required but missing → blocking
  • n/a — not applicable to this category
  • pending — known gap, scheduled (next wave)
  • manual-verify — auditable only via human review
  • inherit — inherited from host pod / sidecar

Summary classification

An element is Passing when no layer is in fail AND no expected layer is pending. The first pending demotes it to Pending. A single fail demotes it to Failing.

This rule is intentionally strict — pending is not pass. The dashboard summary shows three buckets, not two.

Current canonical baseline (2026-05-14)

Running ztp-audit against the canonical static auditor today:

  • 24 elements total
  • 0 failing — no element is in catastrophic gap
  • 15 modules have L1–L4 = pass (post-v4.0.0 OOBI wave)
  • 9 pending — vendored Infra (Postgres, Grafana, Prometheus) await PR-ZTP-2 sidecar; Dashboard awaits PR-ZTP-5 OOBI Bearer; kernel awaits L7+L11 wave

Consequences

Positive

  • The compliance contract is now enforceable in code instead of carried in operator memory. CI can run ztp-audit --exit-on-fail to block PRs that introduce regressions.
  • The Dashboard ships a single page (/admin/security/ztp-compliance, PR-ZTP-4) where the operator sees the full 24×12 matrix at a glance.
  • Adding a new MÓDULO that omits the Registry entry fails the audit silently by being missing — which is the desired behaviour for the next reviewer.

Negative

  • Two-author bookkeeping: pkg/oobi/canon.go slot map + Registry() must stay in sync. Mitigated by a CI test that asserts every canonical slot has a Registry entry (lands in PR-ZTP-4).
  • The 12 layers are an opinionated taxonomy. Future security-research could discover a 13th; we'll bump versions accordingly.

Neutral

  • This PR ships only the framework + Static auditor. The KubernetesAuditor lives in a follow-up. Operators reading the audit today see "what the build claims" — runtime drift detection is the next iteration.

Rollout

PR Scope State
PR-ZTP-1 (this PR) pkg/oobi/ztp-compliance/ library + ztp-audit CLI + ADR 0048 in flight
PR-ZTP-2 pkg/oobi-sidecar/ Go binary that wraps vendored Infra with L1-L4 next
PR-ZTP-3 K8s sidecar injection for Postgres / Grafana / Prometheus pending
PR-ZTP-4 Dashboard /admin/security/ztp-compliance matrix view + API pending
PR-ZTP-5 Dashboard Next.js endurecido com OOBI Bearer pending

References

  • Memo: project_ztp_prem_posture_locked_2026_05_11.md
  • ADR 0029 — sealed audit chain
  • ADR 0043/0044/0045/0046/0047 — OOBI VLAN cluster
  • Package: pkg/oobi/ztp-compliance/