diff --git a/deploy/helm/barycenter/README.md b/deploy/helm/barycenter/README.md new file mode 100644 index 0000000..37b8e1c --- /dev/null +++ b/deploy/helm/barycenter/README.md @@ -0,0 +1,405 @@ +# Barycenter Helm Chart + +OpenID Connect Identity Provider with built-in user management and federation support. + +## Features + +- OpenID Connect / OAuth 2.0 Authorization Server +- User synchronization from JSON files (idempotent) +- GraphQL Admin API for management +- Background job scheduler +- PostgreSQL and SQLite support +- Persistent storage for database and keys + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3.0+ +- PersistentVolume provisioner (optional, for production) + +## Installing the Chart + +### Basic Installation + +```bash +helm install barycenter ./barycenter +``` + +### With Custom Values + +```bash +helm install barycenter ./barycenter -f my-values.yaml +``` + +### Production Installation with User Sync + +1. **Create users secret:** + +```bash +# Copy the example +cp examples/user-sync-secret.yaml my-users-secret.yaml + +# Edit with your users +nano my-users-secret.yaml + +# Create the secret +kubectl create secret generic barycenter-users \ + --from-file=users.json=./users.json \ + -n default +``` + +2. **Install with user sync enabled:** + +```bash +helm install barycenter ./barycenter \ + --set userSync.enabled=true \ + --set userSync.existingSecret=barycenter-users \ + --set config.server.publicBaseUrl=https://auth.example.com \ + --set ingress.enabled=true \ + --set ingress.hosts[0].host=auth.example.com +``` + +## Configuration + +### Basic Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `replicaCount` | Number of replicas (use 1 for SQLite) | `1` | +| `image.repository` | Image repository | `barycenter` | +| `image.tag` | Image tag | `Chart.appVersion` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | + +### Service Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `service.type` | Service type | `ClusterIP` | +| `service.port` | Service port | `8080` | + +### Barycenter Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `config.server.host` | Listen address | `0.0.0.0` | +| `config.server.port` | Listen port | `8080` | +| `config.server.publicBaseUrl` | Public base URL (OIDC issuer) | `""` | +| `config.database.url` | Database connection string | `sqlite:///app/data/barycenter.db?mode=rwc` | +| `config.keys.alg` | Signing algorithm | `RS256` | + +### User Sync Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `userSync.enabled` | Enable user sync init container | `false` | +| `userSync.existingSecret` | Name of secret containing users.json | `""` | +| `userSync.secretKey` | Key in secret containing users.json | `users.json` | +| `userSync.resources` | Init container resources | See values.yaml | + +### Persistence + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `persistence.enabled` | Enable persistent storage | `true` | +| `persistence.size` | PVC size | `10Gi` | +| `persistence.accessMode` | PVC access mode | `ReadWriteOnce` | +| `persistence.storageClass` | Storage class | `""` (default) | + +### Ingress + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `ingress.enabled` | Enable ingress | `false` | +| `ingress.className` | Ingress class name | `nginx` | +| `ingress.hosts` | Ingress hosts | `[{host: idp.example.com, paths: [{path: /, pathType: Prefix}]}]` | +| `ingress.tls` | TLS configuration | `[]` | + +## User Synchronization + +The user sync feature allows you to manage users declaratively using a JSON file. This is perfect for: + +- Initial user provisioning +- Kubernetes init containers +- CI/CD pipelines +- GitOps workflows + +### How It Works + +1. Create a Kubernetes Secret with your users.json +2. Enable user sync in Helm values +3. An init container runs before the main app +4. Users are created/updated idempotently +5. Main app starts with users ready + +### User JSON Schema + +```json +{ + "users": [ + { + "username": "admin", + "email": "admin@example.com", + "password": "secure-password", + "enabled": true, + "email_verified": true, + "properties": { + "role": "administrator", + "custom_field": "value" + } + } + ] +} +``` + +### Creating a User Secret + +**From a file:** + +```bash +kubectl create secret generic barycenter-users \ + --from-file=users.json=./my-users.json \ + -n default +``` + +**From stdin (for CI/CD):** + +```bash +cat <> .gitignore + ``` + +2. **Use secret management tools:** + - Sealed Secrets + - External Secrets Operator + - HashiCorp Vault + - Cloud provider secret managers + +3. **Rotate passwords regularly:** + - Update users.json with new passwords + - Recreate the secret + - Restart deployment + +4. **Restrict admin API access:** + - Use NetworkPolicies + - Don't expose admin port publicly + - Use VPN or bastion for access + +## Support + +- Documentation: https://github.com/CloudNebulaProject/barycenter +- Issues: https://github.com/CloudNebulaProject/barycenter/issues diff --git a/deploy/helm/barycenter/examples/user-sync-secret.yaml b/deploy/helm/barycenter/examples/user-sync-secret.yaml new file mode 100644 index 0000000..7a9dd25 --- /dev/null +++ b/deploy/helm/barycenter/examples/user-sync-secret.yaml @@ -0,0 +1,65 @@ +# Example Secret for User Synchronization +# +# This secret contains the users.json file that will be used by the +# user-sync init container to create/update users in Barycenter. +# +# Usage: +# 1. Copy this file and customize the users list +# 2. Create the secret: kubectl apply -f user-sync-secret.yaml +# 3. Enable userSync in values.yaml: +# userSync: +# enabled: true +# existingSecret: "barycenter-users" +# +# Security Notes: +# - NEVER commit this file with real passwords to version control +# - Consider using a secret management tool (Sealed Secrets, External Secrets, Vault, etc.) +# - Passwords should be strong and unique per environment + +apiVersion: v1 +kind: Secret +metadata: + name: barycenter-users + namespace: default # Change to your namespace +type: Opaque +stringData: + users.json: | + { + "users": [ + { + "username": "admin", + "email": "admin@example.com", + "password": "CHANGE-ME-IN-PRODUCTION", + "enabled": true, + "email_verified": true, + "properties": { + "role": "administrator", + "display_name": "System Administrator" + } + }, + { + "username": "alice", + "email": "alice@example.com", + "password": "alice-secure-password", + "enabled": true, + "email_verified": false, + "properties": { + "department": "Engineering", + "role": "developer", + "display_name": "Alice Johnson", + "team": "Platform" + } + }, + { + "username": "service-account", + "email": "service@example.com", + "password": "service-account-password", + "enabled": true, + "email_verified": true, + "properties": { + "role": "service_account", + "display_name": "Application Service Account" + } + } + ] + } diff --git a/deploy/helm/barycenter/templates/deployment.yaml b/deploy/helm/barycenter/templates/deployment.yaml index 537a4bb..e396025 100644 --- a/deploy/helm/barycenter/templates/deployment.yaml +++ b/deploy/helm/barycenter/templates/deployment.yaml @@ -30,6 +30,35 @@ spec: serviceAccountName: {{ include "barycenter.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- if .Values.userSync.enabled }} + initContainers: + - name: user-sync + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - barycenter + - sync-users + - --file + - /secrets/{{ .Values.userSync.secretKey }} + env: + - name: RUST_LOG + value: "info" + volumeMounts: + - name: config + mountPath: /app/config + readOnly: true + {{- if .Values.persistence.enabled }} + - name: data + mountPath: /app/data + {{- end }} + - name: user-sync-secret + mountPath: /secrets + readOnly: true + resources: + {{- toYaml .Values.userSync.resources | nindent 10 }} + {{- end }} containers: - name: {{ .Chart.Name }} securityContext: @@ -71,6 +100,11 @@ spec: - name: data emptyDir: {} {{- end }} + {{- if .Values.userSync.enabled }} + - name: user-sync-secret + secret: + secretName: {{ .Values.userSync.existingSecret }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/deploy/helm/barycenter/values.yaml b/deploy/helm/barycenter/values.yaml index b7135f2..a7169b8 100644 --- a/deploy/helm/barycenter/values.yaml +++ b/deploy/helm/barycenter/values.yaml @@ -153,3 +153,24 @@ readinessProbe: periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 + +# User synchronization from JSON file +userSync: + # Enable user sync init container + enabled: false + + # Name of existing secret containing users.json + existingSecret: "" + # Example: barycenter-users + + # Secret key containing the users.json file + secretKey: "users.json" + + # Init container resources + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi