Images, secrets and audit

Images, secrets and audit

Image scanning

graph LR C[code] --> B[build image] --> S["scan<br/>Trivy / Grype"] --> SIGN["sign<br/>cosign"] --> R[(registry)] R --> A["admission<br/>allowed registry? signed?"] --> K[cluster]
trivy image nginx:1.27 --severity HIGH,CRITICAL
trivy config ./manifests/          # misconfigurations in YAML, Helm, Dockerfile
trivy k8s --report summary         # scan the running cluster

Fix order: base image update > fewer packages > accept with justification.

Warning

The scanner is part of your supply chain too. In March 2026 attackers published a malicious Trivy v0.69.4 and hijacked the trivy-action / setup-trivy GitHub Action tags to steal CI secrets. Pin tools and actions to verified versions or commit SHAs, and verify checksums and signatures.

Secrets at rest

By default Secrets are stored in etcd base64, not encrypted. Anyone with an etcd backup or etcd access reads them.

# /etc/kubernetes/enc/enc.yaml on the control plane
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources: ["secrets"]
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <32 random bytes, base64>
      - identity: {}          # still able to read old, unencrypted data

kube-apiserver flag --encryption-provider-config. Existing Secrets are encrypted only when rewritten. Production: a KMS provider (Azure Key Vault, AWS KMS, Vault) so the key is not on the control plane disk.

Audit logging

Who did what, when, from where - for every API request.

# /etc/kubernetes/audit/policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: None                       # noise
    users: ["system:kube-proxy"]
  - level: Metadata                   # never log secret contents
    resources: [{ group: "", resources: ["secrets", "configmaps"] }]
  - level: RequestResponse
    resources: [{ group: "rbac.authorization.k8s.io" }]
  - level: Metadata                   # everything else
LevelLogs
Nonenothing
Metadatauser, verb, resource, time, source IP
Request+ request body
RequestResponse+ response body

Flags: --audit-policy-file, --audit-log-path, --audit-log-maxage. Ship the log to your SIEM (Sentinel, Splunk) - that is where detections live.

Beyond

  • CIS Kubernetes Benchmark - kube-bench checks nodes and control plane.
  • Runtime detection - Falco, Defender for Containers, Tetragon.

References