# Baserow Authentication — Bridge Service ## Pourquoi deux types de tokens Baserow expose deux mecanismes d'authentification aux comportements differents : | Type | Header | Droits | Usages | |------|--------|--------|--------| | DB token | `Token brg_*` | CRUD rows uniquement | `listRows`, `createRow`, `updateRow`, `deleteRow` | | User JWT | `JWT eyJ...` | Toutes les routes API | Metadata : `listViews`, `getTable`, `resolveTableIds` | Le DB token (BASEROW_API_TOKEN) est suffisant pour 90% des cas mais Baserow renvoie `401 PERMISSION_DENIED` sur les endpoints metadata. Ce n'est pas un bug : c'est la conception Baserow qui distingue DB tokens (CRUD rows) des user sessions (lecture full-API). Le bridge utilise donc les deux : - **DB token** : routes `/api/database/rows/table/:id/` — toujours actif - **User JWT** : routes `/api/database/views/table/:id/`, `/api/database/tables/:id/` — actif si `BASEROW_USER_EMAIL` + `BASEROW_USER_PASSWORD` sont configures ## API Baserow — endpoints JWT Source : docs.baserow.io + github.com/code-watch/baserow/blob/master/docs/getting-started/api.md ### Login ``` POST /api/user/token-auth/ Content-Type: application/json { "username": "email@example.com", "password": "..." } ``` Reponse : ```json { "token": "eyJ..." } ``` Le JWT est valide 60 minutes (valeur par defaut Baserow, configurable cote serveur). ### Refresh ``` POST /api/user/token-refresh/ Content-Type: application/json { "token": "eyJ..." (token courant) } ``` Reponse : ```json { "token": "eyJ..." (nouveau token) } ``` ### Header d'autorisation ``` Authorization: JWT eyJ... ``` Note : le prefixe est `JWT`, pas `Bearer` ni `Token`. ## Creer le compte service Baserow 1. Ouvrir `http:///admin/users/` 2. Cliquer "Add user" 3. Remplir : - Email : `bridge-svc@interne.local` (ou equivalent interne) - Password : generer un mot de passe fort (min 16 chars, stocker dans Vault ou secret manager) - Is active : oui - Is staff : non (pas besoin d'admin) 4. Ajouter ce user aux groupes (workspaces) ou il doit lire les tables - Permission "Member" suffit pour lire views + tables 5. Verifier : `curl -X POST http://baserow/api/user/token-auth/ -d '{"username":"bridge-svc@...","password":"..."}'` ## Variables d'environnement ```bash # Requis pour activer le JWT manager BASEROW_USER_EMAIL=bridge-svc@interne.local BASEROW_USER_PASSWORD=generated-strong-password # Optionnel — refresh le JWT N secondes avant son expiration (defaut 60) BASEROW_JWT_REFRESH_MARGIN=60 ``` Si ces variables sont absentes, le bridge continue a fonctionner pour les CRUD rows. Les routes views renvoient `500 BASEROW_USER_AUTH_NOT_CONFIGURED`. ## Verification que ca marche ### Via le health endpoint ```bash curl -s http://localhost:4000/api/health # { "status": "ok", "service": "bridge", "version": "0.1.0" } ``` ### Via la route views ```bash curl -s \ -H "Authorization: Bearer brg_" \ "http://localhost:4000/api/v1/views/table/personne" # { "data": [...], "total": N } ``` Avant Patch 031, cette route retournait 401 de Baserow. Apres Patch 031 avec JWT configure, elle retourne les vues de la table. ### Verifier les logs au boot ``` INFO: Baserow user JWT manager enabled (email: bridge-svc@interne.local) ``` Si vous voyez a la place : ``` INFO: Baserow user JWT manager disabled — metadata endpoints will return 503 if called ``` c'est que BASEROW_USER_EMAIL ou BASEROW_USER_PASSWORD est absent. ## Architecture interne ``` getToken() appel ─► BaserowJwtManagerImpl ├─ token cache frais ? → retour immediat ├─ token bientot expire ? → POST /api/user/token-refresh/ │ └─ echec ? → fallback POST /api/user/token-auth/ └─ pas de token ? → POST /api/user/token-auth/ Mutex : si 10 appels simultanes → 1 seul login/refresh, les 9 autres attendent. ``` `BaserowClient.listViewsWithJwt(tableId, jwt)` utilise `Authorization: JWT ` vers Baserow. ## Bonnes pratiques securite - Le password est remplace par `***` dans les logs (voir `baserow-jwt-manager.ts`, appels `this.logger.error`) - Le JWT reste en memoire uniquement (pas de Redis, pas de fichier disque) - Le JWT n'est pas retransmis dans les reponses HTTP du bridge vers les clients - En cas de rotation du mot de passe Baserow : redemarrer le bridge (re-login au premier appel) - Stocker BASEROW_USER_PASSWORD dans un secret manager (Vault, Docker secrets, k8s Secret)