Commit 53f4d1f6 authored by Dimitrios Gogos's avatar Dimitrios Gogos
Browse files

feat: refactor Federation Manager to remove Keycloak integration and add issuer configuration

parent a228d431
Loading
Loading
Loading
Loading
+29 −4
Changes for README.md: 29 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -93,9 +93,10 @@ Keycloak (`charts/keycloak`) runs as a platform service in `oop`, backed by the
  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.
- Keycloak's public URL is `http://<global.publicHost>:30081` (kind sets `publicHost: localhost`; other
  clusters detect it at install). Every token carries `iss=<public URL>/realms/<realm>`, even when a pod
  fetches it from `http://keycloak:8080`. Services only know the in-cluster URL: they read the issuer
  from Keycloak's discovery document and fetch signing keys there, so no public URL is configured in them.
- 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
@@ -108,7 +109,7 @@ Keycloak (`charts/keycloak`) runs as a platform service in `oop`, backed by the
- 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]`.
  refuses to render unless Keycloak's public URL 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.

@@ -145,6 +146,30 @@ The scripts can also be run individually from any directory.

---

## Install on another cluster

No values are required: passwords and client secrets are generated, and the public address is
detected at install time from the first node (its ExternalIP, else its InternalIP). If that is not
the address users reach, pass it once:

```bash
helm upgrade --install oop-platform ./oop-platform-chart -n oop --create-namespace \
  --set global.publicHost=10.20.30.40          # optional
```

Keycloak is then at `http://<publicHost>:30081`, and the portal's login redirects go to
`http://<publicHost>:30082`. Services inside the cluster only use `http://keycloak:8080` and read
the issuer from Keycloak's discovery document, so nothing else needs the address.

- Detection reads the cluster, so it only works with `helm upgrade --install`; with `helm template` or
  GitOps tools such as Argo CD, set `global.publicHost`.
- Changing the address later does not update the redirect URLs already stored in the `oop` realm
  (realm import only runs for a new realm); update the `oop-portal` client in the admin console.
- `scripts/helm-deploy.sh` also passes SRM a token for the cluster's API, which a bare `helm` command
  does not.

---

## Access URLs (after deployment)

| Service | URL |
+3 −4
Changes for environments/kind/values.yaml: 3 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -90,11 +90,10 @@ postgresql:
  networkPolicy:
    enabled: false

global:
  publicHost: localhost

keycloak:
  hostname: "http://localhost:30081"
  service:
    type: NodePort
    nodePort: 30081
  realms:
    oop:
      sampleUsers:
+38 −90
Changes for oop-platform-chart/charts/federation-manager/README.md: 38 added lines, 90 removed lines.
Original line number Diff line number Diff line
# Federation Manager Helm Chart

Helm chart for deploying Federation Manager with Keycloak authentication for the Open Operator Platform.
Helm chart for deploying Federation Manager for the Open Operator Platform.

## Components

This chart deploys:

- **Federation Manager** - Manages federation across multiple operators
- **Keycloak** - OAuth2/OpenID Connect authentication server
- **MongoDB** - Federation Manager's database
- **OpenVPN Sidecar** (Optional) - For remote federation connections

Authentication uses the platform Keycloak (realm `federation`), which is deployed by the umbrella
chart, not by this chart.

## Prerequisites

- Kubernetes 1.19+
- Helm 3.x
- kubectl configured
- A Keycloak with realm `federation` reachable at `federationManager.config.keycloak.host:port`

## Installation

@@ -47,47 +51,33 @@ helm install federation-manager . -n federation-manager -f my-values.yaml

## Configuration

### Keycloak Configuration

The default Keycloak realm configuration includes:

- **Realm**: `federation`
- **Admin User**: `admin` / `admin` (change in production!)
- **Client ID**: `originating-op-1`
- **Client Secret**: `dd7vNwFqjNpYwaghlEwMbw10g0klWDHb`

#### ⚠️ About Keycloak Credentials

The default client credentials provided are **generic OAuth2 credentials** and can be used for testing. However, for production deployments:
### Authentication (Keycloak)

**Option 1: Keep defaults** (for testing/development)
- The provided credentials will work out of the box
- Quick to get started
Federation Manager validates every incoming bearer token against Keycloak's realm `federation`:
signature (keys fetched from `http://<host>:<port>/realms/<realm>`), expiry, issuer, and the
`fed-mgmt` scope. Invalid or missing tokens get `401`. The expected issuer is discovered from
Keycloak's discovery document at that same address, so it follows Keycloak's public URL with no
extra configuration.

**Option 2: Generate new credentials** (recommended for production)

1. Deploy with defaults first
2. Access Keycloak UI at `http://<NODE-IP>:30081`
3. Login with admin/admin
4. Navigate to: Realm Settings → Clients → originating-op-1
5. Regenerate secret under "Credentials" tab
6. Update `values.yaml` with new secret:
```yaml
   keycloak:
     realm:
       client:
         secret: "your-new-secret"
   
federationManager:
  config:
    keycloak:
         client1_secret: "your-new-secret"
   ```
7. Upgrade the deployment:
   ```bash
   helm upgrade federation-manager . -n federation-manager
      client1_id: "originating-op-1"
      client1_secret: "dd7vNwFqjNpYwaghlEwMbw10g0klWDHb"
      client2_id: "originating-op-2"
      client2_secret: "2mhznERfWclLDuVojY77Lp4Qd2r4e8Ms"
      scope: "fed-mgmt"
      host: "keycloak"          # where Federation Manager reaches Keycloak
      port: "8080"
      realm: "federation"
      # Issuer Keycloak puts in tokens (`iss`), also the token URL the Swagger UI shows.
      # Empty = discovered from Keycloak; set it only to override that.
      issuer: ""
```

The client IDs and secrets must match the clients in Keycloak's `federation` realm.

### Federation Manager Configuration

Key configuration sections:
@@ -95,12 +85,6 @@ Key configuration sections:
```yaml
federationManager:
  config:
    # Keycloak OAuth2 settings
    keycloak:
      client1_id: "originating-op-1"
      client1_secret: "dd7vNwFqjNpYwaghlEwMbw10g0klWDHb"
      scope: "fed-mgmt"
    
    # MongoDB connection
    mongodb:
      host: "mongodb.mongodb.svc.cluster.local"
@@ -165,8 +149,6 @@ NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}

# Access URLs
echo "Federation Manager: http://$NODE_IP:30989"
echo "Keycloak: http://$NODE_IP:30081"
echo "Keycloak Admin: http://$NODE_IP:30081/admin (admin/admin)"
```

## Common Operations
@@ -184,9 +166,6 @@ kubectl get svc -n federation-manager
# Federation Manager logs
kubectl logs -f deployment/federation-manager -c federation-manager -n federation-manager

# Keycloak logs
kubectl logs -f deployment/keycloak -n federation-manager

# OpenVPN logs (if enabled)
kubectl logs -f deployment/federation-manager -c openvpn -n federation-manager
```
@@ -206,9 +185,6 @@ helm upgrade federation-manager . -n federation-manager
```bash
# Scale Federation Manager
helm upgrade federation-manager . -n federation-manager --set federationManager.replicaCount=2

# Scale Keycloak
helm upgrade federation-manager . -n federation-manager --set keycloak.replicaCount=2
```

## Integration with OOP Platform
@@ -255,16 +231,13 @@ federationManager:

## Troubleshooting

### Keycloak Not Starting
### Every request returns 401

```bash
# Check logs
kubectl logs deployment/keycloak -n federation-manager

# Common issues:
# - Realm import failed: Check ConfigMap
# - Port conflict: Ensure port 8080 is available
```
- Check the token's `iss` claim equals the `issuer` in
  `http://<host>:<port>/realms/<realm>/.well-known/openid-configuration` (or
  `federationManager.config.keycloak.issuer` if that override is set).
- Check Federation Manager can reach `http://<host>:<port>/realms/<realm>/protocol/openid-connect/certs`.
- Check the token carries the `fed-mgmt` scope.

### Federation Manager Configuration Issues

@@ -297,36 +270,14 @@ kubectl exec -it deployment/federation-manager -c openvpn -n federation-manager

### Production Deployment

1. **Change Keycloak Admin Password**
   ```yaml
   keycloak:
     admin:
       username: admin
       password: "StrongPassword123!"
   ```

2. **Regenerate Client Secrets** (see Keycloak Configuration section above)
1. **Regenerate Client Secrets** in Keycloak's `federation` realm and update
   `federationManager.config.keycloak.client1_secret` / `client2_secret` to match

3. **Use Secrets for Sensitive Data**
   ```bash
   kubectl create secret generic keycloak-admin \
     --from-literal=username=admin \
     --from-literal=password=secure-password \
     -n federation-manager
   ```
2. **Use Secrets for Sensitive Data**

4. **Enable TLS/HTTPS**
   ```yaml
   keycloak:
     ingress:
       enabled: true
       tls:
         - secretName: keycloak-tls
           hosts:
             - keycloak.yourdomain.com
   ```
3. **Enable TLS/HTTPS** for Federation Manager and Keycloak

5. **Resource Limits**
4. **Resource Limits**
   - Already configured with appropriate limits
   - Adjust based on your workload

@@ -347,13 +298,10 @@ kubectl delete secret partner-ovpn -n federation-manager

| Parameter | Description | Default |
|-----------|-------------|---------|
| `keycloak.enabled` | Enable Keycloak deployment | `true` |
| `keycloak.service.nodePort` | NodePort for Keycloak | `30081` |
| `keycloak.admin.username` | Keycloak admin username | `admin` |
| `keycloak.admin.password` | Keycloak admin password | `admin` |
| `keycloak.realm.client.secret` | OAuth2 client secret | (see values.yaml) |
| `federationManager.enabled` | Enable Federation Manager | `true` |
| `federationManager.service.nodePort` | NodePort for Federation Manager | `30989` |
| `federationManager.config.keycloak.host` / `port` / `realm` | Where Federation Manager reaches Keycloak | `keycloak` / `8080` / `federation` |
| `federationManager.config.keycloak.issuer` | Override for the issuer expected in tokens | `""` (discovered from Keycloak) |
| `federationManager.config.partner_op.role` | Role: `partner_op` or `originating_op` | `partner_op` |
| `openvpn.enabled` | Enable OpenVPN sidecar | `false` |
| `openvpn.secretName` | Name of VPN secret | `partner-ovpn` |
+0 −15
Changes for oop-platform-chart/charts/federation-manager/templates/_helpers.tpl: 0 added lines, 15 removed lines.
Original line number Diff line number Diff line
@@ -51,21 +51,6 @@ app.kubernetes.io/name: {{ include "federation-manager.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Keycloak labels
*/}}
{{- define "federation-manager.keycloak.labels" -}}
{{ include "federation-manager.labels" . }}
app: keycloak
{{- end }}

{{/*
Keycloak selector labels
*/}}
{{- define "federation-manager.keycloak.selectorLabels" -}}
app: keycloak
{{- end }}

{{/*
Federation Manager labels
*/}}
+1 −0
Changes for oop-platform-chart/charts/federation-manager/templates/federation-manager-configmap.yaml: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ data:
    host = {{ .Values.federationManager.config.keycloak.host }}
    port = {{ .Values.federationManager.config.keycloak.port }}
    realm = {{ .Values.federationManager.config.keycloak.realm }}
    issuer = {{ .Values.federationManager.config.keycloak.issuer }}

    [server]
    host = {{ .Values.federationManager.config.server.host }}
Loading