|
| 1 | +--- |
| 2 | +title: "Example: OAuth2‑Proxy + Keep + GitLab SSO" |
| 3 | +--- |
| 4 | + |
| 5 | +A **step‑by‑step cookbook** for adding single‑sign‑on to [Keep](https://github.com/keephq) with your **self‑hosted GitLab** using [oauth2‑proxy](https://oauth2‑proxy.github.io/) and the NGINX Ingress Controller. |
| 6 | + |
| 7 | +> **Conventions used below** |
| 8 | +> |
| 9 | +> * `<keep-host>` – public FQDN where users access Keep (e.g. `keep.example.com`) |
| 10 | +> * `<gitlab-host>` – URL of your GitLab instance (e.g. `gitlab.example.com`) |
| 11 | +> * `<registry-host>` – container registry that stores images (omit if you use the public images) |
| 12 | +> * Kubernetes namespace **`keep`** – feel free to change it everywhere if you prefer another namespace. |
| 13 | +
|
| 14 | +--- |
| 15 | + |
| 16 | +## 1. Prerequisites |
| 17 | + |
| 18 | +| What | Why | |
| 19 | +| ------------------------------------------- | ----------------------------------------------------- | |
| 20 | +| Kubernetes cluster & `keep` namespace | Where Keep, oauth2‑proxy and Services live | |
| 21 | +| **ingress‑nginx** (or compatible) | Provides the `auth_request` feature oauth2‑proxy uses | |
| 22 | +| GitLab 15 + at `https://<gitlab-host>` | OpenID‑Connect issuer | |
| 23 | +| Helm 3.x & offline charts/images (optional) | If your cluster has no Internet egress | |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## 2. Create the GitLab OAuth application |
| 28 | + |
| 29 | +1. **GitLab ▸ Admin → Applications → New** |
| 30 | +2. Name → `keep‑sso` |
| 31 | +3. Redirect URI → `https://<keep-host>/oauth2/callback` |
| 32 | +4. Scopes → `openid profile email` (+ `read_api` if you plan to gate access by group/project) |
| 33 | +5. Save – copy the generated **Application ID** and **Secret**. |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## 3. Kubernetes secrets & config |
| 38 | + |
| 39 | +```bash |
| 40 | +# 3.1 Generate a 32‑byte cookie secret |
| 41 | +echo "$(openssl rand -base64 32 | head -c 32 | base64)" > cookie.b64 |
| 42 | + |
| 43 | +# 3.2 Store GitLab credentials and cookie secret |
| 44 | +kubectl -n keep create secret generic oauth2-proxy \ |
| 45 | + --from-literal=client-id=<GITLAB_APP_ID> \ |
| 46 | + --from-literal=client-secret=<GITLAB_APP_SECRET> \ |
| 47 | + --from-file=cookie-secret=cookie.b64 |
| 48 | + |
| 49 | +# 3.3 Add gitlab credentials and cookie secret using OAUTH2_PROXY ENV variables |
| 50 | +OAUTH2_PROXY_CLIENT_ID=<GITLAB_APP_ID> |
| 51 | +OAUTH2_PROXY_CLIENT_SECRET=<GITLAB_APP_SECRET> |
| 52 | +OAUTH2_PROXY_COOKIE_SECRET=cookie.b64 |
| 53 | + |
| 54 | +# (optional) store GitLab’s custom CA certificate |
| 55 | +kubectl -n keep create secret generic gitlab-ca \ |
| 56 | + --from-file=gitlab-ca.pem |
| 57 | +``` |
| 58 | + |
| 59 | +```yaml |
| 60 | +# 3.4 oauth2_proxy.cfg (ConfigMap) |
| 61 | +apiVersion: v1 |
| 62 | +kind: ConfigMap |
| 63 | +metadata: |
| 64 | + name: oauth2-proxy |
| 65 | + namespace: keep |
| 66 | +data: |
| 67 | + oauth2_proxy.cfg: | |
| 68 | + email_domains = ["*"] |
| 69 | + upstreams = ["file:///dev/null"] # we only use auth‑request mode |
| 70 | + provider = "gitlab" |
| 71 | + cookie_name = "keep-dev" #if empty, will use default cookie name: _oauth2_proxy |
| 72 | + cookie_secure = true |
| 73 | +``` |
| 74 | +
|
| 75 | +--- |
| 76 | +
|
| 77 | +## 4. Deploy **oauth2‑proxy** (Helm) |
| 78 | +
|
| 79 | +```yaml |
| 80 | +# values.oauth2-proxy.yaml – minimal baseline |
| 81 | +image: # replace with public image if desired |
| 82 | + repository: <registry-host>/oauth2-proxy/oauth2-proxy |
| 83 | + tag: v7.9.0 |
| 84 | + |
| 85 | +config: |
| 86 | + configFile: |- |
| 87 | + # content comes from the ConfigMap above |
| 88 | +
|
| 89 | +extraArgs: |
| 90 | + oidc-issuer-url: https://<gitlab-host> |
| 91 | + set-xauthrequest: "true" # add X-Auth-Request-*/X-Forwarded-* headers |
| 92 | + pass-authorization-header: "true" # add Authorization: Bearer <id_token> |
| 93 | + # provider-ca-file: /ca/gitlab-ca.pem # enable if you mounted a corporate CA or use ssl-insecure-skip-verify: "true" to disable SSL check. |
| 94 | +extraVolumes: |
| 95 | + - name: gitlab-ca |
| 96 | + secret: |
| 97 | + secretName: gitlab-ca |
| 98 | +extraVolumeMounts: |
| 99 | + - name: gitlab-ca |
| 100 | + mountPath: /ca/gitlab-ca.pem |
| 101 | + subPath: gitlab-ca.pem |
| 102 | + readOnly: true |
| 103 | + |
| 104 | +service: |
| 105 | + type: ClusterIP |
| 106 | + |
| 107 | +ingress: |
| 108 | + enabled: false # we only need an internal Service |
| 109 | +``` |
| 110 | +
|
| 111 | +```bash |
| 112 | +helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests |
| 113 | +helm upgrade --install oauth2-proxy oauth2-proxy/oauth2-proxy \ |
| 114 | + -n keep -f values.oauth2-proxy.yaml |
| 115 | +``` |
| 116 | + |
| 117 | +*Lab‑only shortcut*: instead of mounting the CA you can temporarily add |
| 118 | +`ssl-insecure-skip-verify: "true"` under `extraArgs`. |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +## 5. Patch (or create) Keep’s Ingress resource |
| 123 | + |
| 124 | +Add **three** annotations so ingress‑nginx delegates auth to the Service: |
| 125 | + |
| 126 | +```yaml |
| 127 | +global: |
| 128 | + ingress: |
| 129 | + annotations: |
| 130 | + nginx.ingress.kubernetes.io/auth-url: "http://oauth2-proxy.keep.svc.cluster.local/oauth2/auth" |
| 131 | + nginx.ingress.kubernetes.io/auth-signin: "https://<keep-host>/oauth2/start?rd=$request_uri" |
| 132 | + nginx.ingress.kubernetes.io/auth-response-headers: "authorization,x-auth-request-user,x-auth-request-email,x-forwarded-user,x-forwarded-email,x-forwarded-groups" |
| 133 | +``` |
| 134 | +
|
| 135 | +Redeploy Keep (or patch the Ingress manually). |
| 136 | +
|
| 137 | +--- |
| 138 | +
|
| 139 | +## 6. Environment variables for Keep |
| 140 | +
|
| 141 | +```yaml |
| 142 | +backend: |
| 143 | + env: |
| 144 | + - name: AUTH_TYPE |
| 145 | + value: OAUTH2PROXY |
| 146 | + - name: KEEP_OAUTH2_PROXY_USER_HEADER |
| 147 | + value: x-auth-request-email |
| 148 | + - name: KEEP_OAUTH2_PROXY_ROLE_HEADER |
| 149 | + value: x-auth-request-groups |
| 150 | + - name: KEEP_OAUTH2_PROXY_AUTO_CREATE_USER |
| 151 | + value: true |
| 152 | + - name: KEEP_OAUTH2_PROXY_ADMIN_ROLE |
| 153 | + vakue: <your gitlab group that will have admin role in your keep ui> |
| 154 | + - name: KEEP_OAUTH2_PROXY_NOC_ROLE |
| 155 | + value: <your gitlab group that wont have access to your keep ui> |
| 156 | + |
| 157 | +frontend: |
| 158 | + env: |
| 159 | + # Public URL the **browser** should use |
| 160 | + - name: NEXTAUTH_URL |
| 161 | + value: "https://<keep-host>" |
| 162 | + |
| 163 | + # URL the **server‑side** Next.js code can always reach |
| 164 | + - name: NEXTAUTH_URL_INTERNAL |
| 165 | + value: "http://keep-frontend.keep.svc.cluster.local:3000" |
| 166 | + |
| 167 | + # API URLs |
| 168 | + - name: API_URL_CLIENT # browser → ingress |
| 169 | + value: "/v2" |
| 170 | + - name: API_URL # server → backend Service (no auth‑proxy) |
| 171 | + value: "http://keep-backend.keep.svc.cluster.local:8080" |
| 172 | + |
| 173 | + #Oauth2-Proxy |
| 174 | + - name: AUTH_TYPE |
| 175 | + value: OAUTH2PROXY |
| 176 | + - name: KEEP_OAUTH2_PROXY_USER_HEADER |
| 177 | + value: x-auth-request-email |
| 178 | + - name: KEEP_OAUTH2_PROXY_ROLE_HEADER |
| 179 | + value: x-auth-request-groups |
| 180 | +``` |
| 181 | +
|
| 182 | +Roll out the frontend: |
| 183 | +
|
| 184 | +```bash |
| 185 | +kubectl -n keep rollout restart deploy/keep-frontend |
| 186 | +``` |
| 187 | + |
| 188 | +--- |
| 189 | + |
| 190 | +## 7. Quick validation |
| 191 | + |
| 192 | +```bash |
| 193 | +# 7.1 Call auth endpoint without cookie – expect 401 |
| 194 | +curl -I http://oauth2-proxy.keep.svc.cluster.local/oauth2/auth |
| 195 | + |
| 196 | +# 7.2 Copy the keep-dev cookie from your browser session |
| 197 | +curl -I --cookie "keep-dev=<COOKIE>" \ |
| 198 | + http://oauth2-proxy.keep.svc.cluster.local/oauth2/auth # expect 200 |
| 199 | +``` |
| 200 | + |
| 201 | +Browser smoke‑test: |
| 202 | + |
| 203 | +* `https://<keep-host>` → redirect to GitLab → sign in → return to Keep. |
| 204 | +* DevTools ▸ Network → `/api/auth/session` returns **200**. |
| 205 | + |
| 206 | +--- |
| 207 | + |
| 208 | +## 8. Troubleshooting |
| 209 | + |
| 210 | +| Symptom | Common cause & remedy | |
| 211 | +| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | |
| 212 | +| **TLS error** `x509: certificate signed by unknown authority` | Mount your GitLab CA (`provider-ca-file`) or set `ssl-insecure-skip-verify=true` (dev only). | |
| 213 | +| Ingress logs `auth request unexpected status: 502` | `auth-url` is pointing at the external host – use the internal Service DNS (`http://oauth2-proxy.keep.svc.cluster.local`). | |
| 214 | +| Browser loops at `/signin?callbackUrl=…` | ① `set-xauthrequest` not enabled, or ② `auth-response-headers` not set, or ③ backend receives calls through oauth2‑proxy (`API_URL` wrong). | |
| 215 | +| Redirect to `0.0.0.0:3000` or pod name | `NEXTAUTH_URL` missing at **build time**; rebuild UI or override env. | |
| 216 | +| 401 from `/oauth2/auth` even with cookie | Cookie expired / clocks out of sync. Clear cookie and re‑login. | |
| 217 | + |
| 218 | +--- |
| 219 | + |
| 220 | +## 9. Clean‑up |
| 221 | + |
| 222 | +```bash |
| 223 | +helm -n keep uninstall oauth2-proxy |
| 224 | +helm -n keep uninstall keep # if you want to remove Keep |
| 225 | +kubectl -n keep delete secret oauth2-proxy gitlab-ca |
| 226 | +``` |
| 227 | + |
| 228 | +--- |
| 229 | + |
| 230 | +## Appendix A – Generate a 32‑byte cookie secret |
| 231 | + |
| 232 | +```bash |
| 233 | +openssl rand -hex 16 | xxd -r -p | base64 |
| 234 | +``` |
| 235 | + |
| 236 | +## Appendix B – Sync images to an offline registry (example) |
| 237 | + |
| 238 | +```bash |
| 239 | +skopeo copy docker://quay.io/oauth2-proxy/oauth2-proxy:v7.9.0 \ |
| 240 | + docker://<registry-host>/oauth2-proxy/oauth2-proxy:v7.9.0 |
| 241 | +``` |
0 commit comments