Skip to content

title: Secure Design: Interfaces and Defense in Depth category: reference related: - docs/threat-model.md - docs/sdl/security-requirements.md - docs/security-hardening.md


Secure Design: Interfaces and Defense in Depth

The secure-by-design practice (62443-4-1 Practice 3, SD-1…SD-4) for Cloud-Native DCS. The threat analysis behind this document is the threat model. This document is the design-side record: the interface catalog and the defense-in-depth layer assignment.

Interface catalog (SD-1)

Every product interface, with exposure, trust-boundary crossing, users, assets reachable, and safeguards. "External" means accessible from outside the product's own pods. The boundary column says whether use crosses a trust boundary in the threat model.

Interface Exposure Crosses boundary Users Assets reachable Safeguards
Gateway HTTPS: REST API + web UI/HMI External (cluster ingress) Yes — human/enterprise → control zone Operators, engineers, supervisors, admins; API tools; dcs CLI All control-plane state the caller's permissions allow (recipes, batches, commands, audit queries) TLS; OIDC/LDAP authentication; permission-gated routes (ADR 0005); per-IP read/write rate limits; typed-DTO validation with unknown-field rejection; anti-replay nonces on mutations; audit attribution on every mutation
Gateway auth endpoints (/api/v1/auth/*) External Yes Unauthenticated → authenticated transition Session issuance LDAP bind over LDAPS/StartTLS; failed logins audited; lockout + system-use banner shipped (#974)
Kubernetes API (CRDs, 8 API groups) Internal (cluster) Yes — platform boundary Operators (ServiceAccounts), gateway, admins via GitOps All CR state, Secrets in namespace scope Per-binary least-privilege ClusterRoles (generated, drift-checked); AuditRecord create-only; human write access gated by GitOps admission policy
AuditRecord admission webhook Internal (kube-apiserver → webhook) Yes kube-apiserver Audit-trail integrity TLS; rejects update/delete regardless of RBAC; required-field validation
MQTT broker (Mosquitto, shipped config) Internal conduit Yes — control ↔ field zones dcs-gateway, operators, unit-runtime, historian (per-role credentials) Live process values, commands TLS (8883) in production profile; per-role username/password; topic ACLs; NetworkPolicy conduit rules
Unit-runtime HTTP API (health 61052, API 61152, hostNetwork) Internal, on device node network Yes — control → field zone Physical operator, gateway (via operator) Edge runtime state, FB network control mTLS; fail-closed bearer-token auth; port allocation outside ephemeral range; NetworkPolicy
OPC UA client sessions (unit-runtime, gateway discovery) Outbound to customer servers Yes — product → OT device zone Software process (X.509 client identity) Field device data/commands on the remote server Sign/SignAndEncrypt (Basic256Sha256); operator-supplied per-Unit certs; server-cert SHA-256 pinning; discovery identity scoped to the transient wizard path (#919)
Modbus TCP / EtherNet/IP clients (io-probe, unit-runtime) Outbound to field devices Yes — product → field-bus zone Software process Physical I/O Plaintext by design — compensating controls: dedicated field-bus zone/CIDRs, physical conduit security, egress NetworkPolicies (threat model TB5)
Historian PostgreSQL (CNPG) Internal No (within control zone) historian, audit-archiver, gateway queries Time-series, batch records, archived audit Credentials in Secrets; NetworkPolicy; PVC encryption delegated (register D7); CNPG-managed TLS
Audit archive S3 mirror (optional) Outbound to object store Yes — control zone → storage service audit-archiver Signed archive bundles Object Lock Compliance mode (WORM); write-only credential scope; ≥365-day retention floor
Prometheus metrics endpoints Internal No Monitoring stack Operational telemetry (no process secrets) TLS-capable; NetworkPolicy; no sensitive payloads in metrics
Browser-delivered UI JavaScript External (served to browsers) Yes — product → user endpoint Human users' browsers UI logic; API calls with the user's token First-party same-origin static files only; no eval/dynamic import; served over TLS from signed images; CSP (script-src 'self', object-src 'none', base-uri 'self') + per-script SRI hashes (#978)

Design rule: a new interface (or a change to exposure, users, or assets of an existing one) requires a row here, a threat-model delta, and an SD-3 design review before merge.

Defense-in-depth layers (SD-2)

Layered so that compromise of one layer meets an independent control at the next. Responsibilities per layer:

Layer Controls (product) Delegated share (register)
1. Network segmentation Zone/conduit NetworkPolicy model, default-deny ingress, egress restriction Physical OT segmentation (D8)
2. Transport mTLS on all inter-component HTTP; MQTT TLS; OPC UA Sign/SignAndEncrypt
3. Authentication OIDC/LDAP humans; certs/tokens/credentials for every software process IdP account + password policy (D1, D2)
4. Authorization Permission-gated routes; per-binary K8s RBAC; MQTT topic ACLs
5. Request hygiene Typed validation, unknown-field rejection, anti-replay nonces, rate limits
6. Workload hardening Distroless, non-root, dropped capabilities, seccomp RuntimeDefault, read-only root FS Node OS hardening / Talos (D7 tier)
7. Data integrity & at-rest Immutable AuditRecords, HMAC signatures, WORM archive mirror, spec-hash integrity etcd/PVC/disk encryption (D4, D7)
8. Supply chain Signed images, SBOM, pinned deps, govulncheck/Trivy Admission signature verification (D6)
9. Detection & response hooks Metrics, health probes, audit stream, structured logs IDS/SIEM stack (D9)

Security design review (SD-3)

Every significant design revision (new interface, new trust-boundary crossing, new CRD surface, auth/authz change) gets a design review recording: unaddressed security requirements, threats against the new interfaces/assets, and any secure-design practice not followed. The review artifact is an ADR (for architecture-shaping changes) or the review section of the implementing issue. The standing daily review (#483) backstops smaller changes. The external security-advisor seat joins these reviews once the engagement is active (see the independence plan).

Secure design best practices (SD-4)

The applied list, reviewed with this document:

  • Least privilege: per-binary generated ClusterRoles, the seven-permission vocabulary with least-privilege additions (ADR 0010), and scoped MQTT ACLs.
  • Proven components: Kubernetes primitives, cert-manager, CNPG, Mosquitto, and controller-runtime, all consumed through configuration alone.
  • Economy of mechanism: two sanctioned API transports (apiFetch/ hmiFetch), one modal primitive, one state-machine implementation, enforced by lint gates so simplicity survives contributions.
  • Secure design patterns: fail-closed auth on the runtime API, create-only audit resources, declarative-not-imperative configuration.
  • Attack surface reduction: distroless single-binary images with no shell, dcs internal excluded from release builds (lint-cli-internal-excluded), and unused drivers removed (#727).
  • Documented trust boundaries: threat model + the interface catalog above.
  • Debug surfaces: no hardware. Software debug/profiling endpoints are not compiled into release binaries.