It's blocked on both sides of the Cilium default-deny:
apps egress: apps is egress-default-deny; the allow-list had no openbao entry.
openbao ingress: openbao is ingress-default-deny; the rotator pod wasn't allowlisted (only intra-ns snapshot job, Traefik, and ESO are).
(The raft-snapshot job dodges this by running inside the openbao ns.)
Fix (two rules, matching existing convention)
default-deny.yaml (apps egress): namespace-wide allow to openbao:8200, scoped in effect by openbao's own ingress — the same pattern the mosquitto rule already uses.
openbao-ns.yaml (openbao ingress): scoped allow from the rotator pod labels (apps/woodpecker/secret-rotator) — this is the real security boundary.
Verified: apps has no other blocking egress; kubectl kustomize + yamllint clean. After merge + Flux apply, the on-demand test (kubectl -n apps create job --from=cronjob/woodpecker-secret-rotate ...) should complete.
## Bug
The `woodpecker-secret-rotate` CronJob from #297 fails — its pod (ns `apps`) cannot reach OpenBao:
```
dial tcp 10.103.51.211:8200: i/o timeout (auth/kubernetes/login)
```
It's blocked on **both** sides of the Cilium default-deny:
- **apps egress**: `apps` is egress-default-deny; the allow-list had no `openbao` entry.
- **openbao ingress**: `openbao` is ingress-default-deny; the rotator pod wasn't allowlisted (only intra-ns snapshot job, Traefik, and ESO are).
(The raft-snapshot job dodges this by running *inside* the openbao ns.)
## Fix (two rules, matching existing convention)
- `default-deny.yaml` (apps egress): namespace-wide allow to `openbao:8200`, scoped in effect by openbao's own ingress — the same pattern the mosquitto rule already uses.
- `openbao-ns.yaml` (openbao ingress): scoped allow from the rotator pod labels (`apps`/`woodpecker`/`secret-rotator`) — this is the real security boundary.
Verified: `apps` has no other blocking egress; `kubectl kustomize` + yamllint clean. After merge + Flux apply, the on-demand test (`kubectl -n apps create job --from=cronjob/woodpecker-secret-rotate ...`) should complete.
The woodpecker-secret-rotate CronJob (#297) runs in ns apps and could not reach OpenBao (i/o timeout on auth/kubernetes/login) — blocked on BOTH sides: apps is egress-default-deny (no openbao allow) and openbao is ingress-default-deny (rotator not allowlisted). The snapshot job avoids this by living in the openbao ns; ESO is explicitly allowlisted.
- default-deny.yaml (apps egress): namespace-wide allow to openbao:8200, scoped in effect by openbao's ingress (mosquitto pattern).
- openbao-ns.yaml (openbao ingress): scoped allow from the rotator pod labels (apps/woodpecker/secret-rotator) — the real security boundary.
Verified apps has no other blocking egress; kustomize build + yamllint clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015K7gLUVVnutvDnzV2TrMRJ
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Bug
The
woodpecker-secret-rotateCronJob from #297 fails — its pod (nsapps) cannot reach OpenBao:It's blocked on both sides of the Cilium default-deny:
appsis egress-default-deny; the allow-list had noopenbaoentry.openbaois ingress-default-deny; the rotator pod wasn't allowlisted (only intra-ns snapshot job, Traefik, and ESO are).(The raft-snapshot job dodges this by running inside the openbao ns.)
Fix (two rules, matching existing convention)
default-deny.yaml(apps egress): namespace-wide allow toopenbao:8200, scoped in effect by openbao's own ingress — the same pattern the mosquitto rule already uses.openbao-ns.yaml(openbao ingress): scoped allow from the rotator pod labels (apps/woodpecker/secret-rotator) — this is the real security boundary.Verified:
appshas no other blocking egress;kubectl kustomize+ yamllint clean. After merge + Flux apply, the on-demand test (kubectl -n apps create job --from=cronjob/woodpecker-secret-rotate ...) should complete.