From a99fd7d5d3dc71ad2463fdbd1405c2aeee14d0a8 Mon Sep 17 00:00:00 2001 From: Bharat Kathi Date: Wed, 17 Jun 2026 04:36:33 -0400 Subject: [PATCH] feat(sentinel): wire INTERNAL_BOOTSTRAP_SECRET + Discord login env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related additions from recent Sentinel PRs: 1. INTERNAL_BOOTSTRAP_SECRET (PR #79: s2s auth) Each non-core service now exchanges this shared secret at startup for its pre-seeded bearer JWT, then uses the JWT on every outbound sentinel-client call. Wired to core/discord/oauth/saml from a new key on sentinel-secrets. 2. Discord OAuth client config (PR #76: Login with Discord) The "Continue with Discord" button was merged + deployed via image bumps, but the env vars to make it actually work were never added to the oauth deployment. Adds DISCORD_CLIENT_ID + DISCORD_CLIENT_SECRET from sentinel-secrets and a prod-URL DISCORD_REDIRECT_URI inline. Operator todo before this rolls: Add three new keys to the sentinel-secrets Secret. Same value across every service for INTERNAL_BOOTSTRAP_SECRET — generate with `openssl rand -hex 32`. Discord client id/secret come from the registered application at discord.com/developers. kubectl -n sentinel edit secret sentinel-secrets # Add (base64-encoded values): # INTERNAL_BOOTSTRAP_SECRET # DISCORD_CLIENT_ID # DISCORD_CLIENT_SECRET Then make sure the Discord application has https://sentinel-v5.gauchoracing.com/auth/login/discord registered as an authorized redirect URI. After the secret is populated, the auto-image-bump PR for the next Sentinel release will roll this into prod cleanly. If the secret isn't populated when this lands, the new bootstrap call from non-core services will fail closed (each retries with backoff, then the pod restarts) — no silent data corruption, just CrashLoopBackOff until the operator catches up. --- kubernetes/manifests/sentinel/core.yaml | 9 ++++++++ kubernetes/manifests/sentinel/discord.yaml | 7 ++++++ kubernetes/manifests/sentinel/oauth.yaml | 25 ++++++++++++++++++++++ kubernetes/manifests/sentinel/saml.yaml | 8 +++++++ 4 files changed, 49 insertions(+) diff --git a/kubernetes/manifests/sentinel/core.yaml b/kubernetes/manifests/sentinel/core.yaml index 79121ef..83267ec 100644 --- a/kubernetes/manifests/sentinel/core.yaml +++ b/kubernetes/manifests/sentinel/core.yaml @@ -67,6 +67,15 @@ spec: # group on each boot. Idempotent — safe to leave as-is. - name: ADMIN_ENTITY_IDS value: "ent_01kt38a23b9ya1w5x4t9dasd86" + # Shared secret each non-core service exchanges at startup + # for its pre-seeded bearer JWT. Same value as on every + # other sentinel-* deployment. Rotating it requires a + # rolling restart of every service so each can re-fetch. + - name: INTERNAL_BOOTSTRAP_SECRET + valueFrom: + secretKeyRef: + name: sentinel-secrets + key: INTERNAL_BOOTSTRAP_SECRET --- apiVersion: v1 kind: Service diff --git a/kubernetes/manifests/sentinel/discord.yaml b/kubernetes/manifests/sentinel/discord.yaml index fbdab64..2078a57 100644 --- a/kubernetes/manifests/sentinel/discord.yaml +++ b/kubernetes/manifests/sentinel/discord.yaml @@ -69,6 +69,13 @@ spec: secretKeyRef: name: sentinel-secrets key: DISCORD_TOKEN + # Same value as on core; used at startup to exchange for + # this service's pre-seeded bearer JWT. + - name: INTERNAL_BOOTSTRAP_SECRET + valueFrom: + secretKeyRef: + name: sentinel-secrets + key: INTERNAL_BOOTSTRAP_SECRET --- apiVersion: v1 kind: Service diff --git a/kubernetes/manifests/sentinel/oauth.yaml b/kubernetes/manifests/sentinel/oauth.yaml index 266544b..b2f4951 100644 --- a/kubernetes/manifests/sentinel/oauth.yaml +++ b/kubernetes/manifests/sentinel/oauth.yaml @@ -70,6 +70,31 @@ spec: # ID tokens have to be byte-identical for relying parties. - name: ISSUER value: https://sentinel-v5.gauchoracing.com + # Discord OAuth client config for the "Continue with Discord" + # login button. Client id/secret are the Discord application's + # credentials; the redirect URI must byte-match what the web + # client sends in its authorize call (and what's registered + # on the Discord application's OAuth2 settings). + - name: DISCORD_CLIENT_ID + valueFrom: + secretKeyRef: + name: sentinel-secrets + key: DISCORD_CLIENT_ID + - name: DISCORD_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: sentinel-secrets + key: DISCORD_CLIENT_SECRET + - name: DISCORD_REDIRECT_URI + value: https://sentinel-v5.gauchoracing.com/auth/login/discord + # Shared secret exchanged at startup for this service's + # pre-seeded bearer JWT. Same value as every other + # sentinel-* deployment. + - name: INTERNAL_BOOTSTRAP_SECRET + valueFrom: + secretKeyRef: + name: sentinel-secrets + key: INTERNAL_BOOTSTRAP_SECRET --- apiVersion: v1 kind: Service diff --git a/kubernetes/manifests/sentinel/saml.yaml b/kubernetes/manifests/sentinel/saml.yaml index 4419fbb..7709345 100644 --- a/kubernetes/manifests/sentinel/saml.yaml +++ b/kubernetes/manifests/sentinel/saml.yaml @@ -79,6 +79,14 @@ spec: # registered service provider. - name: ISSUER value: https://sentinel-v5.gauchoracing.com + # Shared secret exchanged at startup for this service's + # pre-seeded bearer JWT. Same value as every other + # sentinel-* deployment. + - name: INTERNAL_BOOTSTRAP_SECRET + valueFrom: + secretKeyRef: + name: sentinel-secrets + key: INTERNAL_BOOTSTRAP_SECRET --- apiVersion: v1 kind: Service