- 6 docs racine (README, HANDOVER, ARCHITECTURE, DECISIONS, INSTALL, OPERATIONS) - 9 docs thématiques dans docs/ - 10 templates docker-compose dans configs/ - 7 scripts Python/Shell d'import Furious vers Zitadel - 2 matrices RBAC Etat infra au 5 juin 2026 : - 88 users Furious importes dans Zitadel - 8 roles RBAC crees et attribues - Intranet filtre les cartes selon role (Approche A) - 7 outils SSO operationnels
359 lines
10 KiB
Markdown
359 lines
10 KiB
Markdown
# 05 — Applications déployées
|
|
|
|
> Détails de chaque application protégée par SSO.
|
|
|
|
---
|
|
|
|
## 📋 Vue d'ensemble
|
|
|
|
| App | Image Docker | SSO via | Port interne | URL |
|
|
|---|---|---|---|---|
|
|
| Gitea | `gitea/gitea:1.22` | OIDC natif | 3000 (HTTP), 22 (SSH) | git.seizeconsulting.com |
|
|
| n8n | `n8nio/n8n:latest` | OAuth2-Proxy | 5678 | n8n.seizeconsulting.com |
|
|
| Portainer | `portainer/portainer-ce:latest` | OAuth2-Proxy | 9000 | portainer.seizeconsulting.com |
|
|
| Code Server | `lscr.io/linuxserver/code-server:latest` | OAuth2-Proxy | 8443 | code.seizeconsulting.com |
|
|
| Uptime Kuma | `louislam/uptime-kuma:1` | OAuth2-Proxy | 3001 | status.seizeconsulting.com |
|
|
|
|
---
|
|
|
|
## 🐙 Gitea
|
|
|
|
### Spécificité : SSO OIDC natif
|
|
|
|
Contrairement aux autres, Gitea **ne passe PAS par OAuth2-Proxy**. Il a sa propre intégration OIDC.
|
|
|
|
### docker-compose.yml (résumé)
|
|
|
|
Voir `configs/gitea/docker-compose.yml.template`.
|
|
|
|
```yaml
|
|
services:
|
|
gitea:
|
|
image: gitea/gitea:1.22
|
|
container_name: gitea
|
|
environment:
|
|
USER_UID: 1000
|
|
USER_GID: 1000
|
|
GITEA__database__DB_TYPE: postgres
|
|
GITEA__database__HOST: postgres:5432
|
|
GITEA__database__NAME: gitea
|
|
GITEA__database__USER: gitea
|
|
GITEA__database__PASSWD: ${GITEA_DB_PASSWORD}
|
|
GITEA__server__DOMAIN: git.seizeconsulting.com
|
|
GITEA__server__ROOT_URL: https://git.seizeconsulting.com/
|
|
GITEA__server__SSH_DOMAIN: git.seizeconsulting.com
|
|
# Auto-registration via OIDC
|
|
GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
|
|
GITEA__oauth2_client__USERNAME: preferred_username
|
|
GITEA__oauth2_client__ACCOUNT_LINKING: auto
|
|
# Désactiver le register manuel (SSO uniquement)
|
|
GITEA__service__DISABLE_REGISTRATION: "true"
|
|
volumes:
|
|
- ./data:/data
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
ports:
|
|
- "22:22" # SSH Git
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.gitea.rule=Host(`git.seizeconsulting.com`)"
|
|
- "traefik.http.routers.gitea.entrypoints=websecure"
|
|
- "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
|
networks:
|
|
- web
|
|
- backend
|
|
```
|
|
|
|
### Configuration SSO côté Gitea (après premier login)
|
|
|
|
1. Aller sur `https://git.seizeconsulting.com` → setup initial
|
|
2. Créer un compte admin Gitea (local, sera utilisé pour configurer le reste)
|
|
3. Site Administration → Authentication Sources → Add :
|
|
- Type : **OAuth2**
|
|
- Authentication Name : `Zitadel`
|
|
- OAuth2 Provider : **OpenID Connect**
|
|
- Client ID : `<de Zitadel>`
|
|
- Client Secret : `<de Zitadel>`
|
|
- OpenID Connect Auto Discovery URL : `https://sso.seizeconsulting.com/.well-known/openid-configuration`
|
|
- Skip Local 2FA : ✅ (Zitadel gère MFA)
|
|
4. **Save**
|
|
|
|
### Configuration côté Zitadel
|
|
|
|
Créer une app dans Projects → Infra Seize → Applications :
|
|
- Type : Web
|
|
- Authentication Method : Basic
|
|
- Grant Type : Authorization Code
|
|
- Redirect URL : `https://git.seizeconsulting.com/user/oauth2/Zitadel/callback`
|
|
- Post-logout Redirect : `https://git.seizeconsulting.com/`
|
|
- Token Settings : JWT + User profile info dans ID Token
|
|
|
|
### Caractéristiques
|
|
|
|
- ✅ **Auto-registration** : à la 1ère connexion via SSO, le compte Gitea est auto-créé
|
|
- ✅ **Username = trigramme** (lu depuis `preferred_username` Zitadel)
|
|
- ❌ **Registration manuelle désactivée** : SSO obligatoire pour les nouveaux users
|
|
|
|
### Rôles RBAC
|
|
|
|
Gitea n'utilise **pas** les rôles Zitadel directement. Les permissions Gitea sont gérées en interne (organizations, teams, repos). Pour l'instant, **tous les users ont accès en lecture** sur les repos publics.
|
|
|
|
À configurer plus tard : créer des **organizations** par BU et donner accès en fonction.
|
|
|
|
---
|
|
|
|
## ⚙️ n8n
|
|
|
|
### docker-compose.yml (résumé)
|
|
|
|
```yaml
|
|
services:
|
|
n8n:
|
|
image: n8nio/n8n:latest
|
|
container_name: n8n
|
|
environment:
|
|
DB_TYPE: postgresdb
|
|
DB_POSTGRESDB_HOST: postgres
|
|
DB_POSTGRESDB_PORT: 5432
|
|
DB_POSTGRESDB_DATABASE: n8n
|
|
DB_POSTGRESDB_USER: n8n
|
|
DB_POSTGRESDB_PASSWORD: ${N8N_DB_PASSWORD}
|
|
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
|
|
N8N_HOST: n8n.seizeconsulting.com
|
|
N8N_PORT: 5678
|
|
N8N_PROTOCOL: https
|
|
WEBHOOK_URL: https://n8n.seizeconsulting.com/
|
|
# ⚠️ Pas de labels Traefik ici : c'est OAuth2-Proxy qui est exposé
|
|
networks:
|
|
- web
|
|
- backend
|
|
```
|
|
|
|
### Particularités
|
|
|
|
- ⚠️ **N8N_ENCRYPTION_KEY** : critique pour décrypter les workflows et credentials. **À sauvegarder absolument**.
|
|
- L'auth n8n native est désactivée car OAuth2-Proxy fait l'auth en amont.
|
|
- Les **workflows** sont stockés dans Postgres (base `n8n`).
|
|
|
|
### Limitation RBAC
|
|
|
|
n8n CE (Community Edition) **ne supporte pas le RBAC granulaire** :
|
|
- Tous les users authentifiés ont accès à TOUS les workflows
|
|
- Pas de notion de "team" ou "project" en CE
|
|
|
|
→ C'est pourquoi le RBAC se fait **côté intranet** (cacher la carte aux non-autorisés). Voir [DECISIONS.md D7](../DECISIONS.md).
|
|
|
|
Pour vrai RBAC :
|
|
- Soit migrer vers **Activepieces** (gratuit, multi-tenant natif)
|
|
- Soit acheter **n8n Enterprise** (~12k€/an)
|
|
|
|
---
|
|
|
|
## 🐳 Portainer
|
|
|
|
### docker-compose.yml (résumé)
|
|
|
|
```yaml
|
|
services:
|
|
portainer:
|
|
image: portainer/portainer-ce:latest
|
|
container_name: portainer
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock # ⚠️ Accès complet à Docker !
|
|
- ./data:/data
|
|
networks:
|
|
- web
|
|
```
|
|
|
|
### Particularités
|
|
|
|
- ⚠️ **Accès au socket Docker** : Portainer a un contrôle **total** sur tous les conteneurs du serveur. À protéger absolument derrière SSO.
|
|
- Auth Portainer native = créée au premier login, à protéger.
|
|
- **RBAC interne** dans Portainer CE = très limité.
|
|
|
|
### Limitation RBAC
|
|
|
|
Portainer CE :
|
|
- 1 seul utilisateur admin
|
|
- Pas d'organisations/teams
|
|
|
|
→ RBAC sur l'intranet uniquement. Si besoin de vrai RBAC : **Portainer Business** (~1800€/an) ou migration vers **Komodo**.
|
|
|
|
---
|
|
|
|
## 💻 Code Server
|
|
|
|
### docker-compose.yml (résumé)
|
|
|
|
```yaml
|
|
services:
|
|
code-server:
|
|
image: lscr.io/linuxserver/code-server:latest
|
|
container_name: code-server
|
|
environment:
|
|
PUID: 1000
|
|
PGID: 1000
|
|
TZ: Europe/Paris
|
|
PASSWORD: ${CODE_PASSWORD} # Fallback si SSO down
|
|
SUDO_PASSWORD: ${CODE_PASSWORD}
|
|
DEFAULT_WORKSPACE: /config/workspace
|
|
volumes:
|
|
- ./config:/config
|
|
networks:
|
|
- web
|
|
```
|
|
|
|
### Particularités
|
|
|
|
- VS Code dans le navigateur
|
|
- L'OAuth2-Proxy gère l'auth en amont, mais Code Server a aussi son propre mdp en fallback (`CODE_PASSWORD`)
|
|
- Workspaces partagés dans `./config/workspace/`
|
|
|
|
### Limitation RBAC
|
|
|
|
Pas de notion de "team" ou "workspace par user" en local. Tout user accède au même workspace.
|
|
|
|
→ Pour vrai RBAC : **OpenVSCode Server** (multi-user natif).
|
|
|
|
---
|
|
|
|
## 📈 Uptime Kuma
|
|
|
|
### docker-compose.yml (résumé)
|
|
|
|
```yaml
|
|
services:
|
|
uptime-kuma:
|
|
image: louislam/uptime-kuma:1
|
|
container_name: uptime-kuma
|
|
volumes:
|
|
- ./data:/app/data
|
|
networks:
|
|
- web
|
|
```
|
|
|
|
### Particularités
|
|
|
|
- Outil de monitoring (HTTP/TCP/Ping checks)
|
|
- Statuspages publiques possibles (mais on les laisse derrière SSO ici)
|
|
- 1 seul user admin
|
|
|
|
### Configuration recommandée
|
|
|
|
Une fois SSO en place, **désactiver le compte admin local** ou changer le mdp en quelque chose de très long (le SSO suffit).
|
|
|
|
### Limitation RBAC
|
|
|
|
Pareil que les autres : 1 seul user, pas de RBAC.
|
|
|
|
→ Pour vrai RBAC : **Gatus** (config-as-code, multi-tenant).
|
|
|
|
---
|
|
|
|
## 🏠 Intranet (page d'accueil)
|
|
|
|
### docker-compose.yml
|
|
|
|
```yaml
|
|
services:
|
|
intranet:
|
|
image: nginx:alpine
|
|
container_name: intranet
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./index.html:/usr/share/nginx/html/index.html:ro
|
|
- ./logo.png:/usr/share/nginx/html/logo.png:ro
|
|
- ./roles-mapping.json:/usr/share/nginx/html/roles-mapping.json:ro
|
|
- ./nginx-rbac.conf:/etc/nginx/nginx.conf:ro
|
|
networks:
|
|
- web
|
|
```
|
|
|
|
### Caractéristiques
|
|
|
|
- Simple nginx avec un HTML statique
|
|
- **Filtrage RBAC côté JavaScript** (voir [07-rbac-intranet.md](./07-rbac-intranet.md))
|
|
- Nginx fait du `sub_filter` pour injecter l'email user dans l'HTML
|
|
- L'HTML cache les cartes selon le rôle
|
|
|
|
### Fichiers critiques
|
|
|
|
| Fichier | Usage |
|
|
|---|---|
|
|
| `index.html` | Le HTML avec les cartes et le JavaScript RBAC |
|
|
| `roles-mapping.json` | Mapping `email → role` (généré par script Python) |
|
|
| `nginx-rbac.conf` | Config nginx avec `sub_filter` pour injecter `__USER_EMAIL__` |
|
|
| `logo.png` | Logo Seize |
|
|
|
|
---
|
|
|
|
## 🗄️ PostgreSQL (principal)
|
|
|
|
### docker-compose.yml
|
|
|
|
```yaml
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: postgres
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: postgres
|
|
volumes:
|
|
- ./data:/var/lib/postgresql/data
|
|
networks:
|
|
- backend
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
```
|
|
|
|
### Particularités
|
|
|
|
- Postgres **mutualisé** entre Gitea et n8n (databases séparées dans la même instance)
|
|
- Pas exposé publiquement (réseau `backend` uniquement)
|
|
- ⚠️ **Postgres Zitadel est séparé** (dans son propre docker-compose)
|
|
|
|
### Databases hébergées
|
|
|
|
| Database | Owner | Service |
|
|
|---|---|---|
|
|
| postgres | postgres | (admin) |
|
|
| gitea | gitea | Gitea |
|
|
| n8n | n8n | n8n |
|
|
| authentik | authentik | Authentik (obsolète) |
|
|
|
|
---
|
|
|
|
## 📦 Volumes critiques par app
|
|
|
|
| App | Volume | Quoi |
|
|
|---|---|---|
|
|
| Gitea | `./data` | Repos, config, attachments |
|
|
| Portainer | `./data` | Compose stacks, snapshots |
|
|
| Code Server | `./config` | Workspace, settings, plugins |
|
|
| Uptime Kuma | `./data` | Monitors, history, statuspages |
|
|
| Postgres | `./data` | Toutes les DBs (sauf Zitadel) |
|
|
| Zitadel | `./postgres-data` + `./machinekey` | Auth complète |
|
|
|
|
---
|
|
|
|
## 🔄 Ajouter une nouvelle app — checklist
|
|
|
|
Voir [OPERATIONS.md](../OPERATIONS.md) section "Ajouter un nouvel outil".
|
|
|
|
1. ✅ DNS record A `<app>.seizeconsulting.com`
|
|
2. ✅ Créer `~/docker/<app>/` avec docker-compose.yml
|
|
3. ✅ Créer l'app dans Zitadel (Project Infra Seize)
|
|
4. ✅ Récupérer Client ID + Secret
|
|
5. ✅ Créer OAuth2-Proxy dédié `~/docker/oauth2-proxy-<app>/`
|
|
6. ✅ Tester le login
|
|
7. ✅ Ajouter la carte dans `~/docker/intranet/index.html` avec `data-app="<app>"`
|
|
8. ✅ Ajouter la ligne dans la matrice RBAC du JavaScript
|
|
9. ✅ Restart intranet
|
|
10. ✅ Tester avec différents profils
|