Skip to content

Commit 971cfdd

Browse files
authored
Merge pull request #373 from OpenMS/claude/hide-demo-password-uB77g
k8s: mount admin password from streamlit-secrets Secret
2 parents 6f9c692 + 2cb4813 commit 971cfdd

7 files changed

Lines changed: 128 additions & 2 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ python*
1212
gdpr_consent/node_modules/
1313
*~
1414
.streamlit/secrets.toml
15+
k8s/**/streamlit-secrets.yaml
1516
docs/superpowers/

.streamlit/config.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ gatherUsageStats = false
44
[global]
55
developmentMode = false
66

7+
[secrets]
8+
# Kubernetes mounts the optional `streamlit-secrets` Secret at /app/admin-secrets/;
9+
# the default locations are kept so local `streamlit run` picks up ./.streamlit/secrets.toml.
10+
files = ["/app/admin-secrets/secrets.toml", "~/.streamlit/secrets.toml", ".streamlit/secrets.toml"]
11+
712
[server]
813
address = "0.0.0.0"
914
maxUploadSize = 200 #MB

.streamlit/secrets.toml.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Streamlit Secrets Configuration
22
# Copy this file to secrets.toml and fill in your values.
33
# IMPORTANT: Never commit secrets.toml to version control!
4+
#
5+
# For Kubernetes deployments, do NOT ship this file in the image -- instead
6+
# mount the password via the `streamlit-secrets` Secret. See
7+
# docs/kubernetes-deployment.md, "Configuring the admin password".
48

59
[admin]
610
# Password required to save workspaces as demo workspaces (online mode only)

docs/kubernetes-deployment.md

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ Traefik `IngressRoute` CRD. The default rule matches `PathPrefix('/')` (all path
141141
### `kustomization.yaml`
142142
Lists all base resources under the `openms` namespace.
143143

144+
### `streamlit-secrets.yaml.example`
145+
Reference manifest for the optional `streamlit-secrets` Secret consumed by the Streamlit Deployment (mounted as a directory at `/app/admin-secrets/`; `.streamlit/config.toml` registers that path under `[secrets].files` so `st.secrets` picks it up — currently used for the admin password that gates the "Save as Demo" feature). Intentionally **not** in `k8s/base/kustomization.yaml`: the Secret is created out-of-band so no password is ever committed. See "Configuring the admin password" below.
146+
144147
## 4. Fork-and-deploy guide
145148

146149
### Prerequisites
@@ -181,13 +184,50 @@ Open `k8s/overlays/<your-app-name>/kustomization.yaml` and change the following
181184

182185
The overlay leaves the nginx `Ingress` unpatched because Traefik is the production ingress. If you are deploying to an nginx-only cluster, add an overlay patch for both `rules[].host` entries in the base `Ingress` (same `.de` / `.org` pattern) instead of the IngressRoute patch.
183186

184-
### Step 5 — Deploy
187+
### Step 5 — Configure the admin password (optional)
188+
189+
Skip this step if you don't need the "Save as Demo" feature. The Streamlit Deployment mounts the `streamlit-secrets` Secret with `optional: true`, so the pod starts either way — the admin UI simply reports "Admin not configured" when the Secret is absent.
190+
191+
**Recommended — imperative, nothing on disk:**
192+
193+
```bash
194+
kubectl -n openms create secret generic streamlit-secrets \
195+
--from-literal=secrets.toml='[admin]
196+
password = "<your-strong-password>"'
197+
```
198+
199+
The password never leaves the cluster. Rotate the same way:
200+
201+
```bash
202+
kubectl -n openms create secret generic streamlit-secrets \
203+
--from-literal=secrets.toml='[admin]
204+
password = "<new-password>"' \
205+
--dry-run=client -o yaml | kubectl apply -f -
206+
kubectl -n openms rollout restart deployment/<your-app-name>-streamlit
207+
```
208+
209+
Because the Secret is created outside Kustomize, the overlay's `namePrefix` does **not** apply to it — the Deployment references the literal name `streamlit-secrets`, so create it with exactly that name.
210+
211+
**Alternative — manifest in the overlay:**
212+
213+
Copy the template and fill it in:
214+
215+
```bash
216+
cp k8s/base/streamlit-secrets.yaml.example k8s/overlays/<your-app-name>/streamlit-secrets.yaml
217+
# edit the password
218+
```
219+
220+
Add `- streamlit-secrets.yaml` to the `resources:` list in `k8s/overlays/<your-app-name>/kustomization.yaml`. The filename `streamlit-secrets.yaml` is gitignored (`.gitignore`: `k8s/**/streamlit-secrets.yaml`); always confirm with `git status` before committing — never commit a filled-in copy.
221+
222+
When the Secret is managed through Kustomize, the overlay's `namePrefix` rewrites both the Secret name and the Deployment reference, so no manual renaming is needed.
223+
224+
### Step 6 — Deploy
185225

186226
```bash
187227
kubectl apply -k k8s/overlays/<your-app-name>/
188228
```
189229

190-
### Step 6 — Verify
230+
### Step 7 — Verify
191231

192232
```bash
193233
kubectl -n openms get pods -l app=<your-app-name>

k8s/base/streamlit-deployment.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ spec:
5050
mountPath: /app/settings-overrides.json
5151
subPath: settings-overrides.json
5252
readOnly: true
53+
- name: admin-secrets
54+
mountPath: /app/admin-secrets
55+
readOnly: true
5356
readinessProbe:
5457
httpGet:
5558
path: /_stcore/health
@@ -76,3 +79,7 @@ spec:
7679
- name: config
7780
configMap:
7881
name: streamlit-config
82+
- name: admin-secrets
83+
secret:
84+
secretName: streamlit-secrets
85+
optional: true
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# EXAMPLE ONLY -- do NOT commit a filled-in copy of this file.
2+
#
3+
# This manifest shows the shape of the Secret consumed by the Streamlit
4+
# Deployment (mounted as a directory at /app/admin-secrets/ via volume
5+
# `admin-secrets`, which is declared with `optional: true` so the app still
6+
# runs when this Secret is absent; `.streamlit/config.toml` registers the
7+
# path under `[secrets].files` so `st.secrets` picks it up).
8+
#
9+
# Recommended path: create the Secret imperatively with
10+
#
11+
# kubectl -n openms create secret generic streamlit-secrets \
12+
# --from-literal=secrets.toml='[admin]
13+
# password = "<your-strong-password>"'
14+
#
15+
# so the password never touches disk outside the cluster. See
16+
# docs/kubernetes-deployment.md, "Configuring the admin password".
17+
#
18+
# Alternative path: copy this file to k8s/overlays/<your-app>/streamlit-secrets.yaml,
19+
# fill in a real password, and reference it from the overlay's
20+
# `resources:` list. The filename `streamlit-secrets.yaml` is gitignored,
21+
# but confirm with `git status` before committing anything.
22+
apiVersion: v1
23+
kind: Secret
24+
metadata:
25+
name: streamlit-secrets
26+
namespace: openms
27+
type: Opaque
28+
stringData:
29+
secrets.toml: |
30+
[admin]
31+
password = "your-secure-admin-password-here"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# EXAMPLE ONLY -- do NOT commit a filled-in copy of this file.
2+
#
3+
# Overlay-level copy of k8s/base/streamlit-secrets.yaml.example for the
4+
# `template-app` deployment. The Secret is consumed by the Streamlit
5+
# Deployment (mounted as a directory at /app/admin-secrets/ via volume
6+
# `admin-secrets`, which is declared with `optional: true` so the app still
7+
# runs when this Secret is absent; `.streamlit/config.toml` registers the
8+
# path under `[secrets].files` so `st.secrets` picks it up).
9+
#
10+
# Recommended path: create the Secret imperatively so the password never
11+
# touches disk outside the cluster. Note that the overlay's
12+
# `namePrefix: template-app-` only applies to resources managed by
13+
# Kustomize, so an out-of-band Secret must be created with the literal
14+
# name `streamlit-secrets`:
15+
#
16+
# kubectl -n openms create secret generic streamlit-secrets \
17+
# --from-literal=secrets.toml='[admin]
18+
# password = "<your-strong-password>"'
19+
#
20+
# See docs/kubernetes-deployment.md, "Configuring the admin password".
21+
#
22+
# Alternative path: copy this file to streamlit-secrets.yaml in this
23+
# directory, fill in a real password, and add `- streamlit-secrets.yaml`
24+
# to the `resources:` list in kustomization.yaml. When managed through
25+
# Kustomize, `namePrefix` rewrites both the Secret name and the Deployment
26+
# reference, so no manual renaming is needed. The filename
27+
# `streamlit-secrets.yaml` is gitignored, but confirm with `git status`
28+
# before committing anything.
29+
apiVersion: v1
30+
kind: Secret
31+
metadata:
32+
name: streamlit-secrets
33+
namespace: openms
34+
type: Opaque
35+
stringData:
36+
secrets.toml: |
37+
[admin]
38+
password = "your-secure-admin-password-here"

0 commit comments

Comments
 (0)