---
id: w7/m2/t002
title: "Operator pod-spec defaults: drop capabilities, RuntimeDefault seccomp, no SA token automount"
worker: worker7
status: done
estimate: 45m
depends_on: [w7/m2/t001]
---

## Objective

The operator stamps hardening defaults on every tenant Deployment it reconciles: containers drop all capabilities (keeping `NET_BIND_SERVICE` if a low port is needed), `seccompProfile: RuntimeDefault`, `allowPrivilegeEscalation: false`, and `automountServiceAccountToken: false` on the pod spec — so a compromised tenant container finds no cluster credentials and no escalation path.

## Context

- `lego/operator/internal/controller/app_controller.go` builds the Deployment; today it sets **no** securityContext and leaves SA-token automount on (verified 2026-07-09).
- Must stay compatible with arbitrary user images: do **not** set `runAsNonRoot` (PSS `baseline` line, m1 ADR).
- Apps' ports are container ports behind a Service — check whether any sample binds <1024 before deciding on `NET_BIND_SERVICE`.
- The opensandbox runtime path (`BEX_RUNTIME=opensandbox`) doesn't build pods — kubernetes runtime only.

## Steps

1. Add the securityContext + automount defaults to the Deployment builder (pod spec + container level).
2. Confirm both samples (`whoami`, `hello-go`) and a CNB-built image still start and serve.
3. Confirm sleep/wake (w1/m4) and restart/suspend/resume verbs still behave.

## Files

- `lego/operator/internal/controller/app_controller.go` (+ its envtest file)

## Acceptance criteria

- [ ] Reconciled tenant pod: no SA token mount, RuntimeDefault seccomp, dropped capabilities, `allowPrivilegeEscalation: false`
- [ ] Both example apps reach Ready and serve unchanged
- [ ] No `runAsNonRoot` forced

## Out of scope

- Build Jobs (t003 — BuildKit needs its own profile: rootless with seccomp/AppArmor unconfined, per `internal/build/build.go`)
