{"ok": true, "next": null, "rows": [{"id": "authentication:allowdebugview", "page": "authentication", "ref": "allowdebugview", "title": "The /-/allow-debug tool", "content": "The  /-/allow-debug  tool lets you try out different   \"action\"  blocks against different  \"actor\"  JSON objects. You can try that out here:  https://latest.datasette.io/-/allow-debug", "breadcrumbs": "[\"Authentication and permissions\", \"Permissions\"]", "references": "[{\"href\": \"https://latest.datasette.io/-/allow-debug\", \"label\": \"https://latest.datasette.io/-/allow-debug\"}]"}, {"id": "authentication:authentication-default-deny", "page": "authentication", "ref": "authentication-default-deny", "title": "Denying all permissions by default", "content": "By default, Datasette allows unauthenticated access to view databases, tables, and execute SQL queries. \n                 You may want to run Datasette in a mode where  all  access is denied by default, and you explicitly grant permissions only to authenticated users, either using the  --root mechanism  or through  configuration file rules  or plugins. \n                 Use the  --default-deny  command-line option to run Datasette in this mode: \n                 datasette --default-deny data.db --root \n                 With  --default-deny  enabled: \n                 \n                     \n                         Anonymous users are denied access to view the instance, databases, tables, and queries \n                     \n                     \n                         Authenticated users are also denied access unless they're explicitly granted permissions \n                     \n                     \n                         The root user (when using  --root ) still has access to everything \n                     \n                     \n                         You can grant permissions using  configuration file rules  or plugins \n                     \n                 \n                 For example, to allow only a specific user to access your instance: \n                 datasette --default-deny data.db --config datasette.yaml \n                 Where  datasette.yaml  contains: \n                 allow:\n  id: alice \n                 This configuration will deny access to everyone except the user with  id  of  alice .", "breadcrumbs": "[\"Authentication and permissions\", \"Permissions\"]", "references": "[]"}, {"id": "authentication:authentication-permissions-allow", "page": "authentication", "ref": "authentication-permissions-allow", "title": "Defining permissions with \"allow\" blocks", "content": "One way to define permissions in Datasette is to use an  \"allow\"  block  in the datasette.yaml file . This is a JSON document describing which actors are allowed to perform an action against a specific resource. \n                 Each  allow  block is compiled into SQL and combined with any\n                     plugin-provided rules  to produce\n                    the cascading allow/deny decisions that power  await .allowed(*, action, resource, actor=None) . \n                 The most basic form of allow block is this ( allow demo ,  deny demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow:\n      id: root\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 This will match any actors with an  \"id\"  property of  \"root\"  - for example, an actor that looks like this: \n                 {\n    \"id\": \"root\",\n    \"name\": \"Root User\"\n} \n                 An allow block can specify \"deny all\" using  false  ( demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow: false\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 An  \"allow\"  of  true  allows all access ( demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow: true\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 Allow keys can provide a list of values. These will match any actor that has any of those values ( allow demo ,  deny demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow:\n      id:\n      - simon\n      - cleopaws\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 This will match any actor with an  \"id\"  of either  \"simon\"  or  \"cleopaws\" . \n                 Actors can have properties that feature a list of values. These will be matched against the list of values in an allow block. Consider the following actor: \n                 {\n    \"id\": \"simon\",\n    \"roles\": [\"staff\", \"developer\"]\n} \n                 This allow block will provide access to any actor that has  \"developer\"  as one of their roles ( allow demo ,  deny demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow:\n      roles:\n      - developer\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 Note that \"roles\" is not a concept that is baked into Datasette - it's a convention that plugins can choose to implement and act on. \n                 If you want to provide access to any actor with a value for a specific key, use  \"*\" . For example, to match any logged-in user specify the following ( allow demo ,  deny demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow:\n      id: \"*\"\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 You can specify that only unauthenticated actors (from anonymous HTTP requests) should be allowed access using the special  \"unauthenticated\": true  key in an allow block ( allow demo ,  deny demo ): \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow:\n      unauthenticated: true\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 Allow keys act as an \"or\" mechanism. An actor will be able to execute the query if any of their JSON properties match any of the values in the corresponding lists in the  allow  block. The following block will allow users with either a  role  of  \"ops\"  OR users who have an  id  of  \"simon\"  or  \"cleopaws\" : \n                 [[[cog\nfrom metadata_doc import config_example\nimport textwrap\nconfig_example(cog, textwrap.dedent(\n  \"\"\"\n    allow:\n      id:\n      - simon\n      - cleopaws\n      role: ops\n    \"\"\").strip(),\n    \"YAML\", \"JSON\"\n  ) \n                 ]]] \n                 [[[end]]] \n                 Demo for cleopaws ,  demo for ops role ,  demo for an actor matching neither rule .", "breadcrumbs": "[\"Authentication and permissions\", \"Permissions\"]", "references": "[{\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%22id%22%3A+%22root%22%7D&allow=%7B%0D%0A++++++++%22id%22%3A+%22root%22%0D%0A++++%7D\", \"label\": \"allow demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%22id%22%3A+%22trevor%22%7D&allow=%7B%0D%0A++++++++%22id%22%3A+%22root%22%0D%0A++++%7D\", \"label\": \"deny demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22root%22%0D%0A%7D&allow=false\", \"label\": \"demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22root%22%0D%0A%7D&allow=true\", \"label\": \"demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22cleopaws%22%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%5B%0D%0A++++++++%22simon%22%2C%0D%0A++++++++%22cleopaws%22%0D%0A++++%5D%0D%0A%7D\", \"label\": \"allow demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22pancakes%22%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%5B%0D%0A++++++++%22simon%22%2C%0D%0A++++++++%22cleopaws%22%0D%0A++++%5D%0D%0A%7D\", \"label\": \"deny demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22simon%22%2C%0D%0A++++%22roles%22%3A+%5B%0D%0A++++++++%22staff%22%2C%0D%0A++++++++%22developer%22%0D%0A++++%5D%0D%0A%7D&allow=%7B%0D%0A++++%22roles%22%3A+%5B%0D%0A++++++++%22developer%22%0D%0A++++%5D%0D%0A%7D\", \"label\": \"allow demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22cleopaws%22%2C%0D%0A++++%22roles%22%3A+%5B%22dog%22%5D%0D%0A%7D&allow=%7B%0D%0A++++%22roles%22%3A+%5B%0D%0A++++++++%22developer%22%0D%0A++++%5D%0D%0A%7D\", \"label\": \"deny demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22simon%22%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%22*%22%0D%0A%7D\", \"label\": \"allow demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22bot%22%3A+%22readme-bot%22%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%22*%22%0D%0A%7D\", \"label\": \"deny demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=null&allow=%7B%0D%0A++++%22unauthenticated%22%3A+true%0D%0A%7D\", \"label\": \"allow demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22hello%22%0D%0A%7D&allow=%7B%0D%0A++++%22unauthenticated%22%3A+true%0D%0A%7D\", \"label\": \"deny demo\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22cleopaws%22%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%5B%0D%0A++++++++%22simon%22%2C%0D%0A++++++++%22cleopaws%22%0D%0A++++%5D%2C%0D%0A++++%22role%22%3A+%22ops%22%0D%0A%7D\", \"label\": \"Demo for cleopaws\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22trevor%22%2C%0D%0A++++%22role%22%3A+%5B%0D%0A++++++++%22ops%22%2C%0D%0A++++++++%22staff%22%0D%0A++++%5D%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%5B%0D%0A++++++++%22simon%22%2C%0D%0A++++++++%22cleopaws%22%0D%0A++++%5D%2C%0D%0A++++%22role%22%3A+%22ops%22%0D%0A%7D\", \"label\": \"demo for ops role\"}, {\"href\": \"https://latest.datasette.io/-/allow-debug?actor=%7B%0D%0A++++%22id%22%3A+%22percy%22%2C%0D%0A++++%22role%22%3A+%5B%0D%0A++++++++%22staff%22%0D%0A++++%5D%0D%0A%7D&allow=%7B%0D%0A++++%22id%22%3A+%5B%0D%0A++++++++%22simon%22%2C%0D%0A++++++++%22cleopaws%22%0D%0A++++%5D%2C%0D%0A++++%22role%22%3A+%22ops%22%0D%0A%7D\", \"label\": \"demo for an actor matching neither rule\"}]"}, {"id": "authentication:authentication-permissions-explained", "page": "authentication", "ref": "authentication-permissions-explained", "title": "How permissions are resolved", "content": "Datasette performs permission checks using the internal  await .allowed(*, action, resource, actor=None) , method which accepts keyword arguments for  action ,  resource  and an optional  actor . \n                 resource  should be an instance of the appropriate  Resource  subclass from  datasette.resources \u2014for example  InstanceResource() ,  DatabaseResource(database=\"... )`` or  TableResource(database=\"...\", table=\"...\") . This defaults to  InstanceResource()  if not specified. \n                 When a check runs Datasette gathers allow/deny rules from multiple sources and\n                    compiles them into a SQL query. The resulting query describes all of the\n                    resources an actor may access for that action, together with the reasons those\n                    resources were allowed or denied. The combined sources are: \n                 \n                     \n                         allow  blocks configured in  datasette.yaml . \n                     \n                     \n                         Actor restrictions  encoded into the actor dictionary or API token. \n                     \n                     \n                         The \"root\" user shortcut when  --root  (or  Datasette.root_enabled ) is active, replying  True  to all permission chucks unless configuration rules deny them at a more specific level. \n                     \n                     \n                         Any additional SQL provided by plugins implementing  permission_resources_sql(datasette, actor, action) . \n                     \n                 \n                 Datasette evaluates the SQL to determine if the requested  resource  is\n                    included. Explicit deny rules returned by configuration or plugins will block\n                    access even if other rules allowed it.", "breadcrumbs": "[\"Authentication and permissions\", \"Permissions\"]", "references": "[]"}], "truncated": false}