From 9fa51f401a546cd1f2c477bcdeca11f6d9d323da Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sun, 30 Aug 2026 09:40:26 +1000 Subject: [PATCH] Add arrstack creds role and k8s auth for mediamark (#141) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why mediamark (kids-content marking UI, namespace `mediamark`) needs Sonarr/Radarr access to list series/movies and read metadata + artwork. It should get ephemeral virtual arrproxy keys from the arrstack secrets engine via arrproxy, not a copy of the static app API keys. ## How - `config/arrstack_secret_backend_role/arrstack/mediamark.yaml` — role minting keys scoped to `sonarr` + `radarr` (no prowlarr), `ttl: 60` / `max_ttl: 86400`, mirroring the existing per-app roles. - `config/auth_kubernetes_role/k8s/au/syd1/mediamark.yaml` — k8s auth role `mediamark`, bound to serviceaccount `default` in namespace `mediamark`, `token_ttl`/`token_max_ttl` 600, audience `vault`. - `policies/arrstack/creds/mediamark.yaml` — `read` on `arrstack/creds/mediamark`, granted to `k8s/au/syd1: [mediamark]` only (deliberately not the shared `default` k8s role, which would expose the creds to every namespace). Engine mount/config and the existing roles are untouched. ## Note The companion argocd-apps change consumes `arrstack/creds/mediamark` via a `VaultDynamicSecret` (response fields: `token`, `id`, `apps`, `subject`, `expires_at`). **GET/HEAD-only is not expressible today.** `arrstack_secret_backend_role` carries `apps`/`ttl`/`max_ttl` only, and arrproxy scopes machine tokens by app — the GET/HEAD restriction on the cheeztv/kids tier is a grant on an OIDC *group*, not on a minted token. The role is scoped as tightly as the engine allows and the limitation is documented in the yaml; per-token method scoping needs a plugin + arrproxy feature. Reviewed-on: https://git.unkin.net/unkin/terraform-vault/pulls/141 Co-authored-by: unkin-agent Co-committed-by: unkin-agent --- .../arrstack/mediamark.yaml | 17 +++++++++++++++++ .../k8s/au/syd1/mediamark.yaml | 10 ++++++++++ policies/arrstack/creds/mediamark.yaml | 12 ++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 config/arrstack_secret_backend_role/arrstack/mediamark.yaml create mode 100644 config/auth_kubernetes_role/k8s/au/syd1/mediamark.yaml create mode 100644 policies/arrstack/creds/mediamark.yaml diff --git a/config/arrstack_secret_backend_role/arrstack/mediamark.yaml b/config/arrstack_secret_backend_role/arrstack/mediamark.yaml new file mode 100644 index 0000000..8935163 --- /dev/null +++ b/config/arrstack_secret_backend_role/arrstack/mediamark.yaml @@ -0,0 +1,17 @@ +--- +# Mints an arrproxy API key for the mediamark kids-content marking UI, scoped to +# Sonarr and Radarr only (no Prowlarr: mediamark never touches indexers). +# +# mediamark only lists series/movies and reads metadata + artwork, so its key is +# read-only in intent. The engine role cannot express that today: an +# arrstack_secret_backend_role carries apps/ttl/max_ttl only, and arrproxy scopes +# machine tokens by app, not by HTTP method (the GET/HEAD restriction on the +# cheeztv/kids tier is a grant on an OIDC *group*, not on a minted token). Until +# the engine and arrproxy grow per-token method scoping, mediamark's read-only +# posture is enforced by the app itself and by the arrproxy tier it routes to. +apps: + - radarr + - sonarr +ttl: 60 # seconds (1m); short-lived by design, renewed on demand +max_ttl: 86400 # seconds (24h); the engine additionally caps renewal at the + # arrproxy admin token's fixed mint expiry. diff --git a/config/auth_kubernetes_role/k8s/au/syd1/mediamark.yaml b/config/auth_kubernetes_role/k8s/au/syd1/mediamark.yaml new file mode 100644 index 0000000..6e583d6 --- /dev/null +++ b/config/auth_kubernetes_role/k8s/au/syd1/mediamark.yaml @@ -0,0 +1,10 @@ +--- +# Kubernetes auth role for the mediamark app: the default service account in the +# mediamark namespace, used by VaultDynamicSecret to read arrstack/creds/mediamark. +bound_service_account_names: + - default +bound_service_account_namespaces: + - mediamark +token_ttl: 600 +token_max_ttl: 600 +audience: vault diff --git a/policies/arrstack/creds/mediamark.yaml b/policies/arrstack/creds/mediamark.yaml new file mode 100644 index 0000000..0ec218f --- /dev/null +++ b/policies/arrstack/creds/mediamark.yaml @@ -0,0 +1,12 @@ +# Allow the mediamark app to mint its own Sonarr/Radarr-scoped arrproxy key. +# Bound to the dedicated "mediamark" k8s role only, never the shared "default" +# role, so no other namespace can read these creds. +--- +rules: + - path: "arrstack/creds/mediamark" + capabilities: + - read + +auth: + k8s/au/syd1: + - mediamark