Sécurité & Authentification
Démarrage rapide
Sécurité & Authentification
PgArachne s’appuie entièrement sur le système de permission de PostgreSQL. Il ne réinvente pas les listes
de contrôle d’accès (ACL).
PgArachne prend en charge quatre méthodes d’authentification. Les méthodes 1 à 3 utilisent
SET LOCAL ROLE pour changer d’identité ; la méthode 4 (identifiants directs) se connecte
directement en tant que l’utilisateur, sans changement de rôle nécessaire.
Cela s’applique aux endpoints JSON-RPC et MCP. L’endpoint SSE
est la seule exception — il authentifie l’appelant mais ne change pas de rôle et ne vérifie pas les
permissions par canal, car les canaux LISTEN/NOTIFY de PostgreSQL ne sont pas
des objets de base de données avec leurs propres GRANTs à faire respecter. Voir la page SSE
pour ce que cela signifie en pratique.
1. Connexion interactive (JWT)
Les utilisateurs s’authentifient en utilisant leur vrai nom d’utilisateur et mot de passe
PostgreSQL par authentification HTTP Basic sur POST /{prefix}/{database}/token. En cas de succès, ils reçoivent un JWT
de courte durée. Les requêtes suivantes portent ce jeton dans l’en-tête
Authorization: Bearer <token>, et PgArachne bascule le rôle actif vers cet utilisateur
pour la durée de chaque requête.
curl -X POST http://localhost:8080/db/my_database/token -u demo_user:user_password
→ {"token":"eyJhbGciOi...","token_type":"Bearer","expires_in":28800}Les identifiants voyagent dans l’en-tête Authorization, jamais dans un corps JSON, et la connexion a sa propre URL, de sorte qu’un reverse proxy peut
la limiter en débit sans lire les corps de requête. La réponse n’est jamais mise en cache.
Nécessite JWT_SECRET. S’il n’est pas configuré, l’endpoint renvoie HTTP 404
(-32601) et les clients utilisent à la place les identifiants directs (méthode 4)
ou les tokens API (méthode 2).
2. Comptes de service (Tokens API)
Pour les systèmes automatisés ou les scripts, vous pouvez utiliser des tokens API longue durée.
- Les jetons sont stockés dans la table
pgarachne.api_tokens. - Chaque jeton est mappé à un utilisateur/rôle de base de données spécifique.
- Envoyez le jeton via l’en-tête
Authorization: Bearer <token>.
La création de tokens API nécessite pgarachne_admin. Utilisez pgarachne.add_api_token(...) avec un rôle membre de pgarachne_admin.
3. Fournisseur d’identité externe (JWT personnalisé)
Si vous authentifiez les utilisateurs en dehors de PgArachne (par exemple via un service d’authentification externe), vous pouvez émettre les JWT dans ce service et les envoyer directement à PgArachne.
- Format de l’en-tête :
Authorization: Bearer <jwt>. - Signature : HMAC uniquement (
HS256/HS384/HS512) avec le mêmeJWT_SECRETque celui configuré dans PgArachne. - Claims requis :
db_role(chaîne non vide) etdb_name(chaîne qui doit correspondre au segment de chemin:database). - Claim requis :
exp(timestamp Unix) pour l’expiration du token.
Nécessite JWT_SECRET ; sans lui, les valeurs Bearer sont uniquement vérifiées comme tokens API.
Exemple minimal de payload :
{
"db_role": "demo_user",
"db_name": "my_database",
"exp": 1767225600
}Note : les algorithmes JWT asymétriques (par exemple RS256/ES256)
ne sont pas pris en charge.
4. Identifiants directs de base de données (Basic Auth)
L’option la plus simple : envoyez le nom d’utilisateur et le mot de passe PostgreSQL avec chaque
requête via l’authentification HTTP Basic standard. PgArachne ouvre un pool de connexions
dédié authentifié directement en tant que cet utilisateur — SET LOCAL ROLE n’est
pas effectué.
Authorization: Basic <base64(username:password)>Exemple avec curl :
curl -X POST http://localhost:8080/db/my_database/jsonrpc \
-u demo_user:user_password \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"api.hello_world","params":{},"id":1}'- Prototypage rapide et développement local — aucune gestion de jetons requise.
- Services internes qui gèrent déjà les identifiants de manière sécurisée.
- Scénarios où émettre un JWT au préalable ajoute une complexité inutile.
Différences clés par rapport aux méthodes basées sur les jetons :
- Aucun
GRANT demo_user TO pgarachnen’est requis — PgArachne ne change pas de rôle. - La sécurité au niveau des lignes (Row-Level Security) et les permissions
GRANTde PostgreSQL sont appliquées comme d’habitude car la connexion s’exécute sous l’identité de l’utilisateur réel. - Les pools de connexions sont conservés par utilisateur pour l’efficacité, avec une durée de vie maximale de 5 minutes. Après un changement de mot de passe, les anciennes connexions expirent dans cette fenêtre.
- Pour que les clés d’idempotence fonctionnent avec les identifiants directs, accordez à
l’utilisateur
EXECUTE ON FUNCTION pgarachne.save_idempotency_key(text, text).
Privilèges Proxy : requis uniquement pour les méthodes 1 à 3
Pour l’authentification par JWT et par jeton API, PgArachne se connecte en tant qu’utilisateur
système défini dans DB_USER (ex : pgarachne) et change d’identité via
SET LOCAL ROLE. L’utilisateur système doit être membre de chaque
rôle cible.
-- Required for JWT / API-token auth only:
GRANT demo_user TO pgarachne;Ce grant n’est pas nécessaire lors de l’utilisation des identifiants directs (méthode 4).
Tableau comparatif des méthodes d’authentification
| Méthode | En-tête | SET LOCAL ROLE | GRANT … TO pgarachne | Idéal pour |
|---|---|---|---|---|
| JWT (/token) | Bearer <jwt> | ✅ Oui | Requis | Sessions utilisateur |
| Jeton API | Bearer <token> | ✅ Oui | Requis | Services automatisés |
| JWT externe | Bearer <jwt> | ✅ Oui | Requis | Intégration IdP externe |
| Identifiants directs | Basic <b64> | ❌ Non | Non requis | Développement, services internes |
Quelles fonctions peuvent être appelées
PgArachne n’a pas de liste blanche de schémas qui lui soit propre — ce qu’un rôle peut appeler est entièrement
déterminé par les privilèges PostgreSQL. Une fonction est appelable (et listée par capabilities, par MCP
tools/list et par l’export OpenAPI) lorsqu’elle prend un unique paramètre jsonb, que le rôle
dispose de EXECUTE sur elle et que le rôle dispose de USAGE sur son schéma. Les fonctions de
pg_catalog, information_schema, pgarachne ainsi que celles appartenant à des
extensions sont omises de la liste pour la garder lisible, mais les mêmes privilèges s’y appliquent.
Les valeurs par défaut de PostgreSQL sont permissives
Par défaut, PostgreSQL accorde EXECUTE sur chaque nouvelle fonction à PUBLIC, et chaque rôle
dispose de USAGE sur le schéma public. Une fonction utilitaire public.something(jsonb)
est donc appelable via l’API par n’importe quel rôle authentifié, sauf si vous révoquez ce privilège. Configuration recommandée :
-- New functions are not executable by everyone (run as the role that creates them):
ALTER DEFAULT PRIVILEGES REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
-- Keep API functions in a dedicated schema and grant explicitly:
GRANT USAGE ON SCHEMA api TO demo_user;
GRANT EXECUTE ON FUNCTION api.hello_world(jsonb) TO demo_user;Protection contre la force brute
LOGIN_RATE_LIMIT et LOGIN_RATE_LIMIT_PER_IP s’appliquent à toutes les méthodes
d’authentification, sur tous les endpoints (JSON-RPC, MCP, SSE, OpenAPI) :
/token: chaque tentative est décomptée des budgets par (IP, nom d’utilisateur) et par IP.- Identifiants directs (Basic Auth) : les tentatives échouées sont décomptées des budgets par (IP, nom d’utilisateur) et par IP. Les requêtes réussies ne sont pas comptées : un client légitime qui envoie ses identifiants à chaque requête n’est donc jamais limité.
- Jetons Bearer (JWT ou token API) : les tentatives échouées sont décomptées du budget par IP.
Une fois un budget épuisé, les tentatives suivantes sont rejetées avec HTTP 429 jusqu’à la fin
de la fenêtre (LOGIN_RATE_WINDOW) — sans même vérifier les identifiants.