mediamark: use ephemeral arrstack virtual keys
The static sonarr/radarr API keys were copies of the real per-app keys,
seeded by hand into kv and never rotated. The arrstack secrets engine can
mint short-lived machine tokens instead, so mediamark leases one rather
than holding a copy of the real thing.
Drop the sonarr-apikey and radarr-apikey VaultStaticSecrets.
Add an arrstack-creds VaultAuth bound to the new `mediamark` k8s role.
Add an arrstack-virtual-key VaultDynamicSecret reading arrstack/creds/mediamark.
Project the leased token to both /etc/mediamark/keys/{sonarr,radarr}.
Point MEDIAMARK_{SONARR,RADARR}_URL at arrproxy-api, which is the only
thing that honours a virtual key.
Reload on arrstack-virtual-key instead of the removed secrets.
This commit is contained in:
@@ -5,7 +5,7 @@ metadata:
|
||||
name: mediamark
|
||||
namespace: mediamark
|
||||
annotations:
|
||||
secret.reloader.stakater.com/reload: "sonarr-apikey,radarr-apikey"
|
||||
secret.reloader.stakater.com/reload: "arrstack-virtual-key"
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
@@ -45,10 +45,13 @@ spec:
|
||||
value: /media
|
||||
- name: MEDIAMARK_KEYS_DIR
|
||||
value: /etc/mediamark/keys
|
||||
# Virtual keys are only honoured by arrproxy, which validates the
|
||||
# machine token and injects the real per-app key upstream; the
|
||||
# sonarr/radarr Services would reject them.
|
||||
- name: MEDIAMARK_SONARR_URL
|
||||
value: http://sonarr-adult.arrstack.svc.cluster.local:8989/3aa168/sonarr
|
||||
value: http://arrproxy-api.arrstack.svc.cluster.local:8080/3aa168/sonarr
|
||||
- name: MEDIAMARK_RADARR_URL
|
||||
value: http://radarr-adult.arrstack.svc.cluster.local:7878/3aa168/radarr
|
||||
value: http://arrproxy-api.arrstack.svc.cluster.local:8080/3aa168/radarr
|
||||
# oauth2-proxy --pass-user-headers forwards the Authentik groups as a
|
||||
# comma-joined X-Forwarded-Groups; X-Auth-Request-Groups is
|
||||
# auth_request-response-only and never reaches a proxied upstream.
|
||||
@@ -95,19 +98,17 @@ spec:
|
||||
- name: mediastore
|
||||
persistentVolumeClaim:
|
||||
claimName: mediamark-mediastore
|
||||
# Per-app *arr API keys as one file per app under MEDIAMARK_KEYS_DIR,
|
||||
# mirroring the arrproxy keys projection.
|
||||
# One ephemeral virtual key covers both apps, so the same token lands on
|
||||
# both per-app files under MEDIAMARK_KEYS_DIR; mediamark re-reads the
|
||||
# file per request, so lease renewal rotates in place.
|
||||
- name: arr-keys
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
name: sonarr-apikey
|
||||
name: arrstack-virtual-key
|
||||
items:
|
||||
- key: apitoken
|
||||
- key: token
|
||||
path: sonarr
|
||||
- secret:
|
||||
name: radarr-apikey
|
||||
items:
|
||||
- key: apitoken
|
||||
- key: token
|
||||
path: radarr
|
||||
restartPolicy: Always
|
||||
|
||||
@@ -6,6 +6,7 @@ resources:
|
||||
- namespace.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- vaultdynamicsecret.yaml
|
||||
- pv-mediastore.yaml
|
||||
- pvc-mediastore.yaml
|
||||
- deployment.yaml
|
||||
|
||||
@@ -16,3 +16,23 @@ spec:
|
||||
method: kubernetes
|
||||
mount: k8s/au/syd1
|
||||
vaultConnectionRef: vso-system/default
|
||||
---
|
||||
# Separate auth for the arrstack secrets engine: the `mediamark` k8s role is the
|
||||
# only one whose policy grants arrstack/creds/mediamark.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultAuth
|
||||
metadata:
|
||||
name: arrstack-creds
|
||||
namespace: mediamark
|
||||
spec:
|
||||
allowedNamespaces:
|
||||
- mediamark
|
||||
kubernetes:
|
||||
audiences:
|
||||
- vault
|
||||
role: mediamark
|
||||
serviceAccount: default
|
||||
tokenExpirationSeconds: 600
|
||||
method: kubernetes
|
||||
mount: k8s/au/syd1
|
||||
vaultConnectionRef: vso-system/default
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
# Ephemeral arrstack virtual key. The engine mints one machine token covering
|
||||
# both radarr and sonarr; it is only honoured by arrproxy, which validates it and
|
||||
# swaps in the real per-app key upstream. Role ttl is 60s, so VSO renews the
|
||||
# lease continuously (renewalPercent default 67) and rewrites the secret; the
|
||||
# reloader annotation restarts pods when the token actually changes.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultDynamicSecret
|
||||
metadata:
|
||||
name: arrstack-virtual-key
|
||||
namespace: mediamark
|
||||
spec:
|
||||
allowStaticCreds: false
|
||||
destination:
|
||||
create: true
|
||||
name: arrstack-virtual-key
|
||||
overwrite: true
|
||||
mount: arrstack
|
||||
path: creds/mediamark
|
||||
revoke: true
|
||||
vaultAuthRef: arrstack-creds
|
||||
@@ -20,41 +20,3 @@ spec:
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
---
|
||||
# Sonarr (adult tier) API key, projected into the mediamark keys dir as
|
||||
# /etc/mediamark/keys/sonarr.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: sonarr-apikey
|
||||
namespace: mediamark
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: sonarr-apikey
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/mediamark/default/sonarr
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
---
|
||||
# Radarr (adult tier) API key, projected into the mediamark keys dir as
|
||||
# /etc/mediamark/keys/radarr.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: radarr-apikey
|
||||
namespace: mediamark
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: radarr-apikey
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/mediamark/default/radarr
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
|
||||
Reference in New Issue
Block a user