Skip to content

Commit f7297c9

Browse files
authored
feat(grafana): consolidate OIDC behind ArgoCD's Dex (#23)
## Summary Move Grafana off its built-in GitHub OAuth onto ArgoCD's embedded Dex, matching Headlamp's pattern. One Dex, one GitHub OAuth app, one team→role mapping in one place. Drops a separately-registered GitHub OAuth App (clientID \`Ov23liI2Cr1ur3xnZdlj\`) — that one can be removed from github.com/organizations/makeitworkcloud/settings/applications/ at your convenience. ## Changes - **\`bootstrap/argocd-config.yaml\`** — register \`grafana\` as a Dex static client. \`redirectURIs: [https://grafana.makeitwork.cloud/login/generic_oauth]\`. - **\`bootstrap/secrets/github-oauth-secret.yaml\`** — add sops-encrypted \`dex.grafana.clientSecret\` to argocd-secret. - **\`workloads/grafana/grafana.yaml\`** — replace the \`GF_AUTH_GITHUB_*\` env block with \`GF_AUTH_GENERIC_OAUTH_*\` pointing at \`https://argocd.makeitwork.cloud/api/dex/{auth,token,userinfo}\`. Update \`ROLE_ATTRIBUTE_PATH\` to match Dex's \`makeitworkcloud:admins\` group format (was GitHub's \`@makeitworkcloud/admins\`). - **\`workloads/grafana/grafana-oidc-secret.yaml\`** — new Secret \`grafana-oidc\` (sops-encrypted) with the matching \`GF_AUTH_GENERIC_OAUTH_CLIENT_ID=grafana\` + \`CLIENT_SECRET\`. Old \`grafana-github-oauth-secret.yaml\` deleted; \`ksops-grafana-secrets.yaml\` updated. - **\`.sops.yaml\`** — generalize the regex from \`GF_AUTH_GITHUB_CLIENT_SECRET\` to \`GF_AUTH_(GITHUB|GENERIC_OAUTH)_CLIENT_SECRET\`. ## Test plan - [ ] After merge: \`kubectl -n argocd get cm argocd-cm -o jsonpath='{.data.dex\\.config}'\` shows the new \`grafana\` static client - [x] After merge: \`kubectl -n grafana get secret grafana-oidc\` populated with both keys - [x] After merge: visiting \`https://grafana.makeitwork.cloud\` redirects to ArgoCD's GitHub-OAuth-via-Dex flow and lands on the dashboard with Admin / Viewer role per team membership - [x] After merge: revoke the standalone "Grafana" GitHub OAuth App at github.com/organizations/makeitworkcloud/settings/applications/ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 783cb84 commit f7297c9

7 files changed

Lines changed: 63 additions & 52 deletions

File tree

.sops.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
creation_rules:
33
# Default: encrypt only common secret fields
44
- age: age152ek83tm4fj5u70r3fecytn4kg7c5xca24erjchxexx4pfqg6das7q763l
5-
encrypted_regex: '^(token|api-token|apiToken|clientID|clientSecret|client_id|client_secret|password|secret|github_token|CLOUDFLARE_API_TOKEN|credentials\.json|.*_SERVICE_KEY|GF_AUTH_GITHUB_CLIENT_SECRET|GF_SECURITY_ADMIN_PASSWORD|dex\.[a-z]+\.clientID|dex\.[a-z]+\.clientSecret|OIDC_CLIENT_(ID|SECRET))$'
5+
encrypted_regex: '^(token|api-token|apiToken|clientID|clientSecret|client_id|client_secret|password|secret|github_token|CLOUDFLARE_API_TOKEN|credentials\.json|.*_SERVICE_KEY|GF_AUTH_(GITHUB|GENERIC_OAUTH)_CLIENT_SECRET|GF_SECURITY_ADMIN_PASSWORD|dex\.[a-z]+\.clientID|dex\.[a-z]+\.clientSecret|OIDC_CLIENT_(ID|SECRET))$'
66

77
# For Cloudflare credentials JSON (special case - entire value is secret)
88
- path_regex: cloudflared-credentials-secret\.yaml$

bootstrap/argocd-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ spec:
117117
secret: $dex.headlamp.clientSecret
118118
redirectURIs:
119119
- https://headlamp.makeitwork.cloud/oidc-callback
120+
# Grafana uses Dex via GF_AUTH_GENERIC_OAUTH_*, replacing its
121+
# built-in GitHub OAuth so all cluster apps share one IdP.
122+
- id: grafana
123+
name: Grafana
124+
secret: $dex.grafana.clientSecret
125+
redirectURIs:
126+
- https://grafana.makeitwork.cloud/login/generic_oauth
120127
# RBAC with GitHub team mapping
121128
rbac:
122129
defaultPolicy: ''

bootstrap/secrets/github-oauth-secret.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ stringData:
1515
dex.github.clientID: ENC[AES256_GCM,data:zPuSme7WNDyFt7bpeqtPy+tZyHU=,iv:mj2QOgHFdUFNNb4zm37MDQQ43FTQtx49Hg9w4k1XEEA=,tag:vWXANlK+Z/LZI3jwaYUhmw==,type:str]
1616
dex.github.clientSecret: ENC[AES256_GCM,data:g53ok+zuNccR47ngruY9HsXRO0JbGazW32MMduvfaim2QBKs03ATCg==,iv:QqaXEDFwKpaEC1Evdaj4j1jmJzbXpevMcYXxqLF1o8U=,tag:sAQU431fwCQH3vAYOm9O1Q==,type:str]
1717
dex.headlamp.clientSecret: ENC[AES256_GCM,data:iO6N04zWyzvaHcs8Bd2fIaYayDAHPonQM/0CI8wXynrH0nklrQpTBuFgCarJ5/iUbGKWKQsECEAH/yzTmqCNIg==,iv:eDlO8C0OJFSnp0d90Qgj2hJqCaa74Fw58dB/VNhFvZg=,tag:GcZdcjnSOab+LWfXgGb3lw==,type:str]
18+
dex.grafana.clientSecret: ENC[AES256_GCM,data:W83Zy4wsbNIUza47swtVAYjYbMiVSbLiPyBjEAj3cBHafRv4LMDtXCe/U9UWvyqMnsVdcXqsmE2FflDGQLBDcQ==,iv:nmsgCR7D35Tya0DRJZUMPtPEkElRJeqInzk4N2yMgP8=,tag:srmM2rscemUDOUjaz/fqhQ==,type:str]
1819
sops:
1920
age:
2021
- recipient: age152ek83tm4fj5u70r3fecytn4kg7c5xca24erjchxexx4pfqg6das7q763l
@@ -26,7 +27,7 @@ sops:
2627
T2dvNlRjNE1lNFVHWnJWNTA2Z2M5STgKUX9gEItGx811Wsq/GjUwe+pxyi9lt5gY
2728
uqKM/eXkZyz9S3HqinAhw5xiPEBokqmNcpaOHtHNgpgkhJY9YFCllQ==
2829
-----END AGE ENCRYPTED FILE-----
29-
lastmodified: "2026-04-30T03:57:26Z"
30-
mac: ENC[AES256_GCM,data:4iLUEDeiW+3mi4xMQPWHt3CM9f21u7cHDHkvKD58Q6fjaNVC1Flu7bdplgVZhCNqdBO9M0RbLB+X6Fu5miA2r5hKFoE1zQnQarPOurnw0R7Kf6qyLtNt9qWTkFqxjtcV6KhSx4ykSwue/9zY6/A1+SdxlIR5PhgRPT87M8vBl10=,iv:H1UB7A6yu7YV14/TtOaMhFBmoW11b8XoID7IKVMEghE=,tag:/eKksCPmLoRp69zIOtzJkA==,type:str]
30+
lastmodified: "2026-04-30T04:26:32Z"
31+
mac: ENC[AES256_GCM,data:NJvT2fUOM2YXni/Di/DJv0hnKOO65sqRnU2jfI1Dur4M2HWjnJTRJTehb4UVbc1GvkLwVCi80inWmheoW3eWjfwDRR74VHKWXQBEG50fDk6AfZMrugH1c71FjbhEzkk33VYIwMn0B2OOyeH06TceXQ6pRAzVfv6nG5zZ9hpo5d4=,iv:DH9adVlZBl99Oj2KGjkEUUfPCmyohyIJ5t6OTnWNQD8=,tag:PqDm8YllKQHS7utXKLI/Iw==,type:str]
3132
encrypted_regex: ^(token|api-token|apiToken|clientID|clientSecret|client_id|client_secret|password|secret|github_token|CLOUDFLARE_API_TOKEN|credentials\.json|.*_SERVICE_KEY|GF_AUTH_GITHUB_CLIENT_SECRET|GF_SECURITY_ADMIN_PASSWORD|dex\.[a-z]+\.clientID|dex\.[a-z]+\.clientSecret)$
3233
version: 3.12.2

workloads/grafana/grafana-github-oauth-secret.yaml

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# OAuth credentials Grafana uses against ArgoCD Dex (id: grafana).
2+
# clientSecret matches dex.grafana.clientSecret in argocd-secret.
3+
apiVersion: v1
4+
kind: Secret
5+
metadata:
6+
name: grafana-oidc
7+
namespace: grafana
8+
annotations:
9+
argocd.argoproj.io/sync-wave: "0"
10+
stringData:
11+
GF_AUTH_GENERIC_OAUTH_CLIENT_ID: grafana
12+
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: ENC[AES256_GCM,data:x0SqnOkBxlV6b6LSta/bh/49Y349iVn8oLbim97K8VuEvxAElE/5acX0ry3A4PcHGssqEY2c/86wxWkOsix4UA==,iv:z0c+Ktf2ZvegbupTjdVIfowAA4//aknWHDyY2douRQ0=,tag:Bm83Gs7+MITxnp1XPaWeQw==,type:str]
13+
sops:
14+
age:
15+
- recipient: age152ek83tm4fj5u70r3fecytn4kg7c5xca24erjchxexx4pfqg6das7q763l
16+
enc: |
17+
-----BEGIN AGE ENCRYPTED FILE-----
18+
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0T0VIVlAxRXNxNFpKZHFO
19+
ajR1U1hNUFB5VExGWVd0clFiRWxvVXVnN3dZCkpwSndGZE9IUUJ6K0I1Qmg4cjRi
20+
dDN4ZUpqUXVKdWR2TXhucUdBMEkxUzgKLS0tIHc4dWdnSDZrTlNVZGljdkkyMnd1
21+
cXFvaG4wOVRXYmczVVZrWmtCR1VsTUkK1+6S5QMqOa4CiQu5PXRM4QaXh/Vi129l
22+
4hTVPzC8RQXxyX09csXUQ/VEgiPJMeruqTIsT/waQlIlYhOQgN3hlw==
23+
-----END AGE ENCRYPTED FILE-----
24+
lastmodified: "2026-04-30T04:27:28Z"
25+
mac: ENC[AES256_GCM,data:psMmpT0VUufD/qgAuVS1IzLhDmBhObZqeVLUZZhvTPsE6mRP1FJckXgf9+7j16pVO2V5PJMx/rgOieQLvs57vW5VOq0A+7j3BLLwjpuHqXuMwbl6hsviOX7TqN45L318QlSVdGHgPB8BKqtJ7Zirz0RYNug1582E4QPXqrX7rQ0=,iv:f9GKrvv5moW+oKrO7N/3o4aDMnkuwUrqrhrEicYpXP4=,tag:m5JDOY0Sn720t6EnJzKO6Q==,type:str]
26+
encrypted_regex: ^(token|api-token|apiToken|clientID|clientSecret|client_id|client_secret|password|secret|github_token|CLOUDFLARE_API_TOKEN|credentials\.json|.*_SERVICE_KEY|GF_AUTH_(GITHUB|GENERIC_OAUTH)_CLIENT_SECRET|GF_SECURITY_ADMIN_PASSWORD|dex\.[a-z]+\.clientID|dex\.[a-z]+\.clientSecret|OIDC_CLIENT_(ID|SECRET))$
27+
version: 3.12.2

workloads/grafana/grafana.yaml

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,37 +33,39 @@ spec:
3333
secretKeyRef:
3434
name: grafana-admin-password
3535
key: GF_SECURITY_ADMIN_PASSWORD
36-
# GitHub OAuth
37-
- name: GF_AUTH_GITHUB_ENABLED
36+
# OIDC via ArgoCD's embedded Dex (Dex bridges to GitHub).
37+
- name: GF_AUTH_GENERIC_OAUTH_ENABLED
3838
value: "true"
39-
- name: GF_AUTH_GITHUB_ALLOW_SIGN_UP
39+
- name: GF_AUTH_GENERIC_OAUTH_NAME
40+
value: "GitHub"
41+
- name: GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP
4042
value: "true"
41-
- name: GF_AUTH_GITHUB_AUTO_LOGIN
43+
- name: GF_AUTH_GENERIC_OAUTH_AUTO_LOGIN
4244
value: "true"
4345
- name: GF_AUTH_DISABLE_LOGIN_FORM
4446
value: "true"
45-
- name: GF_AUTH_GITHUB_CLIENT_ID
47+
- name: GF_AUTH_GENERIC_OAUTH_CLIENT_ID
4648
valueFrom:
4749
secretKeyRef:
48-
name: grafana-github-oauth
49-
key: GF_AUTH_GITHUB_CLIENT_ID
50-
- name: GF_AUTH_GITHUB_CLIENT_SECRET
50+
name: grafana-oidc
51+
key: GF_AUTH_GENERIC_OAUTH_CLIENT_ID
52+
- name: GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET
5153
valueFrom:
5254
secretKeyRef:
53-
name: grafana-github-oauth
54-
key: GF_AUTH_GITHUB_CLIENT_SECRET
55-
- name: GF_AUTH_GITHUB_SCOPES
56-
value: "user:email,read:org"
57-
- name: GF_AUTH_GITHUB_AUTH_URL
58-
value: "https://github.com/login/oauth/authorize"
59-
- name: GF_AUTH_GITHUB_TOKEN_URL
60-
value: "https://github.com/login/oauth/access_token"
61-
- name: GF_AUTH_GITHUB_API_URL
62-
value: "https://api.github.com/user"
63-
- name: GF_AUTH_GITHUB_ALLOWED_ORGANIZATIONS
64-
value: "makeitworkcloud"
65-
- name: GF_AUTH_GITHUB_ROLE_ATTRIBUTE_PATH
66-
value: "contains(groups[*], '@makeitworkcloud/admins') && 'Admin' || contains(groups[*], '@makeitworkcloud/developers') && 'Viewer' || 'Viewer'"
55+
name: grafana-oidc
56+
key: GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET
57+
- name: GF_AUTH_GENERIC_OAUTH_SCOPES
58+
value: "openid profile email groups"
59+
- name: GF_AUTH_GENERIC_OAUTH_AUTH_URL
60+
value: "https://argocd.makeitwork.cloud/api/dex/auth"
61+
- name: GF_AUTH_GENERIC_OAUTH_TOKEN_URL
62+
value: "https://argocd.makeitwork.cloud/api/dex/token"
63+
- name: GF_AUTH_GENERIC_OAUTH_API_URL
64+
value: "https://argocd.makeitwork.cloud/api/dex/userinfo"
65+
# Dex emits groups as `org:team` (from the GitHub connector's
66+
# teamNameField: slug); map those to Grafana roles.
67+
- name: GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH
68+
value: "contains(groups[*], 'makeitworkcloud:admins') && 'Admin' || contains(groups[*], 'makeitworkcloud:developers') && 'Viewer' || 'Viewer'"
6769
persistentVolumeClaim:
6870
spec:
6971
accessModes:

workloads/grafana/ksops-grafana-secrets.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ metadata:
88
path: ksops
99
files:
1010
- grafana-admin-secret.yaml
11-
- grafana-github-oauth-secret.yaml
11+
- grafana-oidc-secret.yaml
1212
- tor-proxy-key-secret.yaml
1313
- status-tor-proxy-key-secret.yaml

0 commit comments

Comments
 (0)