T4: k8s namespace + capability Roles #20

Merged
ginjiruu merged 3 commits from t4-k8s-capability-roles into master 2026-08-11 18:41:39 +00:00
Owner

By ⁨⁩⁨ginjiruu⁩⁨⁩ — ⁨⁨⁩Open⁨⁩⁩ — ⁨⁩+⁨149⁩ ⁨⁩-⁨3⁩⁨⁩
⁨From ⁨t4-k8s-capability-roles⁩ into ⁨master⁩

Closes #7

Implements T4: the k8s tenant module now creates, per catalog app, a namespace plus namespace-scoped capability Roles per the ADR-0007 k8s column, each bound to the app's kanidm capability group:

  • viewer / contributor: get/list on non-secret resources (pods, services, configmaps, deployments, statefulsets, ingresses, events, pods/log)
  • developer: edit (get/list/watch/create/update/patch) on the same non-secret set — no delete
  • maintainer: developer + delete/deletecollection
  • live-debugging: get pods + create on pods/exec, pods/attach, pods/portforward
  • k8s-secret-viewer: get/list secrets (namespace-wide, all-or-nothing per ADR-0007)
  • root: namespace Role * incl secrets (per app, matching the kanidm <app>-root group)

Each Role has a namespace-scoped RoleBinding whose subject is the matching kanidm group name (group-<app>-<capability>, <app>-root) with kind: Group — membership grants arrive via the OIDC groups claim, never cluster-wide. generated-secret-manager / manual-secret-manager are Vault-only per the matrix and get no Role or binding.

Verification: tofu validate passes; tofu plan is green (30 to add: 2 namespaces + 14 Roles + 14 RoleBindings across privatebin/syncthing).

Wiring note: subject names are the kanidm group names, so the apiserver OIDC setup must request kanidm's groups_name scope and set --oidc-groups-claim=groups for the bindings to match. <app>-root is nested in every capability group (ADR-0007), so root members also match the capability bindings.

By ⁨⁩⁨ginjiruu⁩⁨⁩ — ⁨⁨⁩Open⁨⁩⁩ — ⁨⁩+⁨149⁩ ⁨⁩-⁨3⁩⁨⁩ ⁨From `⁨t4-k8s-capability-roles⁩` into `⁨master⁩`⁩ Closes #7 Implements T4: the k8s tenant module now creates, per catalog app, a namespace plus namespace-scoped capability Roles per the ADR-0007 k8s column, each bound to the app's kanidm capability group: - `viewer` / `contributor`: get/list on non-secret resources (pods, services, configmaps, deployments, statefulsets, ingresses, events, pods/log) - `developer`: edit (get/list/watch/create/update/patch) on the same non-secret set — no delete - `maintainer`: developer + `delete`/`deletecollection` - `live-debugging`: get pods + create on pods/exec, pods/attach, pods/portforward - `k8s-secret-viewer`: get/list secrets (namespace-wide, all-or-nothing per ADR-0007) - `root`: namespace Role `*` incl secrets (per app, matching the kanidm `<app>-root` group) Each Role has a namespace-scoped RoleBinding whose subject is the matching kanidm group name (`group-<app>-<capability>`, `<app>-root`) with `kind: Group` — membership grants arrive via the OIDC groups claim, never cluster-wide. `generated-secret-manager` / `manual-secret-manager` are Vault-only per the matrix and get no Role or binding. Verification: `tofu validate` passes; `tofu plan` is green (30 to add: 2 namespaces + 14 Roles + 14 RoleBindings across privatebin/syncthing). Wiring note: subject names are the kanidm group *names*, so the apiserver OIDC setup must request kanidm's `groups_name` scope and set `--oidc-groups-claim=groups` for the bindings to match. `<app>-root` is nested in every capability group (ADR-0007), so root members also match the capability bindings.
ginjiruu merged commit 189647866b into master 2026-08-11 18:41:39 +00:00
ginjiruu deleted branch t4-k8s-capability-roles 2026-08-11 18:41:40 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lab/iac!20
No description provided.