ci: enable oidc for jenkins/gitops/gitea
This commit is contained in:
parent
04602a2914
commit
a46226bb0a
@ -55,6 +55,12 @@ spec:
|
||||
value: "master"
|
||||
- name: ROOT_URL
|
||||
value: "https://scm.bstein.dev"
|
||||
- name: GITEA__service__ENABLE_OPENID_SIGNIN
|
||||
value: "true"
|
||||
- name: GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION
|
||||
value: "true"
|
||||
- name: GITEA__service__DISABLE_REGISTRATION
|
||||
value: "false"
|
||||
- name: DB_TYPE
|
||||
value: "postgres"
|
||||
- name: DB_HOST
|
||||
|
||||
@ -7,3 +7,4 @@ resources:
|
||||
- service.yaml
|
||||
- pvc.yaml
|
||||
- ingress.yaml
|
||||
- oidc-job.yaml
|
||||
|
||||
85
services/gitea/oidc-job.yaml
Normal file
85
services/gitea/oidc-job.yaml
Normal file
@ -0,0 +1,85 @@
|
||||
# services/gitea/oidc-job.yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: gitea-oidc-bootstrap
|
||||
namespace: gitea
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 1800
|
||||
backoffLimit: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: gitea
|
||||
job: gitea-oidc-bootstrap
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
affinity:
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchLabels:
|
||||
app: gitea
|
||||
topologyKey: kubernetes.io/hostname
|
||||
restartPolicy: OnFailure
|
||||
volumes:
|
||||
- name: gitea-data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-data
|
||||
containers:
|
||||
- name: gitea-oidc-bootstrap
|
||||
image: gitea/gitea:1.23
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
env:
|
||||
- name: CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: gitea-oidc
|
||||
key: client_id
|
||||
- name: CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: gitea-oidc
|
||||
key: client_secret
|
||||
- name: DISCOVERY_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: gitea-oidc
|
||||
key: openid_auto_discovery_url
|
||||
command:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
set -euo pipefail
|
||||
APPINI=/data/gitea/conf/app.ini
|
||||
BIN=/usr/local/bin/gitea
|
||||
list="$($BIN -c "$APPINI" admin auth list)"
|
||||
id=$(echo "$list" | awk '$2=="keycloak"{print $1}')
|
||||
if [ -n "$id" ]; then
|
||||
echo "Updating existing auth source id=$id"
|
||||
$BIN -c "$APPINI" admin auth update-oauth \
|
||||
--id "$id" \
|
||||
--name keycloak \
|
||||
--provider openidConnect \
|
||||
--key "$CLIENT_ID" \
|
||||
--secret "$CLIENT_SECRET" \
|
||||
--auto-discover-url "$DISCOVERY_URL" \
|
||||
--scopes "openid profile email" \
|
||||
--group-claim-name groups
|
||||
else
|
||||
echo "Creating keycloak auth source"
|
||||
$BIN -c "$APPINI" admin auth add-oauth \
|
||||
--name keycloak \
|
||||
--provider openidConnect \
|
||||
--key "$CLIENT_ID" \
|
||||
--secret "$CLIENT_SECRET" \
|
||||
--auto-discover-url "$DISCOVERY_URL" \
|
||||
--scopes "openid profile email" \
|
||||
--group-claim-name groups
|
||||
fi
|
||||
@ -23,13 +23,10 @@ spec:
|
||||
remediateLastFailure: true
|
||||
cleanupOnFail: true
|
||||
values:
|
||||
additionalArgs:
|
||||
- --auth-methods=oidc
|
||||
adminUser:
|
||||
create: true
|
||||
createClusterRole: true
|
||||
createSecret: true
|
||||
username: admin
|
||||
# bcrypt hash for temporary password "G1tOps!2025" (rotate after login)
|
||||
passwordHash: "$2y$12$wDEOzR1Gc2dbvNSJ3ZXNdOBVFEjC6YASIxnZmHIbO.W1m0fie/QVi"
|
||||
create: false
|
||||
ingress:
|
||||
enabled: true
|
||||
className: traefik
|
||||
@ -45,5 +42,7 @@ spec:
|
||||
- secretName: gitops-ui-tls
|
||||
hosts:
|
||||
- cd.bstein.dev
|
||||
oidcSecret:
|
||||
create: false
|
||||
metrics:
|
||||
enabled: true
|
||||
|
||||
@ -7,3 +7,4 @@ resources:
|
||||
- helmrelease.yaml
|
||||
- certificate.yaml
|
||||
- networkpolicy-acme.yaml
|
||||
- rbac.yaml
|
||||
|
||||
15
services/gitops-ui/rbac.yaml
Normal file
15
services/gitops-ui/rbac.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
# services/gitops-ui/rbac.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: gitops-admins
|
||||
labels:
|
||||
app.kubernetes.io/name: weave-gitops
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
@ -44,7 +44,7 @@ spec:
|
||||
- oic-auth
|
||||
containerEnv:
|
||||
- name: ENABLE_OIDC
|
||||
value: "false"
|
||||
value: "true"
|
||||
- name: OIDC_ISSUER
|
||||
value: "https://sso.bstein.dev/realms/atlas"
|
||||
- name: OIDC_CLIENT_ID
|
||||
@ -85,50 +85,45 @@ spec:
|
||||
optional: true
|
||||
initScripts:
|
||||
oidc.groovy: |
|
||||
import hudson.util.Secret
|
||||
import jenkins.model.IdStrategy
|
||||
import jenkins.model.Jenkins
|
||||
import org.jenkinsci.plugins.oic.OicSecurityRealm
|
||||
import org.jenkinsci.plugins.oic.OicServerWellKnownConfiguration
|
||||
def env = System.getenv()
|
||||
def enable = (env['ENABLE_OIDC'] ?: 'false').toBoolean()
|
||||
if (!enable) {
|
||||
if (!(env['ENABLE_OIDC'] ?: 'false').toBoolean()) {
|
||||
println("OIDC disabled (ENABLE_OIDC=false); keeping default security realm")
|
||||
return
|
||||
}
|
||||
def required = ['OIDC_CLIENT_ID','OIDC_CLIENT_SECRET','OIDC_AUTH_URL','OIDC_TOKEN_URL','OIDC_USERINFO_URL']
|
||||
def required = ['OIDC_CLIENT_ID','OIDC_CLIENT_SECRET','OIDC_ISSUER']
|
||||
if (!required.every { env[it] }) {
|
||||
println("OIDC enabled but missing vars: ${required.findAll { !env[it] }}")
|
||||
return
|
||||
}
|
||||
try {
|
||||
def wellKnown = "${env['OIDC_ISSUER']}/.well-known/openid-configuration"
|
||||
def serverCfg = new OicServerWellKnownConfiguration(wellKnown)
|
||||
serverCfg.setScopesOverride('openid profile email')
|
||||
def realm = new OicSecurityRealm(
|
||||
env['OIDC_CLIENT_ID'],
|
||||
env['OIDC_CLIENT_SECRET'],
|
||||
env['OIDC_TOKEN_URL'],
|
||||
env['OIDC_AUTH_URL'],
|
||||
env['OIDC_USERINFO_URL'],
|
||||
true, // logout from provider
|
||||
env['OIDC_LOGOUT_URL'] ?: "",
|
||||
"", // postLogoutRedirectUrl
|
||||
"openid email profile",
|
||||
"", // prompt
|
||||
"preferred_username",
|
||||
"name",
|
||||
"email",
|
||||
false, // disableSslVerification
|
||||
true, // escapeHatchEnabled
|
||||
"admin",
|
||||
"", // escapeHatchSecret
|
||||
"", // escapeHatchGroup
|
||||
true, // loadUserInfo
|
||||
true, // validateScopes
|
||||
false, // allowUnsignedIdTokens
|
||||
false, // enforceValidIssuers
|
||||
env['OIDC_ISSUER'] ?: "",
|
||||
false // disableUserInfoFetch
|
||||
Secret.fromString(env['OIDC_CLIENT_SECRET']),
|
||||
serverCfg,
|
||||
false,
|
||||
IdStrategy.CASE_INSENSITIVE,
|
||||
IdStrategy.CASE_INSENSITIVE
|
||||
)
|
||||
realm.setLogoutFromOpenidProvider(true)
|
||||
realm.setPostLogoutRedirectUrl('https://ci.bstein.dev')
|
||||
realm.setUserNameField('preferred_username')
|
||||
realm.setFullNameFieldName('name')
|
||||
realm.setEmailFieldName('email')
|
||||
realm.setGroupsFieldName('groups')
|
||||
realm.setRootURLFromRequest(true)
|
||||
realm.setSendScopesInTokenRequest(true)
|
||||
def j = Jenkins.get()
|
||||
j.setSecurityRealm(realm)
|
||||
j.save()
|
||||
println("Configured OIDC realm from init script")
|
||||
println("Configured OIDC realm from init script (well-known)")
|
||||
} catch (Exception e) {
|
||||
println("Failed to configure OIDC realm: ${e}")
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user