> ## Documentation Index
> Fetch the complete documentation index at: https://docs.readdy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SQL Editor and Advanced Permissions

> Query your database, control access to tables and rows, and restore supported permission changes in Readdy Backend

Open **"Backend"** → **"Database"** in a project connected to [Readdy Backend](/features/backend). Use **"SQL Editor"** for queries and scripts, or **"Permissions"** to review access and preview changes before applying them. To edit a few records without SQL, use **"Table Editor"**.

Owners and Editors can run supported SQL and preview permissions. Only the **Owner** can apply or restore permissions, manage custom roles, or run SQL grants and revocations. Viewers cannot use these tools.

<Warning>
  SQL writes and applied permission changes affect your connected database immediately. Try unfamiliar changes in a separate test project first. Permission history cannot recover deleted data or tables.
</Warning>

## Run SQL

<Steps>
  <Step title="Open SQL Editor">
    Click **"SQL Editor"** and enter a query. To check the connection, run:

    ```sql theme={null}
    SELECT 1 AS connection_check;
    ```

    Use the table directory to find your table and column names. For larger tables, add `LIMIT 100` to keep results manageable.
  </Step>

  <Step title="Run Your Query or Script">
    Click **"Run all"** to execute the editor contents, or select complete statements and click **"Run selection"**.

    Separate statements with semicolons. If you use a transaction, include `BEGIN` and its matching `COMMIT` or `ROLLBACK` in the same run; you cannot leave a transaction open between clicks.
  </Step>

  <Step title="Check the Result">
    Review the result or error below the editor. Run queries separately when you need to inspect each result in a multi-statement script.

    After a timeout or lost response, check the affected data before retrying a write—it may already have completed.
  </Step>
</Steps>

SQL Editor supports queries, data changes, and supported table-structure changes in `public`. It does not expose every PostgreSQL command, such as creating arbitrary database functions or administering the database server. Protected objects may have additional restrictions.

## Change Permissions

<Steps>
  <Step title="Select an Object">
    Click **"Permissions"**, choose an **"Object category"**, and open the table or other object you want to manage.

    <Frame>
      <img src="https://mintcdn.com/readdy/KH2-McIsN27v6sJc/images/sql-advanced-permissions/permission-directory.png?fit=max&auto=format&n=KH2-McIsN27v6sJc&q=85&s=3ee55fa103fdf8241e6c18860d230de4" alt="Database permission directory with object category, schema, and name filters" width="718" height="632" data-path="images/sql-advanced-permissions/permission-directory.png" />
    </Frame>
  </Step>

  <Step title="Choose the Role and Access">
    Select the recipient role and the permissions to grant or revoke. For a table, choose **"Table grants"** or **"Column grants"** under **"Permission scope"**.

    | Role | Applies to |
    | - | - |
    | `anon` | Requests from signed-out website visitors |
    | `authenticated` | Requests from signed-in website users |
    | `PUBLIC` | Every database role, including signed-out and signed-in users |

    Granting access to `authenticated` does not limit users to their own records. Use row-level security for that restriction.
  </Step>

  <Step title="Preview and Apply">
    Click **"Preview differences"** and review the object, role, **"Before"** / **"After"** values, and warnings. As the Owner, select the confirmation checkbox and click **"Confirm and apply"**.

    If permissions changed after your preview, read the latest permissions and prepare a new preview.
  </Step>

  <Step title="Verify Website Access">
    Use **"Read latest permissions"**, then test the affected website action as the intended signed-in or signed-out user. Database permission changes take effect without republishing the website.

    If the submission result is uncertain, use **"Query original operation"** to check it before submitting again.
  </Step>
</Steps>

<Note>
  A revoked direct grant may still be allowed through `PUBLIC`, a broader table grant, or another permission source. Check **"Effective privileges"** as well as **"Direct grants"**. Schema access and row rules can still restrict access.
</Note>

<AccordionGroup>
  <Accordion title="What other permissions can I manage?">
    * **Sequences:** control access to generated IDs; an insert may need sequence access in addition to table access.
    * **Functions:** allow or revoke execution of an existing PostgreSQL function. Select the exact argument signature when names repeat. These are separate from [Backend Functions](/features/backend#using-functions).
    * **Schemas:** allow object lookup; this does not grant access to the tables inside.
    * **New object defaults:** set grants for future objects created by the selected creator. Existing objects are unchanged.

    Objects marked read-only cannot be changed through this editor.
  </Accordion>

  <Accordion title="How do I create a custom database role?">
    As the Owner, open **"Permissions"** → **"Custom roles"** → **"Create role"**. Enter a name starting with a letter, using up to 48 lowercase letters, numbers, or underscores. Add an optional description, select the confirmation checkbox, and submit.

    Then select that role in an object's permission editor to grant access. Creating a role does not create a login or automatically assign it to website users. For normal signed-in user access, use `authenticated` and row policies.

    To delete a custom role, first resolve the grants and dependencies shown in **"Custom roles"**.
  </Accordion>
</AccordionGroup>

## Limit Users to Their Own Rows

Row-level security (RLS) controls which records a website user can read or change. For user-specific rules, first set up [Authentication](/features/authentication) and ensure your table stores the owner's user ID.

<Steps>
  <Step title="Open the Row Policy Draft">
    Open your table in **"Permissions"** and select **"Row policy draft"** under **"Permission scope"**. Choose **"Create policy"**, enter a name, and select the command and recipient role.

    For example, to let signed-in users read their own records, choose `SELECT` and `authenticated`.
  </Step>

  <Step title="Define the Row Rule">
    Choose a policy mode. **Permissive** policies allow access when any permissive policy matches. **Restrictive** policies add a condition that must also match; a permissive policy must still allow access.

    For the read-own-records example, choose **"Current user owns the row"** under **"Visible rows (USING)"** and select the column containing the user's ID.

    For inserts or updates, also complete **"Written rows (WITH CHECK)"** when shown. You can use a related membership table for shared records, or combine supported rules with **"All rules must match"** or **"Any rule may match"**.
  </Step>

  <Step title="Apply and Test the Rule">
    Preview the differences, then confirm and apply as the Owner. Check that RLS is enabled on the table and that the role has the required table permissions.

    Test through your website with two signed-in users and a signed-out visitor. Confirm both the actions that should work and those that should be denied.
  </Step>
</Steps>

<Warning>
  Creating a policy does not enable RLS. If it is disabled, enable it through SQL Editor using `ALTER TABLE public.your_table ENABLE ROW LEVEL SECURITY;`, replacing `your_table` with the actual table name. Review existing policies first: another permissive policy may still allow broader access. SQL Editor uses management access, so its results do not prove what website users can access.
</Warning>

## Restore a Permission Change

<Steps>
  <Step title="Find the Operation">
    Open **"Permissions"** → **"Operation history"** and click **"Review restoration"** on a supported operation.

    <Frame>
      <img src="https://mintcdn.com/readdy/KH2-McIsN27v6sJc/images/sql-advanced-permissions/operation-history.png?fit=max&auto=format&n=KH2-McIsN27v6sJc&q=85&s=f43faed93f8d504f8459b3b61ebd6355" alt="Permission operation history with query and restoration actions" width="718" height="632" data-path="images/sql-advanced-permissions/operation-history.png" />
    </Frame>
  </Step>

  <Step title="Review What Will Be Restored">
    Select the permission settings to restore, then click **"Prepare restoration preview"**. Review the current and proposed values.

    If later changes conflict with the operation, restoration is blocked. Review current permissions and prepare a new change instead.
  </Step>

  <Step title="Confirm the Restoration">
    As the Owner, select the confirmation checkbox and click **"Confirm and apply"**. Check the result and test website access again.
  </Step>
</Steps>

Restoration creates a new operation in history. It restores only the selected supported permissions—not table rows, dropped objects, or the entire database. Operation history is not a complete log of SQL Editor activity.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Why is Confirm and apply disabled?">
    Only the Owner can apply changes. Check the confirmation checkbox and any displayed warnings. If the preview is outdated, read the latest permissions and prepare a new one.
  </Accordion>

  <Accordion title="Why does my website still show permission denied?">
    Check the actual request role, **"Effective privileges"**, and the table's row policies. For inserts, also check generated-ID sequence access and the policy's **"Written rows (WITH CHECK)"** rule.
  </Accordion>

  <Accordion title="Why can't I edit an existing row policy?">
    Complex policies or policies modified outside the supported visual builder may be read-only. The builder cannot edit every SQL policy expression.
  </Accordion>

  <Accordion title="Why are these tools unavailable?">
    Check your project membership and Readdy Backend connection. If your project uses an external [Supabase integration](/integrations/supabase), manage it through Supabase's own tools.
  </Accordion>
</AccordionGroup>

## Need Help?

If this guide doesn't resolve your issue, [submit a support ticket](https://readdy.ai/feedback). We're here to help!


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.