Troubleshoot access policies
Diagnose queries that fail, return fewer rows than expected, or stop working after enforcement is turned on.
Use this page to diagnose and resolve common issues with access policies, and refer to Data access enforcement for more information.
Why did my query fail?
Find the error you received to identify the cause:
| Result | Cause | Resolution |
|---|---|---|
| A 403 naming a table or column | No policy grants that data to this user. | Add the table or column to a policy covering the user's group. |
| A 403 stating the query uses constructs that cannot be evaluated | Retool parsed the query but cannot determine what data it touches. | Rewrite the query using simpler constructs. |
| A 403 about a catalog or introspection schema | The query reads database catalog tables, which are always blocked. | Query application tables instead. |
| A 403 about GUI mode | GUI mode queries are blocked for users with granular grants. | Write the query in SQL. |
| A 403 about public apps | The query has no signed-in user to evaluate policies against. | Access policies do not support public or embedded apps. |
| A 403 about non-interactive workflow runs | The workflow run has no user to attribute it to. Refer to Why did my workflow stop working?. | Query a resource without enforcement turned on. |
| A 403 stating policy evaluation failed | A filter value could not be resolved for this user, often a missing user attribute. | Check that the user has the attributes the policy's filters reference. |
| A 400 about malformed SQL | Retool could not parse the query at all. | Fix the syntax error. |
For the reason code each failure carries, refer to Error codes.
Why can't I query the resource at all?
Every query failing, rather than one query failing, usually means no active policy covers you. An enforced resource is closed by default, so a user with no applicable grant is blocked from every table on it. This applies to admins and the resource owner too.
Ask someone with Own access to the resource to check that:
- You belong to a group named in a policy's Apply to list.
- The policy is active. An inactive policy grants nothing.
- The policy covers the environment you are querying.
- You are not a member of a group named in the policy's Except list.
Why is my query returning fewer rows than expected?
Row filters narrow results silently, with no error and no indication that data was withheld. If a query returns fewer rows than you expect, or none at all, a filter is applying.
Two behaviors explain most cases:
- The columns you select change the rows you get. Grants are combined across the columns a query references, so adding a column can narrow the result to nothing. To find the column responsible, remove columns from the select list one at a time until the rows return. Refer to The rows returned depend on the columns selected for an example.
- A broad policy is overriding a narrow one. A policy that grants a column with no row filter leaves that column unfiltered, no matter what other policies restrict it. If a restriction seems to have no effect, look for a whole-table or Full access policy still active on the resource. Deactivate it, or add the affected group to its Except list to keep it in place for everyone else. Refer to Grant broad access and restrict with exceptions.
Why does my join fail?
A join fails when the column it joins on is not part of a grant, even if every column in the select list is granted. ID columns are no exception. Primary and foreign keys are not granted automatically.
Add the join columns to the rule explicitly. The same applies to columns used only in a WHERE or GROUP BY clause.
Why did my workflow stop working?
Evaluating a policy requires a user. A workflow run that Retool cannot attribute to a user is blocked with the error code headless_workflow_run.
A run has no user to attribute it to when it is triggered by:
- A schedule.
- A webhook.
- A query.
- An email.
- Another agent.
Runs started manually, from the workflow editor, or from a button in an app are also blocked unless your organization is configured to attribute them to the user who started them. That configuration is off by default. Refer to The Current User object for how workflows resolve the user a run belongs to.
The block applies per query rather than to the run as a whole, so the run starts and only the blocks querying that resource fail. A workflow that also writes elsewhere can partially complete, which matters for workflows written before enforcement was turned on.
Point workflows at a resource without data access enforcement turned on. Refer to Use a separate resource for workflow queries for guidance on separating resources for access policies and workflows.
How do I find out which data I can access?
Policies are visible only to users with Own access to the resource. Without it, you cannot open the Access Enforcement tab, and error messages name the table or column involved without naming the policy responsible.
Retool includes the grants that apply to you in the schema information it gives agents, covering the actions you are allowed, the tables and columns available and unavailable to you, and the columns that row filters reference. The policies themselves, and the values their filters compare against, are not included.
This means you can ask an agent which tables and columns you can reach on the resource, and it answers from your own grants. It cannot tell you which policy grants them, or what a row filter compares against, so it can tell you a column is restricted without telling you which rows you get.
Grants in agent schema information are available on cloud instances only. For self-hosted instances, ask a user with Own access to the resource instead.
Where can I see which queries were blocked?
Blocked queries and queries narrowed by a row filter are written to audit logs, along with policy creation, updates, and deletion. Entries record which policies applied.
Refer to Audit events for the event names, and View user audit logs for how to read them.