You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: serverless/sql-databases/how-to/use-row-level-security.mdx
+66Lines changed: 66 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -84,3 +84,69 @@ This requires setting up different [IAM permissions sets](/identity-and-access-m
84
84
<Messagetype="tip">
85
85
Note that row level security and policies can be created or deleted by a table owner. In this example, you can check table owner with the following command `select * from pg_tables where tablename = 'pets';`.
86
86
</Message>
87
+
88
+
## Use Row Level Security with PostgREST
89
+
90
+
PostgREST built-in Row Level Security based on users JWT relies either on [role impersonation](https://docs.postgrest.org/en/v12/references/auth.html#user-impersonation) or [transaction-scoped settings](https://docs.postgrest.org/en/v12/references/transactions.html#tx-settings). Due to connection pooling, Serverless SQL Database currently only support transaction-scoped settings and requires using a single PostgreSQL role for all queries (the internal `role_readwrite` in PostgreSQL).
-`db-uri` should use credentials with an application having **ServerlessSQLDatabaseDataReadWrite** permissions (and not **ServerlessSQLDatabaseDataReadWrite** neither **ServerlessSQLDatabaseFullAccess**)
102
+
-`db-schemas` is your database schema. You can use `"public"` as a default value.
103
+
-`jwt-secret` can be generated using the command `openssl rand -base64 32`
104
+
105
+
3. Run PostgREST:
106
+
```bash
107
+
postgrest tutorial.conf
108
+
```
109
+
You can check that your are able to query your database by [generating a JWT](https://docs.postgrest.org/en/v12/tutorials/tut1.html#step-3-sign-a-token) with the payload data `{"role": "role_readwrite"}`:
110
+
```bash
111
+
curl http://localhost:3000/pets \
112
+
-H "Authorization: Bearer $TOKEN"
113
+
```
114
+
where `$TOKEN` is your generated JWT.
115
+
A pet list should display.
116
+
117
+
4. Connect to your Serverless SQL Database with **ServerlessSQLDatabaseFullAccess** permissions, and delete the existing policy on the `pets` table:
118
+
```sql
119
+
DROP POLICY pets_keeper ON pets;
120
+
```
121
+
122
+
5. Create a new policy on the `pets` table:
123
+
```sql
124
+
CREATE POLICY pets_keeper ON pets TO role_readwrite
125
+
USING (keeper = current_setting('request.jwt.claims', true)::json->>'user_type');
126
+
```
127
+
This policy will use `current_settings` instead on `current_user` and thus check for additional fields contained by the JWT instead of only the `"role"` field.
128
+
129
+
6. Generate a JWT with the following payload data:
130
+
```json
131
+
{
132
+
"role": "role_readwrite",
133
+
"user_type": "role_readwrite"
134
+
}
135
+
```
136
+
<Messagetype="tip">
137
+
In this configuration, `user_type` value from JWT will be checked against `keeper` column value in your database to authorize access. You can replace `"user_type": "role_readwrite"` by any alternative field name or value depending on your use case. However you need to keep `"role": "role_readwrite"` for any kind of users you want to authenticate through PostgREST, because alternative roles (such as `role_admin`) will already have too much privileges and be able to see any data.
138
+
</Message>
139
+
140
+
7. Query your database using this JWT through PostgREST:
141
+
```bash
142
+
curl http://localhost:3000/pets \
143
+
-H "Authorization: Bearer $TOKEN"
144
+
```
145
+
You should only see pets with a `keeper` column value of `role_readwrite`.
146
+
147
+
Your new application can now only access a specific subset of rows based on its permissions using transaction-scoped settings.
148
+
149
+
<Messagetype="tip">
150
+
You can change your JWT payload data with `"user_type": "role_admin"` and see that only another set of rows will be displayed. You can go further by adding any additional fields or values to filter, and edit your policy to filter on a more complex set of rules.
0 commit comments