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
2 changed files with 22 additions and 1 deletions
+6
View File
@@ -1469,6 +1469,12 @@ ArgoCD will sync the Keycloak config, and the registrar CronJob will pick up the
| `k8s.secret.client-id-key` | No | `client-id` | Field name for the client ID in the K8s Secret | | `k8s.secret.client-id-key` | No | `client-id` | Field name for the client ID in the K8s Secret |
| `k8s.secret.client-secret-key` | No | `client-secret` | Field name for the client secret in the K8s Secret | | `k8s.secret.client-secret-key` | No | `client-secret` | Field name for the client secret in the K8s Secret |
#### Public CLI Client (Device-Code Login)
`forte-cli` is a shared **public** client (no secret) with the RFC 8628 device-authorization grant enabled (`oauth2.device.authorization.grant.enabled: "true"`, `standardFlowEnabled: false`, `directAccessGrantsEnabled: false`). Downloaded skills and CLI tools that log in through the Auth Sidecar (forte-drop first) use it with `<PREFIX>_CLIENT_ID=forte-cli`; nothing per-tool needs to be registered in Keycloak.
It must be defined in `forte-realm.json` (this legacy path): the self-service registrar hardcodes `publicClient: false` / `standardFlowEnabled: true` and drops `attributes`, so a `client-config` Secret cannot produce a public device-code client. It carries no `k8s.secret.sync` attribute (the registrar's secret sync skips it) and is listed in the cleanup CronJob's protected clients.
### Retrieving Secrets for External Deployments ### Retrieving Secrets for External Deployments
The registrar always writes a **central copy** of every synced secret to the `secrets` namespace, in addition to the target namespace. This allows operators to retrieve client credentials for applications deployed outside this cluster: The registrar always writes a **central copy** of every synced secret to the `secrets` namespace, in addition to the target namespace. This allows operators to retrieve client credentials for applications deployed outside this cluster:
+16 -1
View File
@@ -186,6 +186,21 @@ keycloakConfigCli:
} }
} }
] ]
},
{
"clientId": "forte-cli",
"name": "Forte CLI",
"description": "Shared public client for RFC 8628 device-code login from downloaded skills/CLI tools (forte-drop first) against services behind Auth Sidecar. No client secret.",
"enabled": true,
"protocol": "openid-connect",
"standardFlowEnabled": false,
"directAccessGrantsEnabled": false,
"publicClient": true,
"redirectUris": [],
"webOrigins": [],
"attributes": {
"oauth2.device.authorization.grant.enabled": "true"
}
} }
], ],
"browserFlow": "browser-auto-idp", "browserFlow": "browser-auto-idp",
@@ -671,7 +686,7 @@ extraDeploy:
MIN_AGE_SEC=$((MIN_AGE_DAYS * 86400)) MIN_AGE_SEC=$((MIN_AGE_DAYS * 86400))
# Hardcoded protected clients (never delete these) # Hardcoded protected clients (never delete these)
PROTECTED_JSON='["gitea","grafana","argocd","vaultwarden","account","account-console","admin-cli","broker","realm-management","security-admin-console"]' PROTECTED_JSON='["gitea","grafana","argocd","forte-cli","vaultwarden","account","account-console","admin-cli","broker","realm-management","security-admin-console"]'
echo "Fetching clients from realm '${REALM}'..." echo "Fetching clients from realm '${REALM}'..."
CLIENTS=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \ CLIENTS=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \