Commit a228d431 authored by Dimitrios Gogos's avatar Dimitrios Gogos
Browse files

feat: integrate Keycloak as identity provider with realms and sample users support

parent 374cdecf
Loading
Loading
Loading
Loading
+51 −2
Changes for README.md: 51 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ Intended for local development, integration testing, and demos. **Not for produc
| Artifact Manager | `oop` | Stores and serves artefacts |
| OEG (Open Exposure Gateway) | `oop` | Northbound API entry point for tenants |
| Federation Manager | `oop` | Inter-operator federation workflows |
| Keycloak | `oop` | OAuth2/OIDC authentication for FM |
| Keycloak | `oop` | OAuth2/OIDC identity provider: realm `oop` (portal users, app providers, OEG tokens) and realm `federation` (FM partners) |
| PostgreSQL | `oop` | Shared instance; one database and role per component |
| AI2 MCP | `oop` | MCP server exposing CAMARA-compliant tools |
| AI2 AI Agent | `oop` | Natural language interface backed by Groq |
@@ -75,6 +75,54 @@ them `postgres-client: "true"` or adding a selector to `postgresql.networkPolicy

---

## Identity (Keycloak)

Keycloak (`charts/keycloak`) runs as a platform service in `oop`, backed by the shared PostgreSQL
(database `keycloak`). Two realms are imported on first start from
`charts/keycloak/templates/realms-configmap.yaml`:

| 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`) |

- 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
  implies another; one person can hold several.
- Client `oop-portal-admin` is the portal backend's user-management account: its service account holds
  only `realm-management` `manage-users`, `view-users`, `query-users` and `view-realm`, and its secret is
  `keycloak-credentials` → `oop-portal-admin-client-secret`. People never get Keycloak admin rights
  through the portal; the portal checks `platform-admin` on its user pages.
- On kind, `keycloak.hostname` is `http://localhost:30081`, so every token has
  `iss=http://localhost:30081/realms/<realm>` even when a pod fetches it from `http://keycloak:8080`.
  Services validate that issuer and fetch signing keys from the in-cluster URL.
- Tokens from `oop-portal` carry `aud: oeg`.
- There is no mail server, so nothing is sent by email (no verification, no reset links). "Forgot
  password?" stays on the login page, but its texts (`keycloak.realms.oop.forgotPassword`) tell users to
  ask a platform administrator. An admin resets the password in the admin console: Users → the user →
  Credentials → Reset password, marked *Temporary* so the user picks a new one at the next login.
  Logged-in users change their own password through the portal (`kc_action=UPDATE_PASSWORD`).
- The admin password and the `oop-portal` client secret are generated on first install into Secret
  `keycloak-credentials`, which is kept on `helm uninstall` because the realms keep using them. Pin them
  with `keycloak.admin.password` / `keycloak.realms.oop.portal.clientSecret` in `secrets.values.yaml`.
- The kind environment also creates sample users, one per role: `dev-provider` (`app-provider`),
  `dev-operator` (`operator`) and `dev-admin` (`platform-admin`), sharing the password in
  `keycloak-credentials` → `dev-user-password`. They come from `keycloak.realms.oop.sampleUsers`, which
  refuses to render unless `keycloak.hostname` is `http://localhost[:port]` or `http://127.0.0.1[:port]`.
- **Realm import only creates missing realms.** After a realm exists, changes to its JSON are ignored:
  apply them in the admin console, or delete the realm (or the `keycloak` database) and restart Keycloak.

Read the admin password, or the seed users' password:

```bash
kubectl -n oop get secret keycloak-credentials -o jsonpath='{.data.admin-password}' | base64 -d; echo
kubectl -n oop get secret keycloak-credentials -o jsonpath='{.data.dev-user-password}' | base64 -d; echo
```

Seed users can log in to the account console at http://localhost:30081/realms/oop/account.

---

## Deploy on kind (one command)

```bash
@@ -105,7 +153,8 @@ The scripts can also be run individually from any directory.
| Artifact Manager | http://localhost:30080 |
| OEG API (Swagger) | http://localhost:32263/oeg/1.0.0/docs/ |
| Keycloak | http://localhost:30081 |
| Keycloak Admin | http://localhost:30081/admin — `admin / admin` |
| Keycloak Admin | http://localhost:30081/admin — user `admin`, password in Secret `keycloak-credentials` (see [Identity](#identity-keycloak)) |
| OIDC discovery (realm `oop`) | http://localhost:30081/realms/oop/.well-known/openid-configuration |
| Federation Manager | http://localhost:30989 |
| AI2 MCP | http://localhost:32004 |
| AI2 AI Agent | http://localhost:32013 |
+10 −7
Changes for environments/kind/values.yaml: 10 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -83,13 +83,6 @@ federationManager:
    image:
      pullPolicy: IfNotPresent

  keycloak:
    service:
      type: NodePort
      nodePort: 30081
    image:
      pullPolicy: IfNotPresent

postgresql:
  persistence:
    storageClass: standard
@@ -97,6 +90,16 @@ postgresql:
  networkPolicy:
    enabled: false

keycloak:
  hostname: "http://localhost:30081"
  service:
    type: NodePort
    nodePort: 30081
  realms:
    oop:
      sampleUsers:
        enabled: true

ai2:
  images:
    mcp:
+5 −2
Changes for oop-platform-chart/Chart.lock: 5 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -2,6 +2,9 @@ dependencies:
- name: postgresql
  repository: ""
  version: 1.0.0
- name: keycloak
  repository: ""
  version: 1.0.0
- name: srm
  repository: ""
  version: 1.0.0
@@ -20,5 +23,5 @@ dependencies:
- name: nats
  repository: https://nats-io.github.io/k8s/helm/charts/
  version: 1.2.10
digest: sha256:7d1507b7f8711961519364feeb12197081c138809775dcabbdd03da4933f032e
generated: "2026-09-12T18:56:52.464189855+03:00"
digest: sha256:7138b0459ac2999c638b9090e83bc096c518e88ebde0f8f8b8d9132802e61e32
generated: "2026-09-12T21:40:09.436761398+03:00"
+4 −1
Changes for oop-platform-chart/Chart.yaml: 4 added lines, 1 removed line.
Original line number Diff line number Diff line
apiVersion: v2
name: oop-platform
description: Open Operator Platform - Complete platform deployment (SRM, OEG, Federation Manager, AI2, Portal and PostgreSQL)
description: Open Operator Platform - Complete platform deployment (SRM, OEG, Federation Manager, AI2, Portal, PostgreSQL and Keycloak)
type: application
version: 1.0.0

@@ -32,6 +32,9 @@ dependencies:
  - name: postgresql
    version: "1.0.0"
    condition: postgresql.enabled
  - name: keycloak
    version: "1.0.0"
    condition: keycloak.enabled
  - name: srm
    version: "1.0.0"
    condition: srm.enabled
+13 −0
Changes for oop-platform-chart/charts/keycloak/Chart.yaml: 13 added lines, 0 removed lines.
Original line number Diff line number Diff line
apiVersion: v2
name: keycloak
description: Keycloak identity provider for the OOP platform (realm oop for portal users and app providers, realm federation for FM)
type: application
version: 1.0.0
appVersion: "26.7.3"
keywords:
  - oop
  - keycloak
  - oidc
  - oauth2
maintainers:
  - name: Open Operator Platform Team
Loading