Skip to main content

Defense-in-Depth Model

Purpose: For security officers, explains the five security layers and their interactions across the platform.

Repository

Kyverno ClusterPolicies, NetworkPolicies, and Pod Security Admission configurations are maintained in the openCenter-gitops-base repository (applications/base/services/kyverno/default-ruleset/). The openCenter-cli generates FluxCD manifests that reference these policies, but policy definitions and enforcement rules live in openCenter-gitops-base. To verify or customize security policies, audit that repository directly.

Concept Summary

openCenter's security architecture is distributed across five layers, each owned by a different component and enforced at a different point in the request lifecycle. No single layer is sufficient on its own — a compromised container image, for example, is caught by Kyverno policies (Layer 2) even if it passes Pod Security Admission (Layer 1). This layering is intentional: each layer compensates for gaps in the others.

How It Works

Layer 1: Cluster Security — Pod Security Admission (PSA)

Configured during cluster provisioning via Kubespray's k8s_hardening.yml. PSA operates at the Kubernetes API server level and evaluates pods against the Pod Security Standards before they are admitted.

  • Enforcement: baseline — rejects pods that violate baseline security (e.g., privileged containers, hostPID)
  • Audit/Warn: restricted — logs and warns on pods that violate the stricter restricted profile

PSA is the first gate. It runs before any webhook-based admission controller and cannot be bypassed by workloads.

See Pod Security Admission for configuration details.

Layer 2: Platform Security — Kyverno Policies

17 ClusterPolicies deployed via FluxCD from openCenter-gitops-base. Kyverno operates as a validating and mutating admission webhook, providing finer-grained controls than PSA.

Where PSA enforces broad profiles, Kyverno enforces specific rules:

  • Disallow privileged containers, host namespaces, host paths
  • Require runAsNonRoot, restrict seccomp profiles, limit volume types
  • Validate image registries, enforce resource limits

Kyverno also generates policy reports, providing audit evidence that PSA alone cannot produce.

See Kyverno Policy Catalog for the full list of 17 policies.

Layer 3: Secrets Management — SOPS + Age

All secrets are encrypted at rest in Git (SOPS with Age keys) and encrypted at rest in etcd (Kubernetes encryption). FluxCD decrypts secrets during reconciliation using the Age private key stored in the cluster.

Key lifecycle policies enforce rotation:

  • Age keys: 90-day rotation
  • SSH deploy keys: 180-day rotation

The dual-key rotation strategy ensures zero downtime during key transitions.

See Secrets Model for the full architecture.

Layer 4: Access Control — Keycloak + RBAC

Keycloak provides OIDC-based authentication. RBAC Manager translates RBACDefinition custom resources into Kubernetes RoleBindings, mapping Keycloak groups to cluster roles.

Default roles:

  • cluster-admins — full cluster access
  • viewers — read-only access to all namespaces

Custom roles are added by creating RBACDefinition resources in the customer overlay.

Layer 5: Network Security — NetworkPolicies / Istio

Network isolation is applied at two levels:

  • Platform services: NetworkPolicies restrict traffic to/from FluxCD, OLM, and other platform components. These are deployed from openCenter-gitops-base.
  • Application workloads: Application teams define their own NetworkPolicies following default-deny patterns.

For clusters requiring mTLS and zero-trust networking, Istio is available as an optional service mesh.

See Network Policies for patterns and examples.

Trade-offs and Alternatives

Why both PSA and Kyverno?

PSA is built into Kubernetes and cannot be disabled by a misconfigured webhook. Kyverno provides granularity, mutation, and reporting that PSA lacks. Running both means a Kyverno outage does not remove all admission controls, and PSA's coarse profiles are supplemented by Kyverno's specific rules.

Why not OPA/Gatekeeper instead of Kyverno?

Kyverno policies are written in YAML, matching the GitOps model. Rego (OPA's policy language) adds a learning curve and a separate toolchain. For openCenter's use case — enforcing a known set of baseline policies — Kyverno's declarative approach reduces operational complexity.

Common Misconceptions

"PSA and Kyverno are redundant." They overlap intentionally. PSA is the safety net that cannot be bypassed; Kyverno is the fine-grained control plane. Removing either weakens the overall posture.

"Network policies are optional." For platform services, NetworkPolicies are deployed by default. For application workloads, they are the application team's responsibility but strongly recommended. Without them, any pod can reach any other pod in the cluster.

Further Reading