Files
2026-08-27 17:52:23 +02:00

72 lines
4.6 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The secrets an operator writes. Minted ONCE, mounted by every pod.
#
# ─── READ THIS BEFORE YOU GENERATE ANYTHING ───────────────────────────────────────────────────
#
# There are two Secrets, and the split is not filing: `jarvis-generated` holds the values that are
# random bytes and `jarvis-secrets` — this file — holds the ones that are facts about your estate.
# One of those can be regenerated safely and the other cannot, so they do not share an object.
#
# The three keys below are here as the MANUAL path. If you would rather have them minted for you,
# apply `01-secret-job.yaml` instead and leave the `VAULT_*`/`JWT_*` lines out of this file
# entirely. Do not do both: `04-api.yaml` reads this Secret last on purpose, so a value typed here
# wins over a generated one, and the two quietly disagreeing is the shape of the accident.
#
# `apps/api/init-secrets.cjs` is the Compose generator, and it must NEVER become an initContainer
# here. Its guarantee that a key is minted exactly once is every writer sharing one filesystem.
# Per-pod, on an `emptyDir`, each replica generates its own — and the consequence is not a crash.
# Pod A seals a vault credential under a key pod B does not have; pod B reports that credential as
# corrupt; both pods log nothing at boot, because from each one's point of view everything is fine.
# By the time anybody notices, there are several keys in circulation and no way to tell which
# entries belong to which. `apps/api/mint-k8s-secret.cjs` is the same one-shot done correctly, with
# the API server's 409 standing in for the filesystem's exclusion.
#
# Either way, keep the output. The vault key in particular is the thing every stored credential is
# encrypted under — a database backup that travelled with its own key would be a backup that
# decrypts itself, which is why this lives apart from the database.
#
# VAULT_MASTER_KEY openssl rand -base64 32
# JWT_ACCESS_SECRET openssl rand -base64 48
# JWT_REFRESH_SECRET openssl rand -base64 48
#
# In anything beyond a trial, do not commit this file with values in it. Use SealedSecrets,
# ExternalSecrets, or `kubectl create secret generic` from a password manager.
# ──────────────────────────────────────────────────────────────────────────────────────────────
apiVersion: v1
kind: Secret
metadata:
name: jarvis-secrets
namespace: jarvis
type: Opaque
stringData:
# Everything in the vault is sealed under this. Lose it and the credentials are unreadable;
# leak it and a database dump is enough to read them all.
VAULT_MASTER_KEY: "REPLACE_ME"
JWT_ACCESS_SECRET: "REPLACE_ME"
JWT_REFRESH_SECRET: "REPLACE_ME"
# WHEN THE VAULT KEY WAS CREATED, as an ISO 8601 timestamp or epoch seconds.
#
# Set it when you mint the key, and never move it afterwards. On Compose this is inferred from the
# key file's modification time, which is a good answer on a volume nobody rewrites. Here it is a
# wrong one: the kubelet writes a projected Secret into every pod at start, so the mtime is the
# POD's age and every pod reports a key created seconds ago however old it is.
#
# What that number decides is narrow and serious. An instance with no accounts can have its first
# super-admin claimed by whoever reaches the install screen — unless the vault key is old, which
# means the database has gone missing from an instance that already existed (a bad restore, a PVC
# pointed at the wrong volume) and the claim needs proof of possession instead. Without this line,
# that check reads "brand new instance" on exactly the estate it exists to protect.
VAULT_KEY_CREATED_AT: "REPLACE_ME"
# `connection_limit` is not optional here, and it is the reason this URL is in the Secret rather
# than assembled from parts. Prisma's default pool is per-process: N pods times that default will
# exhaust `max_connections` long before the application is under any real load. Size it as
# (max_connections reserve) ÷ (replicas + maxSurge + jobs).
DATABASE_URL: "postgresql://jarvis:REPLACE_ME@postgres.jarvis.svc.cluster.local:5432/jarvis?schema=public&connection_limit=10&pool_timeout=20"
# Required to create new organizations, users or agents. Without it an instance keeps running
# everything it already has and creates nothing new. See the project README.
JARVIS_LICENSE_KEY: ""
OPENAI_API_KEY: "REPLACE_ME"