sections: internals:permission-sql-parameters
This data as json
| id | page | ref | title | content | breadcrumbs | references |
|---|---|---|---|---|---|---|
| internals:permission-sql-parameters | internals | permission-sql-parameters | Available SQL parameters | When writing SQL for PermissionSQL , the following parameters are automatically available: :actor - JSON string or NULL The full actor dictionary serialized as JSON. Use SQLite's json_extract() function to access fields: json_extract(:actor, '$.role') = 'admin' json_extract(:actor, '$.team') = 'engineering' :actor_id - string or NULL The actor's id field, for simple equality comparisons: :actor_id = 'alice' :action - string The action being checked (e.g., "view-table" , "insert-row" , "execute-sql" ). Example usage: Here's an example plugin that grants view-table permissions to users with an "analyst" role for tables in the "analytics" database: from datasette import hookimpl from datasette.permissions import PermissionSQL @hookimpl def permission_resources_sql(datasette, actor, action): if action != "view-table": return None return PermissionSQL( source="my_analytics_plugin", sql=""" SELECT 'analytics' AS parent, NULL AS child, 1 AS allow, 'Analysts can view analytics database' AS reason WHERE json_extract(:actor, '$.role') = 'analyst' AND :action = 'view-table' """, params={}, ) A more complex example that uses custom parameters: @hookimpl def permission_resources_sql(datasette, actor, action): if not actor: return None user_teams = actor.get("teams", []) return PermissionSQL( source="team_permissions_plugin", sql=""" SELECT team_database AS parent, team_table AS child, 1 AS allow, 'User is member of team: ' || team_name AS reason FROM team_permissions WHERE user_id = :user_id AND :action IN ('view-table', 'insert-row', 'update-row') """, params={"user_id": actor.get("id")}, ) Permission resolution rules: When multiple PermissionSQL objects return conflicting rules for the same resource, Datasette applies the following precedence: Specificity : Child-level rules (with both parent and child ) override parent-level rules (with only parent ), which override root-level rules (with neither parent nor child ) Deny over allow : At the same specificity level, deny ( allow=0 ) takes precedence over allow ( allow=1 ) Implicit deny : If no rules match a resource, access is denied by default | ["Internals for plugins", "Permission classes and utilities", "PermissionSQL class"] | [] |