Wire API_TOKEN_PEPPERS into NetBox config
ci/woodpecker/pr/vector-test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful

NetBox 4.6.5 refuses to save v2 API tokens without API_TOKEN_PEPPERS
("Unable to save v2 tokens: API_TOKEN_PEPPERS is not defined"), blocking
creation of the superuser token the NetBox Vault engine needs. The chart
only auto-generates a pepper when it creates the config secret itself,
which it does not do while existingSecret (netbox-secret-key) is set, so
the config secret carries no api_token_peppers key.

- Document api_token_peppers on the netbox-secret-key VaultStaticSecret: a
  JSON pepper map {"1": "<random>"} seeded once into Vault alongside
  secret_key; VSO syncs it into the config secret the chart already mounts.
- Add a reloader annotation (commonAnnotations) so the web and worker
  Deployments roll when netbox-secret-key changes, picking up the seeded
  pepper without a manual restart.
This commit is contained in:
Ben Vincent
2026-08-09 12:19:24 +10:00
parent 2739a29778
commit f1d37f3b6e
2 changed files with 19 additions and 2 deletions
+7 -1
View File
@@ -19,7 +19,13 @@ spec:
type: kv-v2
vaultAuthRef: default
---
# Django SECRET_KEY (key: secret_key). One-time Vault seed.
# Config secret. Keys:
# secret_key : Django SECRET_KEY (50+ random chars). One-time Vault seed.
# api_token_peppers : JSON object {"1": "<50+ char random>"} used to HMAC-hash
# v2 API tokens. One-time Vault seed — rotating a pepper
# invalidates existing v2 tokens, so set it once.
# VSO syncs every key at the path into the destination Secret, and the NetBox
# chart mounts both keys from it (existingSecret) — no explicit key mapping needed.
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
+12 -1
View File
@@ -13,13 +13,24 @@ image:
# Two web replicas for zero-downtime rollouts (media is RWX, see below).
replicaCount: 2
# Django SECRET_KEY — existingSecret must contain key: secret_key.
# Config secret. Must contain key: secret_key (Django SECRET_KEY). Also carries
# api_token_peppers — a JSON object {"1": "<50+ char random>"} the chart mounts
# (optional file) into API_TOKEN_PEPPERS; NetBox 4.6 refuses to save v2 tokens
# without it. The chart only auto-generates a pepper when it creates this secret
# itself, which it does NOT do while existingSecret is set — so the pepper is
# seeded into Vault alongside secret_key (see base/vaultstaticsecret.yaml).
existingSecret: netbox-secret-key
# Bootstrap superuser — existingSecret keys: username, password, email, api_token.
superuser:
existingSecret: netbox-superuser
# Roll NetBox (web + worker) when the config secret changes, so a Vault-seeded
# api_token_peppers (or a rotated secret_key) is picked up without a manual
# restart. commonAnnotations lands on Deployment metadata, where reloader reads it.
commonAnnotations:
secret.reloader.stakater.com/reload: netbox-secret-key
# Disable the bundled Bitnami subcharts; we bring our own Postgres and Valkey.
postgresql:
enabled: false