Aller au contenu principal
Page traduite

Cette page a été traduite de l'anglais avec l'aide de l'IA. En cas de divergence, la version anglaise fait référence.

Gestion des accès

La gestion des accès des appelants authentifie l'appelant d'une session StackQL et autorise chaque instruction au regard d'une politique. Elle est indépendante des identifiants des providers, qui restent fournis par --auth, par des variables d'environnement ou par des sessions de provider. Elle est désactivée par défaut, et les déploiements qui ne l'activent pas se comportent comme auparavant. Disponible à partir de StackQL v1.0.

Voir aussi :
[ Options globales ] [mcp] [whoami] [groups]


Activer la gestion des accès​

La gestion des accès s'active en démarrant StackQL avec l'option globale --access.config pointant vers un fichier de configuration JSON. L'exemple démarre un shell interactif en mode protégé ; exec et mcp s'activent de la même manière.

stackql --access.config '{"path": "/etc/stackql/access.json"}' shell

--access.config prend une enveloppe JSON avec une seule clé path ; un simple chemin de fichier est également accepté. La configuration est chargée une seule fois au démarrage, effectuez donc la rotation des clés ou de la politique par un redémarrage contrôlé.

Tant que la gestion des accès est activée, seules les commandes exec, shell, mcp et version s'exécutent ; les autres commandes, y compris registry, refusent de s'exécuter plutôt que de contourner le chemin protégé. srv et le type de serveur MCP reverse_proxy refusent également, car la dépendance du protocole filaire PostgreSQL n'expose pas encore de preuve d'authentification par connexion. Les instructions SQL AUTH et AUTH REVOKE sont refusées en mode protégé ; provisionnez plutôt les identifiants des providers par la configuration de l'hôte. Un exec protégé qui échoue renvoie le code de sortie 1 après avoir affiché l'erreur.

Modes d'authentification​

Le fichier de configuration sélectionne un type : jwt (valeur par défaut s'il est omis), bearer, mtls ou local_os. La configuration est du JSON strict : les champs inconnus et les champs appartenant à un autre mode sont rejetés. Tous les modes partagent les mêmes rules et le même annuaire des principaux.

JWT​

L'appelant présente un jeton signé, qui est vérifié hors ligne avec les clés épinglées dans la configuration. Une configuration minimale nomme l'émetteur et l'audience que le jeton doit porter, liste une clé publique et accorde au groupe readers l'accès en lecture :

{
"type": "jwt",
"issuer": "https://identity.example",
"audience": "stackql",
"keys": [
{"kid": "primary", "algorithm": "EdDSA", "public_key_pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n"}
],
"rules": [
{"subject": "group:readers", "resource": "host/sql/read", "action": "execute"}
]
}

L'émetteur, l'audience et les clés publiques sont épinglés dans la configuration ; il n'y a pas de découverte OIDC. Les algorithmes acceptés sont EdDSA, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384 et ES512, et les clés RSA doivent compter au moins 2048 bits. Chaque clé est liée à l'algorithme configuré pour elle. Les jetons dont l'ID de clé est inconnu, la signature invalide, l'expiration absente ou dépassée, le nbf ou le iat dans le futur, ou l'émetteur ou l'audience incorrects sont rejetés. Les revendications de groupe et les URL portées par le jeton ne servent ni à établir la confiance ni à déterminer l'appartenance à l'annuaire.

Jeton bearer statique​

L'appelant présente un jeton opaque, et la configuration liste l'empreinte SHA-256 de chaque jeton accepté avec le sujet qu'il identifie. Ce mode convient à un petit ensemble fixe d'identités de service, lorsque l'exploitation d'un émetteur de jetons ne se justifie pas :

{
"type": "bearer",
"issuer": "local-tokens",
"tokens": [{"subject": "alice", "sha256": "<64 hexadecimal characters: the SHA-256 of the token>"}],
"rules": [{"subject": "group:readers", "resource": "host/sql/read", "action": "execute"}]
}

Seule l'empreinte SHA-256 de chaque jeton est configurée, et les empreintes doivent être uniques. Modifier les empreintes configurées nécessite un redémarrage.

TLS mutuel​

L'appelant est identifié par le certificat client qu'il présente sur le transport MCP HTTPS. La configuration contient la CA qui doit avoir émis le certificat et indique quel nom alternatif du sujet (SAN) porte l'identité :

{
"type": "mtls",
"issuer": "client-certificates",
"client_ca_pem": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
"certificate_identity": "uri_san",
"rules": [{"subject": "group:readers", "resource": "host/sql/read", "action": "execute"}]
}

La chaîne de certificats du client est vérifiée avec client_ca_pem et le sujet de l'identité est tiré d'exactement un SAN du type configuré, uri_san ou dns_san. Il n'y a pas de repli sur le Common Name. Le TLS mutuel n'est disponible que sur le transport MCP HTTPS.

Identité locale de l'OS​

Aucun identifiant n'est échangé : le sujet est l'identité du système d'exploitation sous laquelle s'exécute le processus StackQL. La configuration ne nécessite qu'un libellé issuer et les règles :

{
"type": "local_os",
"issuer": "this-host",
"rules": [{"subject": "group:readers", "resource": "host/sql/read", "action": "execute"}]
}

Le sujet de l'identité est l'UID Unix effectif ou le SID Windows du processus StackQL, y compris les UID numériques de conteneur sans entrée passwd. Aucun identifiant n'est présenté et STACKQL_CALLER_TOKEN est ignoré. Ce mode est uniquement local : il est refusé pour les appelants HTTP. L'appartenance à des groupes du système d'exploitation n'accorde aucun accès ; seule l'appartenance à l'annuaire le fait.

Échéance de session​

Par défaut, les requêtes n'ont pas d'échéance dérivée de l'authentification. Les identifiants sont vérifiés et l'appartenance à l'annuaire est actualisée à chaque nouvelle instruction : un identifiant expiré ne peut donc pas lancer de nouveau travail, mais l'expiration n'interrompt pas une instruction déjà autorisée. Définissez "enforce_session_deadline": true pour annuler à max_session_seconds (valeur par défaut 300, maximum 86400), échéance raccourcie par l'expiration du JWT ou du certificat. Cela ne renouvelle pas les jetons.

Annuaire des principaux​

Les identités sont associées à des principaux, et les principaux à des groupes, dans quatre tables du backend SQLite ou PostgreSQL configuré :

TableContenu
stackql_access_principalsID du principal et objet JSON d'attributs de type chaîne de caractères. Un attribut tenant sert d'espace de noms à l'état IaC en préversion.
stackql_access_identitiesCorrespondance entre une paire (issuer, subject) vérifiée et l'ID du principal.
stackql_access_groupsID de groupe.
stackql_access_membershipsLiaisons entre principal et groupe.

Provisionnez les tables, les identités et les appartenances par une connexion d'administration de base de données de confiance avant de servir des requêtes protégées :

INSERT INTO stackql_access_principals (id, attributes) VALUES ('alice', '{}');
INSERT INTO stackql_access_groups (id) VALUES ('readers');
INSERT INTO stackql_access_identities (issuer, subject, principal_id)
VALUES ('https://identity.example', 'alice', 'alice');
INSERT INTO stackql_access_memberships (principal_id, group_id) VALUES ('alice', 'readers');

Utilisez l'émetteur et le sujet réels du mode : pour l'identité locale de l'OS, ce peut être ('this-host', '1000'), et pour le TLS mutuel ('client-certificates', 'spiffe://example/alice'). Sélectionnez le backend explicitement :

stackql --access.config '{"path":"/etc/stackql/access.json"}' \
--sqlBackend '{"dbEngine":"postgres_tcp","dsn":"postgres://runtime@localhost/stackql?sslmode=require","sqlDialect":"postgres"}' \
exec 'SELECT whoami(), groups();'

L'annuaire produit un instantané immuable pour chaque instruction. La révocation est un DELETE FROM stackql_access_memberships sur la connexion d'administration ; l'instruction suivante voit le nouvel instantané. Les identités inconnues, un schéma absent, des données mal formées et les indisponibilités de l'annuaire entraînent tous un refus d'accès. Le SQL protégé ordinaire ne peut pas accéder aux tables de l'annuaire. Réservez les écritures d'appartenance à la connexion d'administration, protégez le fichier de base de données et utilisez des privilèges de base de données distincts pour l'administration et pour l'exécution lorsque le backend le permet.

Règles de politique​

Chaque règle accorde une action sur une resource à un subject de la forme group:<group id>. Utilisez les identifiants compilés de méthode et d'opération issus de documents de provider de confiance ; un caractère générique d'opération accorde les méthodes de mutation aussi bien que les lectures.

Le groupe readers détient implicitement la capacité SQL de lecture sûre de l'hôte. Les lectures effectuées par des principaux extérieurs à ce groupe nécessitent host/sql/read, et les autres instructions nécessitent execute sur host/sql/<statement kind>. Les opérations de provider et l'utilisation des identifiants nécessitent toujours des règles explicites, et une autorisation accordée sur une collection n'accorde pas ses méthodes sous-jacentes. Vérifications supplémentaires de l'hôte :

RessourceActionPortée
host/sql/readexecuteInstructions de lecture en dehors du groupe de lecteurs implicite
host/sql/execexecuteEXEC natif, y compris les EXEC imbriqués
host/iac/run, host/iac/destroyexecuteLes relations IaC en préversion, malgré leur syntaxe SELECT
host/function/<name>executeFonctions hors de la courte liste d'autorisation des fonctions réputées pures
host/backendreadRelations opaques du backend, stockées et externes
host/credentialsreloadL'outil MCP reload_credentials
session/variablesreadDéréférencement des variables de session et des secrets
session/configwriteSET et UNSET

L'expansion des requêtes stockées est vérifiée avant l'exécution, et la réutilisation des caches de plans et de lignes est désactivée sur les chemins protégés.

Points d'entrée​

Authentificationexec, shell, MCP stdioMCP HTTPS
JWTVariable d'environnement STACKQL_CALLER_TOKENEn-tête de requête Authorization: Bearer
Jeton bearer statiqueVariable d'environnement STACKQL_CALLER_TOKENEn-tête de requête Authorization: Bearer
OS localUID ou SID effectif du processus ; aucun identifiantRefusé
TLS mutuelRefusé : aucune connexion TLS vérifiéeChaîne client vérifiée et un SAN configuré

Fournissez les identifiants locaux de type jeton par l'environnement du processus, jamais sous forme de littéral SQL ni d'argument de ligne de commande. En HTTPS, le vérificateur d'appelant remplace le contrôle par jeton bearer partagé auth_token_env_var décrit dans Authentification des clients HTTP ; la configuration du certificat et de la clé TLS du serveur est obligatoire, et une requête HTTP sans identifiants ne se rabat jamais sur le jeton d'environnement du serveur.

Inspecter l'appelant​

Dans une session authentifiée, whoami() renvoie l'ID du principal et groups() renvoie les groupes de l'annuaire sous forme de tableau JSON :

SELECT whoami() AS principal, groups() AS memberships;
|-----------|-------------|
| principal | memberships |
|-----------|-------------|
| alice | ["readers"] |
|-----------|-------------|

Les deux fonctions nécessitent une session démarrée avec --access.config.

Parcours guidés​

Le dépôt StackQL fournit quatre parcours guidés exécutables, un par mode d'authentification, pilotés par un script Python qui provisionne un annuaire de démonstration et vérifie une requête. Ils ne nécessitent aucun compte cloud et sont exécutés par la suite de tests du projet.