datasette/docs
Simon Willison 2b879e462f Implement resource-based permission system with SQL-driven access control
This introduces a new hierarchical permission system that uses SQL queries
for efficient permission checking across resources. The system replaces the
older permission_allowed() pattern with a more flexible resource-based
approach.

Core changes:

- New Resource ABC and Action dataclass in datasette/permissions.py
  * Resources represent hierarchical entities (instance, database, table)
  * Each resource type implements resources_sql() to list all instances
  * Actions define operations on resources with cascading rules

- New plugin hook: register_actions(datasette)
  * Plugins register actions with their associated resource types
  * Replaces register_permissions() and register_resource_types()
  * See docs/plugin_hooks.rst for full documentation

- Three new Datasette methods for permission checks:
  * allowed_resources(action, actor) - returns list[Resource]
  * allowed_resources_with_reasons(action, actor) - for debugging
  * allowed(action, resource, actor) - checks single resource
  * All use SQL for filtering, never Python iteration

- New /-/tables endpoint (TablesView)
  * Returns JSON list of tables user can view
  * Supports ?q= parameter for regex filtering
  * Format: {"matches": [{"name": "db/table", "url": "/db/table"}]}
  * Respects all permission rules from configuration and plugins

- SQL-based permission evaluation (datasette/utils/actions_sql.py)
  * Cascading rules: child-level → parent-level → global-level
  * DENY beats ALLOW at same specificity
  * Uses CTEs for efficient SQL-only filtering
  * Combines permission_resources_sql() hook results

- Default actions in datasette/default_actions.py
  * InstanceResource, DatabaseResource, TableResource, QueryResource
  * Core actions: view-instance, view-database, view-table, etc.

- Fixed default_permissions.py to handle database-level allow blocks
  * Now creates parent-level rules for view-table action
  * Fixes: datasette ... -s databases.fixtures.allow.id root

Documentation:

- Comprehensive register_actions() hook documentation
- Detailed resources_sql() method explanation
- /-/tables endpoint documentation in docs/introspection.rst
- Deprecated register_permissions() with migration guide

Tests:

- tests/test_actions_sql.py: 7 tests for core permission API
- tests/test_tables_endpoint.py: 13 tests for /-/tables endpoint
- All 118 documentation tests pass
- Tests verify SQL does filtering (not Python)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 10:32:18 -07:00
..
_static Add favicon to documentation (#1967) 2022-12-31 11:00:31 -08:00
_templates Drop jQuery dependency 2023-03-26 16:38:58 -07:00
.gitignore Added initial docs, including a changelog 2017-11-16 07:11:00 -08:00
authentication.rst New allowed_resources_sql plugin hook and debug tools (#2505) 2025-10-08 14:27:51 -07:00
auto-build.sh Added --load-extension argument to datasette serve 2017-11-16 08:48:49 -08:00
binary_data.rst Use shot-scraper images from datasette-screenshots repo, closes #1844 2022-10-14 12:57:00 -07:00
changelog.rst Release 1.0a19 2025-04-21 22:38:53 -07:00
cli-reference.rst Documentation for datasette serve environment variables 2024-09-09 09:18:47 -07:00
codespell-ignore-words.txt Move Metadata to --internal database 2024-06-11 09:33:23 -07:00
conf.py track_event() mechanism for analytics and plugins 2024-01-31 15:21:40 -08:00
configuration.rst Configuration via the command-line section 2024-02-05 13:43:50 -08:00
contributing.rst New allowed_resources_sql plugin hook and debug tools (#2505) 2025-10-08 14:27:51 -07:00
csv_export.rst Use shot-scraper images from datasette-screenshots repo, closes #1844 2022-10-14 12:57:00 -07:00
custom_templates.rst New .core CSS class for inputs and buttons 2024-09-03 08:37:26 -07:00
datasette-0.51.png Release 0.51 2020-10-31 15:21:49 -07:00
datasette-logo.svg Added new logo to the documentation 2020-07-12 12:53:29 -07:00
deploying.rst Remove all remaining "$ " prefixes from docs, closes #2140 2023-08-11 10:44:34 -07:00
ecosystem.rst Shrunk ecosystem docs in favour of datasette.io, closes #1182 2021-01-09 14:17:18 -08:00
events.rst More links between events documentation 2024-02-01 15:42:45 -08:00
facets.rst Move non-metadata configuration from metadata.yaml to datasette.yaml 2023-10-12 09:16:37 -07:00
full_text_search.rst Move non-metadata configuration from metadata.yaml to datasette.yaml 2023-10-12 09:16:37 -07:00
getting_started.rst Replace Glitch with Codespaces, closes #2488 2025-05-28 19:17:22 -07:00
index.rst Removed broken refs to Glitch, closes #2503 2025-09-28 21:15:58 -07:00
installation.rst Python 3.14, drop Python 3.9 2025-10-08 13:11:32 -07:00
internals.rst catalog_views table, closes #2495 2025-07-15 10:22:56 -07:00
introspection.rst Implement resource-based permission system with SQL-driven access control 2025-10-24 10:32:18 -07:00
javascript_plugins.rst JavaScript plugins documentation, closes #2250 2024-02-05 11:47:17 -08:00
json_api.rst Correct syntax for link headers, closes #2470 2025-03-09 20:05:43 -05:00
Makefile Added documentation on the Datasette Ecosystem 2019-01-31 19:36:07 -08:00
metadata.rst Removed units functionality and Pint dependency 2024-08-20 19:03:33 -07:00
metadata_doc.py Rename metadata tables and add schema to docs, refs #2382 2024-08-05 13:53:55 -07:00
pages.rst Fix global-power-points references 2025-05-28 19:07:46 -07:00
performance.rst Release 0.63a1 2022-10-23 20:07:09 -07:00
plugin_hooks.rst Implement resource-based permission system with SQL-driven access control 2025-10-24 10:32:18 -07:00
plugins.rst New allowed_resources_sql plugin hook and debug tools (#2505) 2025-10-08 14:27:51 -07:00
publish.rst Remove all remaining "$ " prefixes from docs, closes #2140 2023-08-11 10:44:34 -07:00
settings.rst Further wording tweaks 2025-04-16 08:25:03 -07:00
spatialite.rst Remove all remaining "$ " prefixes from docs, closes #2140 2023-08-11 10:44:34 -07:00
sql_queries.rst Move non-metadata configuration from metadata.yaml to datasette.yaml 2023-10-12 09:16:37 -07:00
testing_plugins.rst Docs on temporary plugins in fixtures, closes #2234 2024-01-12 14:12:14 -08:00
upgrade_guide.rst Markup fix 2024-08-05 14:07:16 -07:00
writing_plugins.rst New .core CSS class for inputs and buttons 2024-09-03 08:37:26 -07:00