Compare commits

..
Author SHA1 Message Date
d087472e63 Add forte-cli public device-code Keycloak client
AI Code Review / ai-review (pull_request) Skipped
scan.yaml / test (pull_request) Successful in 27s
Add a shared public client `forte-cli` to the `forte` realm so downloaded
skills (forte-drop first) can do RFC 8628 device-code login through the
Auth Sidecar. Today no client in the realm has the device grant enabled,
so the flow cannot start.

Client (inline in forte-realm.json, imported verbatim by keycloak-config-cli):
- publicClient: true, standardFlowEnabled: false,
  directAccessGrantsEnabled: false
- attributes: oauth2.device.authorization.grant.enabled=true
- no secret, no redirectUris/webOrigins, no k8s.secret.sync

It has to go in the realm JSON because the self-service registrar
hardcodes publicClient:false/standardFlowEnabled:true and drops
attributes. Also add forte-cli to the cleanup CronJob's protected list
(belt-and-braces; it does not match the UUID pattern anyway).

Additive only: gitea/grafana/argocd and all other realm settings are
unchanged. Keycloak is deployed only via the upc-dev overlay, which
inherits base values, so this lands on id.forteapps.net.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciXev3MtCxo3eomcfrDRW
2026-10-01 10:37:49 +00:00
60b8fa657a chore(deps): update nikitafilonov/ai-review docker tag to v1 (#53)
scan.yaml / test (push) Successful in 8s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| nikitafilonov/ai-review | docker | major | `v0.77.0` → `v1.1.0` |

---

### Configuration

📅 **Schedule**: (in timezone Europe/Oslo)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMTIuMyIsInVwZGF0ZWRJblZlciI6IjQ0LjExMi4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->

---------

Co-authored-by: Renovate Bot <renovate@forteapps.net>
Reviewed-on: #53
Reviewed-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
Co-authored-by: gitea_admin <admin@forteapps.net>
2026-10-01 09:40:57 +00:00
7 changed files with 28 additions and 7 deletions
+2 -2
View File
@@ -41,11 +41,11 @@ jobs:
run: git submodule update --remote --merge
- name: Run inline review
uses: docker://nikitafilonov/ai-review:v0.77.0
uses: docker://nikitafilonov/ai-review:v1.1.0
with:
args: ai-review run-inline
- name: Run summary review
uses: docker://nikitafilonov/ai-review:v0.77.0
uses: docker://nikitafilonov/ai-review:v1.1.0
with:
args: ai-review run-summary
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
version = "~> 5.0"
}
tls = {
source = "hashicorp/tls"
@@ -2,7 +2,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
version = "~> 5.0"
}
tls = {
source = "hashicorp/tls"
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
version = "~> 5.0"
}
tls = {
source = "hashicorp/tls"
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
version = "~> 5.0"
}
tls = {
source = "hashicorp/tls"
+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-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
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",
@@ -671,7 +686,7 @@ extraDeploy:
MIN_AGE_SEC=$((MIN_AGE_DAYS * 86400))
# 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}'..."
CLIENTS=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \