Loading README.md +1 −1 Changes for README.md: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ Keycloak (`charts/keycloak`) runs as a platform service in `oop`, backed by the | Realm | Used by | Clients | |---|---|---| | `oop` | Portal users, app providers, OEG | `oop-portal` (confidential, Auth Code + PKCE), `oeg` (audience only) | | `federation` | FM, partner OPs (ADR-0042) | `originating-op-1`, `originating-op-2` (client credentials, scope `fed-mgmt`) | | `federation` | FM, partner OPs (ADR-0042) | `originating-op-1`, `originating-op-2` (client credentials, scope `fed-mgmt`; `fed-mgmt-notif` optional, for callbacks) | - Realm roles in `oop` (ADR-0048): `app-provider` (developers; given to every new user, including self-registered ones), `operator` (runs the platform) and `platform-admin` (manages users). None Loading oop-platform-chart/charts/keycloak/README.md +16 −1 Changes for oop-platform-chart/charts/keycloak/README.md: 16 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -149,6 +149,14 @@ The source of this model is ADR-0048. Roles say **what** someone may do. They do not say **whose data** they may see; that is the organization's job ([section 9](#9-organizations-and-tenants)). ### CAMARA scopes Portal tokens also carry one scope per CAMARA operation (QoD, Edge Application Management, Location Retrieval), named as in each API's OpenAPI `security` block. The list lives in [`files/camara-scopes.yaml`](files/camara-scopes.yaml): add an entry there when OEG gains an operation. On an existing installation, also create the scope in the admin console and add it to `oop-portal` as **Default** ([Change realm settings after install](#change-realm-settings-after-install)). ### Clients | Client | Kind | Used by | What it does | Loading Loading @@ -201,6 +209,13 @@ unless Keycloak's public URL is `http://localhost[:port]` or `http://127.0.0.1[: - Each partner client can only use **client credentials** (machine to machine). No browser, no password. - Every token carries the scope **`fed-mgmt`** (the name the GSMA OPG.04 API contract requires) and the audience **`federation-manager`**, which Federation Manager checks. - Partners sending us a **callback** (federation status, instance status, zone updates) ask for **`fed-mgmt-notif`** too (`scope=fed-mgmt-notif` in the token request). It is an *optional* scope, so only tokens that request it carry it: a normal API token is not a callback token. Both names come from `global.federation.scopes`. On an installation older than this scope, add it by hand: realm `federation` → **Client scopes** → **Create client scope** (name `fed-mgmt-notif`, protocol OpenID Connect), then on each partner client → **Client scopes** → **Add client scope** → `fed-mgmt-notif` as **Optional**. - Each partner has its **own** secret, generated into `keycloak-credentials` as `federation-<client id>-secret`. We give it to that partner over a secure channel. One partner's secret never works for another partner. Loading Loading @@ -474,7 +489,7 @@ Use the same ID for everyone in the same organization: it is compared exactly. create the client in the admin console (realm `federation` → **Clients** → **Create client**): - Client ID: the same ID; **Client authentication** on; only **Service accounts roles** ticked. - **Credentials** tab: paste the secret from `keycloak-credentials`. - **Client scopes** tab: add `fed-mgmt` as **Default**. - **Client scopes** tab: add `fed-mgmt` as **Default** and `fed-mgmt-notif` as **Optional**. - **Client scopes** → `<client id>-dedicated` → **Add mapper** → **By configuration** → **Audience**: *Included Custom Audience* `federation-manager`, *Add to access token* on. 3. Send the client ID and secret to the partner over a secure channel, together with our token URL: Loading oop-platform-chart/charts/keycloak/files/camara-scopes.yaml 0 → 100644 +35 −0 Changes for oop-platform-chart/charts/keycloak/files/camara-scopes.yaml: 35 added lines, 0 removed lines. Original line number Diff line number Diff line # CAMARA operation scopes of realm `oop`, one per operation across QoD, Edge Application # Management and Location Retrieval. Names match each API's OpenAPI `security` block. # Every scope here is created in the realm and issued on portal tokens. - name: "edge-application-management:apps:read" description: "List/view applications" - name: "edge-application-management:apps:write" description: "Register applications" - name: "edge-application-management:apps:delete" description: "Delete applications" - name: "edge-application-management:instances:read" description: "List/view app instances" - name: "edge-application-management:instances:write" description: "Create app instances" - name: "edge-application-management:instances:delete" description: "Delete app instances" - name: "edge-application-management:deployments:read" description: "List/view app deployments" - name: "edge-application-management:deployments:write" description: "Create app deployments" - name: "edge-application-management:deployments:update" description: "Update app deployments" - name: "edge-application-management:deployments:delete" description: "Delete app deployments" - name: "edge-application-management:clusters:read" description: "List clusters" - name: "edge-application-management:edge-cloud-zones:read" description: "List edge cloud zones" - name: "qod-sessions-read" description: "Retrieval of QoS sessions" - name: "qod-sessions-write" description: "Creation and update of QoS sessions" - name: "qod-sessions-delete" description: "Deletion of QoS sessions" - name: "location-retrieval:read" description: "Retrieve a device's location" oop-platform-chart/charts/keycloak/templates/_helpers.tpl +14 −0 Changes for oop-platform-chart/charts/keycloak/templates/_helpers.tpl: 14 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -100,6 +100,20 @@ Audience added to partner tokens in the `federation` realm; Federation Manager r {{- .Values.realms.federation.audience | default (dig "federation" "audience" "federation-manager" (.Values.global | default dict)) -}} {{- end }} {{/* OPG.04 scope names in the `federation` realm, from global.federation.scopes: `api` for normal E/WBI calls (default scope of every partner client), `notif` for callbacks (optional scope, so only tokens that request it carry it). The federation-manager chart should read the same globals. Usage: include "keycloak.federationScope" (list $ "api") */}} {{- define "keycloak.federationScope" -}} {{- $ctx := index . 0 -}} {{- $key := index . 1 -}} {{- $defaults := dict "api" "fed-mgmt" "notif" "fed-mgmt-notif" -}} {{- dig "federation" "scopes" $key (index $defaults $key) ($ctx.Values.global | default dict) -}} {{- end }} {{/* Keycloak's public URL (KC_HOSTNAME, and so the `iss` of every token): `hostname` if set, else <scheme>://<public host>:<NodePort> (the Service port for other Service types). Loading oop-platform-chart/charts/keycloak/templates/realms-configmap.yaml +17 −48 Changes for oop-platform-chart/charts/keycloak/templates/realms-configmap.yaml: 17 added lines, 48 removed lines. Original line number Diff line number Diff line Loading @@ -78,49 +78,19 @@ data: ] }, {{- /* One CAMARA scope per operation across QoD, Edge Application Management and Location Retrieval (matches each API's OpenAPI `security` block exactly -- see the *-api.yaml files under src/open_exposure_gateway/api/camara/). Attached below as default scopes on the `portal` client alongside Keycloak's own built-ins, so every token already carries them the same way `organization` and the realm role already do -- no separate consent step, since it's the same developer logging into their own account, not a third party requesting delegated access. Attached below as default scopes on the `portal` client alongside Keycloak's own built-ins, so every token already carries them the same way `organization` and the realm role already do -- no separate consent step, since it's the same developer logging into their own account, not a third party requesting delegated access. */ -}} {{- $camaraScopeNames := list "edge-application-management:apps:read" "edge-application-management:apps:write" "edge-application-management:apps:delete" "edge-application-management:instances:read" "edge-application-management:instances:write" "edge-application-management:instances:delete" "edge-application-management:deployments:read" "edge-application-management:deployments:write" "edge-application-management:deployments:update" "edge-application-management:deployments:delete" "edge-application-management:clusters:read" "edge-application-management:edge-cloud-zones:read" "qod-sessions-read" "qod-sessions-write" "qod-sessions-delete" "location-retrieval:read" }} {{- $camaraScopes := $.Files.Get "files/camara-scopes.yaml" | fromYamlArray }} {{- $camaraScopeNames := list }} "clientScopes": [ { "name": "edge-application-management:apps:read", "protocol": "openid-connect", "description": "List/view applications" }, { "name": "edge-application-management:apps:write", "protocol": "openid-connect", "description": "Register applications" }, { "name": "edge-application-management:apps:delete", "protocol": "openid-connect", "description": "Delete applications" }, { "name": "edge-application-management:instances:read", "protocol": "openid-connect", "description": "List/view app instances" }, { "name": "edge-application-management:instances:write", "protocol": "openid-connect", "description": "Create app instances" }, { "name": "edge-application-management:instances:delete", "protocol": "openid-connect", "description": "Delete app instances" }, { "name": "edge-application-management:deployments:read", "protocol": "openid-connect", "description": "List/view app deployments" }, { "name": "edge-application-management:deployments:write", "protocol": "openid-connect", "description": "Create app deployments" }, { "name": "edge-application-management:deployments:update", "protocol": "openid-connect", "description": "Update app deployments" }, { "name": "edge-application-management:deployments:delete", "protocol": "openid-connect", "description": "Delete app deployments" }, { "name": "edge-application-management:clusters:read", "protocol": "openid-connect", "description": "List clusters" }, { "name": "edge-application-management:edge-cloud-zones:read", "protocol": "openid-connect", "description": "List edge cloud zones" }, { "name": "qod-sessions-read", "protocol": "openid-connect", "description": "Retrieval of QoS sessions" }, { "name": "qod-sessions-write", "protocol": "openid-connect", "description": "Creation and update of QoS sessions" }, { "name": "qod-sessions-delete", "protocol": "openid-connect", "description": "Deletion of QoS sessions" }, { "name": "location-retrieval:read", "protocol": "openid-connect", "description": "Retrieve a device's location" } {{- range $i, $sc := $camaraScopes }} {{- $camaraScopeNames = append $camaraScopeNames $sc.name }} {{- if $i }},{{ end }} { "name": {{ $sc.name | toJson }}, "protocol": "openid-connect", "description": {{ $sc.description | toJson }} } {{- end }} ], "clients": [ { Loading Loading @@ -261,15 +231,13 @@ data: { "realm": "federation", "enabled": true, {{- $apiScope := include "keycloak.federationScope" (list $ "api") }} {{- $notifScope := include "keycloak.federationScope" (list $ "notif") }} "clientScopes": [ { "name": {{ .clientScope.name | toJson }}, "protocol": "openid-connect", "description": {{ .clientScope.description | toJson }} } { "name": {{ $apiScope | toJson }}, "protocol": "openid-connect", "description": "OPG.04 E/WBI API calls" }, { "name": {{ $notifScope | toJson }}, "protocol": "openid-connect", "description": "OPG.04 E/WBI callbacks" } ], "clients": [ {{- $scope := .clientScope.name }} {{- $audience := include "keycloak.federationAudience" $ }} {{- range $i, $c := (include "keycloak.federationClients" $ | fromJsonArray) }} {{- if $i }},{{ end }} Loading @@ -284,7 +252,8 @@ data: "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": true, "defaultClientScopes": [ {{ $scope | toJson }} ], "defaultClientScopes": [ {{ $apiScope | toJson }} ], "optionalClientScopes": [ {{ $notifScope | toJson }} ], "protocolMappers": [ {{- include "keycloak.audienceMapper" (dict "name" "audience-federation-manager" "custom" $audience) | nindent 12 }} ] Loading Loading
README.md +1 −1 Changes for README.md: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ Keycloak (`charts/keycloak`) runs as a platform service in `oop`, backed by the | Realm | Used by | Clients | |---|---|---| | `oop` | Portal users, app providers, OEG | `oop-portal` (confidential, Auth Code + PKCE), `oeg` (audience only) | | `federation` | FM, partner OPs (ADR-0042) | `originating-op-1`, `originating-op-2` (client credentials, scope `fed-mgmt`) | | `federation` | FM, partner OPs (ADR-0042) | `originating-op-1`, `originating-op-2` (client credentials, scope `fed-mgmt`; `fed-mgmt-notif` optional, for callbacks) | - Realm roles in `oop` (ADR-0048): `app-provider` (developers; given to every new user, including self-registered ones), `operator` (runs the platform) and `platform-admin` (manages users). None Loading
oop-platform-chart/charts/keycloak/README.md +16 −1 Changes for oop-platform-chart/charts/keycloak/README.md: 16 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -149,6 +149,14 @@ The source of this model is ADR-0048. Roles say **what** someone may do. They do not say **whose data** they may see; that is the organization's job ([section 9](#9-organizations-and-tenants)). ### CAMARA scopes Portal tokens also carry one scope per CAMARA operation (QoD, Edge Application Management, Location Retrieval), named as in each API's OpenAPI `security` block. The list lives in [`files/camara-scopes.yaml`](files/camara-scopes.yaml): add an entry there when OEG gains an operation. On an existing installation, also create the scope in the admin console and add it to `oop-portal` as **Default** ([Change realm settings after install](#change-realm-settings-after-install)). ### Clients | Client | Kind | Used by | What it does | Loading Loading @@ -201,6 +209,13 @@ unless Keycloak's public URL is `http://localhost[:port]` or `http://127.0.0.1[: - Each partner client can only use **client credentials** (machine to machine). No browser, no password. - Every token carries the scope **`fed-mgmt`** (the name the GSMA OPG.04 API contract requires) and the audience **`federation-manager`**, which Federation Manager checks. - Partners sending us a **callback** (federation status, instance status, zone updates) ask for **`fed-mgmt-notif`** too (`scope=fed-mgmt-notif` in the token request). It is an *optional* scope, so only tokens that request it carry it: a normal API token is not a callback token. Both names come from `global.federation.scopes`. On an installation older than this scope, add it by hand: realm `federation` → **Client scopes** → **Create client scope** (name `fed-mgmt-notif`, protocol OpenID Connect), then on each partner client → **Client scopes** → **Add client scope** → `fed-mgmt-notif` as **Optional**. - Each partner has its **own** secret, generated into `keycloak-credentials` as `federation-<client id>-secret`. We give it to that partner over a secure channel. One partner's secret never works for another partner. Loading Loading @@ -474,7 +489,7 @@ Use the same ID for everyone in the same organization: it is compared exactly. create the client in the admin console (realm `federation` → **Clients** → **Create client**): - Client ID: the same ID; **Client authentication** on; only **Service accounts roles** ticked. - **Credentials** tab: paste the secret from `keycloak-credentials`. - **Client scopes** tab: add `fed-mgmt` as **Default**. - **Client scopes** tab: add `fed-mgmt` as **Default** and `fed-mgmt-notif` as **Optional**. - **Client scopes** → `<client id>-dedicated` → **Add mapper** → **By configuration** → **Audience**: *Included Custom Audience* `federation-manager`, *Add to access token* on. 3. Send the client ID and secret to the partner over a secure channel, together with our token URL: Loading
oop-platform-chart/charts/keycloak/files/camara-scopes.yaml 0 → 100644 +35 −0 Changes for oop-platform-chart/charts/keycloak/files/camara-scopes.yaml: 35 added lines, 0 removed lines. Original line number Diff line number Diff line # CAMARA operation scopes of realm `oop`, one per operation across QoD, Edge Application # Management and Location Retrieval. Names match each API's OpenAPI `security` block. # Every scope here is created in the realm and issued on portal tokens. - name: "edge-application-management:apps:read" description: "List/view applications" - name: "edge-application-management:apps:write" description: "Register applications" - name: "edge-application-management:apps:delete" description: "Delete applications" - name: "edge-application-management:instances:read" description: "List/view app instances" - name: "edge-application-management:instances:write" description: "Create app instances" - name: "edge-application-management:instances:delete" description: "Delete app instances" - name: "edge-application-management:deployments:read" description: "List/view app deployments" - name: "edge-application-management:deployments:write" description: "Create app deployments" - name: "edge-application-management:deployments:update" description: "Update app deployments" - name: "edge-application-management:deployments:delete" description: "Delete app deployments" - name: "edge-application-management:clusters:read" description: "List clusters" - name: "edge-application-management:edge-cloud-zones:read" description: "List edge cloud zones" - name: "qod-sessions-read" description: "Retrieval of QoS sessions" - name: "qod-sessions-write" description: "Creation and update of QoS sessions" - name: "qod-sessions-delete" description: "Deletion of QoS sessions" - name: "location-retrieval:read" description: "Retrieve a device's location"
oop-platform-chart/charts/keycloak/templates/_helpers.tpl +14 −0 Changes for oop-platform-chart/charts/keycloak/templates/_helpers.tpl: 14 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -100,6 +100,20 @@ Audience added to partner tokens in the `federation` realm; Federation Manager r {{- .Values.realms.federation.audience | default (dig "federation" "audience" "federation-manager" (.Values.global | default dict)) -}} {{- end }} {{/* OPG.04 scope names in the `federation` realm, from global.federation.scopes: `api` for normal E/WBI calls (default scope of every partner client), `notif` for callbacks (optional scope, so only tokens that request it carry it). The federation-manager chart should read the same globals. Usage: include "keycloak.federationScope" (list $ "api") */}} {{- define "keycloak.federationScope" -}} {{- $ctx := index . 0 -}} {{- $key := index . 1 -}} {{- $defaults := dict "api" "fed-mgmt" "notif" "fed-mgmt-notif" -}} {{- dig "federation" "scopes" $key (index $defaults $key) ($ctx.Values.global | default dict) -}} {{- end }} {{/* Keycloak's public URL (KC_HOSTNAME, and so the `iss` of every token): `hostname` if set, else <scheme>://<public host>:<NodePort> (the Service port for other Service types). Loading
oop-platform-chart/charts/keycloak/templates/realms-configmap.yaml +17 −48 Changes for oop-platform-chart/charts/keycloak/templates/realms-configmap.yaml: 17 added lines, 48 removed lines. Original line number Diff line number Diff line Loading @@ -78,49 +78,19 @@ data: ] }, {{- /* One CAMARA scope per operation across QoD, Edge Application Management and Location Retrieval (matches each API's OpenAPI `security` block exactly -- see the *-api.yaml files under src/open_exposure_gateway/api/camara/). Attached below as default scopes on the `portal` client alongside Keycloak's own built-ins, so every token already carries them the same way `organization` and the realm role already do -- no separate consent step, since it's the same developer logging into their own account, not a third party requesting delegated access. Attached below as default scopes on the `portal` client alongside Keycloak's own built-ins, so every token already carries them the same way `organization` and the realm role already do -- no separate consent step, since it's the same developer logging into their own account, not a third party requesting delegated access. */ -}} {{- $camaraScopeNames := list "edge-application-management:apps:read" "edge-application-management:apps:write" "edge-application-management:apps:delete" "edge-application-management:instances:read" "edge-application-management:instances:write" "edge-application-management:instances:delete" "edge-application-management:deployments:read" "edge-application-management:deployments:write" "edge-application-management:deployments:update" "edge-application-management:deployments:delete" "edge-application-management:clusters:read" "edge-application-management:edge-cloud-zones:read" "qod-sessions-read" "qod-sessions-write" "qod-sessions-delete" "location-retrieval:read" }} {{- $camaraScopes := $.Files.Get "files/camara-scopes.yaml" | fromYamlArray }} {{- $camaraScopeNames := list }} "clientScopes": [ { "name": "edge-application-management:apps:read", "protocol": "openid-connect", "description": "List/view applications" }, { "name": "edge-application-management:apps:write", "protocol": "openid-connect", "description": "Register applications" }, { "name": "edge-application-management:apps:delete", "protocol": "openid-connect", "description": "Delete applications" }, { "name": "edge-application-management:instances:read", "protocol": "openid-connect", "description": "List/view app instances" }, { "name": "edge-application-management:instances:write", "protocol": "openid-connect", "description": "Create app instances" }, { "name": "edge-application-management:instances:delete", "protocol": "openid-connect", "description": "Delete app instances" }, { "name": "edge-application-management:deployments:read", "protocol": "openid-connect", "description": "List/view app deployments" }, { "name": "edge-application-management:deployments:write", "protocol": "openid-connect", "description": "Create app deployments" }, { "name": "edge-application-management:deployments:update", "protocol": "openid-connect", "description": "Update app deployments" }, { "name": "edge-application-management:deployments:delete", "protocol": "openid-connect", "description": "Delete app deployments" }, { "name": "edge-application-management:clusters:read", "protocol": "openid-connect", "description": "List clusters" }, { "name": "edge-application-management:edge-cloud-zones:read", "protocol": "openid-connect", "description": "List edge cloud zones" }, { "name": "qod-sessions-read", "protocol": "openid-connect", "description": "Retrieval of QoS sessions" }, { "name": "qod-sessions-write", "protocol": "openid-connect", "description": "Creation and update of QoS sessions" }, { "name": "qod-sessions-delete", "protocol": "openid-connect", "description": "Deletion of QoS sessions" }, { "name": "location-retrieval:read", "protocol": "openid-connect", "description": "Retrieve a device's location" } {{- range $i, $sc := $camaraScopes }} {{- $camaraScopeNames = append $camaraScopeNames $sc.name }} {{- if $i }},{{ end }} { "name": {{ $sc.name | toJson }}, "protocol": "openid-connect", "description": {{ $sc.description | toJson }} } {{- end }} ], "clients": [ { Loading Loading @@ -261,15 +231,13 @@ data: { "realm": "federation", "enabled": true, {{- $apiScope := include "keycloak.federationScope" (list $ "api") }} {{- $notifScope := include "keycloak.federationScope" (list $ "notif") }} "clientScopes": [ { "name": {{ .clientScope.name | toJson }}, "protocol": "openid-connect", "description": {{ .clientScope.description | toJson }} } { "name": {{ $apiScope | toJson }}, "protocol": "openid-connect", "description": "OPG.04 E/WBI API calls" }, { "name": {{ $notifScope | toJson }}, "protocol": "openid-connect", "description": "OPG.04 E/WBI callbacks" } ], "clients": [ {{- $scope := .clientScope.name }} {{- $audience := include "keycloak.federationAudience" $ }} {{- range $i, $c := (include "keycloak.federationClients" $ | fromJsonArray) }} {{- if $i }},{{ end }} Loading @@ -284,7 +252,8 @@ data: "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": true, "defaultClientScopes": [ {{ $scope | toJson }} ], "defaultClientScopes": [ {{ $apiScope | toJson }} ], "optionalClientScopes": [ {{ $notifScope | toJson }} ], "protocolMappers": [ {{- include "keycloak.audienceMapper" (dict "name" "audience-federation-manager" "custom" $audience) | nindent 12 }} ] Loading