feat(keycloak): add forte-cli public device-code client #26
Closed
jorgen.stensrud
wants to merge 1 commits from
fm/launchpad-forte-cli into main
pull from: fm/launchpad-forte-cli
merge into: :main
:main
:renovate/prometheus-29.x
:renovate/traefik-41.x
:renovate/aws-6.x
:renovate/google-8.x
:fm/launchpad-forte-cli
:renovate/grafana-10.x
:renovate/kubernetes-monorepo
:feature/forte-prod
:fix/drop-duplicate-keycloak-secret
:feature/dns01
:feat/forte-drop-infra
:feature/ppusher
:feature/chibisafe
:hotfix/backup
:feature/vault-migration
:feature/hashicorp-vault
:feature/homepage
:feature/argocd-rbac
:feature/argocd-tls
:feature/multi-cloud
:feature/karpor
:feature/backstage
:feature/ai-review
:gitea-pages
:feature/gitea-docs
:feature/multicluster
:feature/secret-syncing
:feature/smtp
No Reviewers
Milestone
No items
No Milestone
Assignees
aslak.ege (Aslak Ege)
danijel.simeunovic (Danijel Simeunovic)
edvard.unsvag (Edvard Unsvåg)
ellina.ivleva (Ellina Ivleva)
gitea_admin
henrik.farstad
jorgen.stensrud (Jørgen Stensrud)
kristoffer.kopperud (Kristoffer Markus Kopperud)
ola.skarphol
oystein.roti (Øystein Roti)
peter.froystad
petter.schultz (Petter Schultz)
ragnhild.hande (Ragnhild Aaraas Hånde)
Thomas-Mannsverk-Eliassen (Thomas Mannsverk Eliassen)
thomas.solbjor (Thomas Solbjor)
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Forte/launchpad#26
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
Adds a shared public OIDC client
forte-clito theforterealm with the RFC 8628 device-authorization grant enabled, so downloaded skills / CLI tools (forte-drop'sdrop.sh loginfirst) can log in through the Auth Sidecar. Today no client in the realm hasoauth2.device.authorization.grant.enabled, so the device-code flow cannot even start (k8s rollout plan §2.2a, step 0a). All skills reuse it via<PREFIX>_CLIENT_ID=forte-cli.Client config (inline in
forte-realm.json,infra/values/base/keycloak-values.yaml)k8s.secret.sync, so the registrar's legacy sync skips it).standardFlowEnabled: false,directAccessGrantsEnabled: false, emptyredirectUris/webOrigins: the only usable grant is device-code.Why the realm JSON and not a
client-configSecretThe self-service registrar (jq block around line 520-532) hardcodes
publicClient: false/standardFlowEnabled: trueand dropsattributes, so it cannot produce this client. The inlineclientslist bypasses the registrar entirely: the Bitnami chart renderskeycloakConfigCli.configurationverbatim into thekeycloak-keycloak-config-cli-configmapConfigMap (IMPORT_FILES_LOCATIONS=/config/*), and keycloak-config-cli 6.4.0 imports the client representation as-is. The registrar's legacy path only reads clients withk8s.secret.sync=trueto sync secrets; it never rewrites clients.Environments
Keycloak is deployed only by the
upc-devoverlay (infra/overlays/upc-dev/kustomization.yaml->infra/base/keycloak), whose Application usesbase+upc-devvalues, andupc-devonly overridesingress.hostname. Theupc-prodoverlay has no Keycloak Application. Sobaseis the right (and only) place, and this lands onid.forteapps.net, the realm forte-drop-mcp uses.Scope / safety
gitea,grafana,argocdand all other realm settings are byte-identical tomain(checked by parsing the realm JSON before/after).forte-cliis also added to the cleanup CronJob'sPROTECTED_JSONlist, next tovaultwarden. Belt-and-braces: the cleanup only targets UUID-shaped clientIds anyway. Happy to drop that one line if you want the diff to be the client only.docs/DEVELOPER-GUIDE.md.Verification done
helm templatewith chart 25.2.0 + both value files (as in the Argo Application) renders cleanly (23 resources).forte-realm.jsonparses;forte-cliis present withpublicClient: true,standardFlowEnabled: false,directAccessGrantsEnabled: false, device-grant attribute"true"; nosecret, nok8s.secret.sync. It is the only device-grant client in the realm.sh -n; cleanup script differs frommainonly inPROTECTED_JSON.The second call should return
device_code/user_code/verification_uriinstead ofunauthorized_client.Follow-ups (not in this MR)
resource=so the tokenaudmatches the sidecar'sAUTH_MCP_RESOURCE. If Keycloak does not honour it for device-code tokens, add oneoidc-audience-mapperper resource onforte-cli.done < <(...)(bash process substitution) under/bin/shon alpine;sh -nrejects it onmaintoo. Worth a separate look.Auth infra: please do not merge without captain sign-off.
🤖 Generated with Claude Code
https://claude.ai/code/session_01QciXev3MtCxo3eomcfrDRW
46eab199eetod087472e63Superseded by #44, which contains this commit unchanged (same
forte-cliclient) plus the audience mapper the forte-drop-mcp sidecar needs. Closing in favour of merging #44 alone.Pull request closed