mirror of
https://github.com/simonw/datasette.git
synced 2026-10-07 18:06:59 +02:00
Explain permission decisions
This commit is contained in:
parent
db82123108
commit
8c42f79323
7 changed files with 803 additions and 167 deletions
|
|
@ -45,7 +45,10 @@ Using the "root" actor
|
|||
|
||||
Datasette currently leaves almost all forms of authentication to plugins - `datasette-auth-github <https://github.com/simonw/datasette-auth-github>`__ for example.
|
||||
|
||||
The one exception is the "root" account, which you can sign into while using Datasette on your local machine. The root user has **all permissions** - they can perform any action regardless of other permission rules.
|
||||
The one exception is the "root" account, which you can sign into while using
|
||||
Datasette on your local machine. The root user starts with **all permissions**:
|
||||
Datasette contributes a global allow rule for every action. More specific deny
|
||||
rules can still override that global rule.
|
||||
|
||||
The ``--root`` flag is designed for local development and testing. When you start Datasette with ``--root``, the root user automatically receives every permission, including:
|
||||
|
||||
|
|
@ -84,12 +87,14 @@ Click on that link and then visit ``http://127.0.0.1:8001/-/actor`` to confirm t
|
|||
Permissions
|
||||
===========
|
||||
|
||||
Datasette's permissions system is built around SQL queries. Datasette and its plugins construct SQL queries to resolve the list of resources that an actor cas access.
|
||||
|
||||
The key question the permissions system answers is this:
|
||||
|
||||
Is this **actor** allowed to perform this **action**, optionally against this particular **resource**?
|
||||
|
||||
Every permission decision can be understood in terms of those three values.
|
||||
Datasette implements the decisions using SQL, but you do not need to understand
|
||||
the generated SQL to configure or debug permissions.
|
||||
|
||||
**Actors** are :ref:`described above <authentication_actor>`.
|
||||
|
||||
An **action** is a string describing the action the actor would like to perform. A full list is :ref:`provided below <actions>` - examples include ``view-table`` and ``execute-sql``.
|
||||
|
|
@ -138,7 +143,59 @@ This configuration will deny access to everyone except the user with ``id`` of `
|
|||
How permissions are resolved
|
||||
----------------------------
|
||||
|
||||
Datasette performs permission checks using the internal :ref:`datasette_allowed`, method which accepts keyword arguments for ``action``, ``resource`` and an optional ``actor``.
|
||||
Permission rules describe an effect (``allow`` or ``deny``) at one of three
|
||||
levels:
|
||||
|
||||
``resource``
|
||||
A specific child resource, such as the ``analytics/sales`` table.
|
||||
|
||||
``parent``
|
||||
A parent resource, such as the ``analytics`` database. A parent rule also
|
||||
applies to its child resources.
|
||||
|
||||
``global``
|
||||
Every resource for that action.
|
||||
|
||||
Datasette resolves matching rules from most specific to least specific:
|
||||
|
||||
#. Resource rules take precedence over parent and global rules.
|
||||
#. Parent rules take precedence over global rules.
|
||||
#. If both allow and deny rules match at the same level, deny takes precedence.
|
||||
#. If no rule matches, access is denied.
|
||||
|
||||
This means a resource-level allow can provide an exception to a parent-level
|
||||
deny. It also means that two plugins which disagree at the same level resolve
|
||||
to deny.
|
||||
|
||||
.. list-table:: Permission rule examples
|
||||
:header-rows: 1
|
||||
|
||||
* - Matching rules
|
||||
- Result
|
||||
- Explanation
|
||||
* - Global allow
|
||||
- Allow
|
||||
- The global rule is the most specific matching rule.
|
||||
* - Global allow, parent deny
|
||||
- Deny
|
||||
- The parent rule is more specific.
|
||||
* - Parent deny, resource allow
|
||||
- Allow
|
||||
- The resource rule is more specific.
|
||||
* - Resource allow and resource deny
|
||||
- Deny
|
||||
- Deny takes precedence at the same level.
|
||||
* - No matching rules
|
||||
- Deny
|
||||
- Permissions default to deny when no rule applies.
|
||||
|
||||
The built-in public defaults are global allow rules for actions such as
|
||||
``view-instance``, ``view-database`` and ``view-table``. They follow the same
|
||||
precedence rules as configuration and plugin rules. The ``--default-deny``
|
||||
option prevents Datasette from contributing those default allow rules.
|
||||
|
||||
Datasette performs checks using :ref:`datasette_allowed`, which accepts keyword
|
||||
arguments for ``action``, ``resource`` and an optional ``actor``.
|
||||
|
||||
``resource`` should be an instance of the appropriate ``Resource`` subclass from :mod:`datasette.resources`—for example ``InstanceResource()``, ``DatabaseResource(database="...``)`` or ``TableResource(database="...", table="...")``. This defaults to ``InstanceResource()`` if not specified.
|
||||
|
||||
|
|
@ -149,12 +206,18 @@ resources were allowed or denied. The combined sources are:
|
|||
|
||||
* ``allow`` blocks configured in :ref:`datasette.yaml <authentication_permissions_config>`.
|
||||
* :ref:`Actor restrictions <authentication_cli_create_token_restrict>` encoded into the actor dictionary or API token.
|
||||
* The "root" user shortcut when ``--root`` (or :attr:`Datasette.root_enabled <datasette.app.Datasette.root_enabled>`) is active, replying ``True`` to all permission chucks unless configuration rules deny them at a more specific level.
|
||||
* The "root" user rule when ``--root`` (or :attr:`Datasette.root_enabled <datasette.app.Datasette.root_enabled>`) is active. This is a global allow rule, so a more specific configuration deny can override it.
|
||||
* Any additional SQL provided by plugins implementing :ref:`plugin_hook_permission_resources_sql`.
|
||||
|
||||
Datasette evaluates the SQL to determine if the requested ``resource`` is
|
||||
included. Explicit deny rules returned by configuration or plugins will block
|
||||
access even if other rules allowed it.
|
||||
Actor restrictions are applied after the allow/deny rules. They act as an
|
||||
additional allowlist: a restriction can remove access but cannot grant access
|
||||
that the actor did not already have. See
|
||||
:ref:`authentication_cli_create_token_restrict`.
|
||||
|
||||
Some actions have dependencies on other actions. These are evaluated as an
|
||||
``AND`` condition. For example, ``execute-sql`` also requires
|
||||
``view-database``: both decisions must be allowed for the final result to be
|
||||
allowed.
|
||||
|
||||
.. _authentication_permissions_allow:
|
||||
|
||||
|
|
@ -1145,11 +1208,26 @@ The debug tool at ``/-/permissions`` is available to any actor with the ``permis
|
|||
|
||||
datasette -s permissions.permissions-debug true data.db
|
||||
|
||||
The page shows the permission checks that have been carried out by the Datasette instance.
|
||||
The permission debug tools answer four different questions:
|
||||
|
||||
It also provides an interface for running hypothetical permission checks against a hypothetical actor. This is a useful way of confirming that your configured permissions work in the way you expect.
|
||||
Why was this decision allowed or denied?
|
||||
Use :ref:`PermissionCheckView`. It shows every matching rule, identifies
|
||||
the winning specificity level, applies actor restrictions and evaluates
|
||||
any required actions.
|
||||
|
||||
This is designed to help administrators and plugin authors understand exactly how permission checks are being carried out, in order to effectively configure Datasette's permission system.
|
||||
Which resources can the current actor access?
|
||||
Use :ref:`AllowedResourcesView` to view an access map for a selected
|
||||
action.
|
||||
|
||||
Which raw rules did Datasette and its plugins contribute?
|
||||
Use :ref:`PermissionRulesView` to inspect the rules before they are
|
||||
resolved into decisions.
|
||||
|
||||
Which checks has this Datasette instance performed recently?
|
||||
Use ``/-/permissions`` to view recent permission activity.
|
||||
|
||||
These tools are designed to help administrators and plugin authors understand
|
||||
and confirm the effective permissions configuration.
|
||||
|
||||
These debug endpoints are exempt from the :ref:`JSON API stability promise <json_api_stability>` - their JSON shapes may change in future releases.
|
||||
|
||||
|
|
@ -1184,11 +1262,28 @@ This endpoint requires the ``permissions-debug`` permission.
|
|||
Permission check view
|
||||
---------------------
|
||||
|
||||
The ``/-/check`` endpoint evaluates a single action/resource pair and returns information indicating whether the access was allowed along with diagnostic information.
|
||||
The ``/-/check`` endpoint evaluates and explains a single actor, action and
|
||||
resource decision. The explanation includes:
|
||||
|
||||
* Every matching allow and deny rule, with its source and reason.
|
||||
* The winning resource, parent or global scope.
|
||||
* Rules ignored because a more specific rule matched, or because a deny won at
|
||||
the same scope.
|
||||
* Actor restriction allowlists that included or excluded the resource.
|
||||
* Additional actions required by the requested action.
|
||||
* An explicit default-deny explanation when no rule matched.
|
||||
|
||||
This endpoint provides an interactive HTML form interface. Add ``.json`` to the URL path (e.g. ``/-/check.json?action=view-instance``) to get the raw JSON response instead.
|
||||
|
||||
Pass ``?action=`` to specify the action to check, and optional ``?parent=`` and ``?child=`` parameters to specify the resource.
|
||||
Pass ``?action=`` to specify the action to check, and optional ``?parent=`` and
|
||||
``?child=`` parameters to specify the resource. The interactive form also
|
||||
accepts actor JSON, allowing a hypothetical actor to be tested without signing
|
||||
in as that actor. The JSON endpoint accepts the same value using the ``actor``
|
||||
query string parameter. Use ``actor=null`` to represent an anonymous actor.
|
||||
|
||||
This endpoint requires the ``permissions-debug`` permission. The hypothetical
|
||||
actor is used only for the decision being explained; access to the debug tool
|
||||
is checked against the actor who is actually signed in.
|
||||
|
||||
.. _authentication_ds_actor:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue