1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 11:14:04 +00:00

[4.x] Make forcing RLS configurable (#1293)

* Add `$forceRls` static property to tenants:rls

* Set `$forceRls` in tests where scoping is tested, add non-superuser, non-bypassrls table owner test

* Move DROP TABLE statement

* Remove try/catch

* Put DROP OWNED BY into try/catch

* Static property cleanup in afterEach

* Make with() matrix syntax more clear by using with() multiple times

* Fix typo, improve comment

* Move and update force RLS comment

* Add test for `$forceRls = false`, refactor BYPASSRLS test

* Update link in test comment

* Add a dataset for `$forceRls` in the table owner test, fix BYPASSRLS test

* Correct PR link comment

* minor fixes

* Add test that makes the bypassrls/forceRls behavior clear

* Delete redundant test

* cleanup

* Update tests/RLS/TableManagerTest.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Samuel Štancl <samuel@archte.ch>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
lukinovec 2025-06-05 05:06:05 +02:00 committed by GitHub
parent e74e1f92e1
commit 2057e1e5ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 181 additions and 20 deletions

View file

@ -22,6 +22,23 @@ class CreateUserWithRLSPolicies extends Command
protected $description = "Creates RLS policies for all tables related to the tenant table. Also creates the RLS user if it doesn't exist yet";
/**
* Force, rather than just enable, the created RLS policies.
*
* By default, table owners bypass RLS policies. When this is enabled,
* they also need the BYPASSRLS permission. If your setup lets you create
* a user with BYPASSRLS, you may prefer leaving this on for additional
* safety. Otherwise, if you can't use BYPASSRLS, you can set this to false
* and depend on the behavior of table owners bypassing RLS automatically.
*
* This setting generally doesn't affect behavior at all with "default"
* setups, however if you have a more custom setup, with additional users
* involved (e.g. central connection user not being the same user that
* creates tables, or the created "RLS user" creating some tables) you
* should take care with how you configure this.
*/
public static bool $forceRls = true;
public function handle(PermissionControlledPostgreSQLSchemaManager $manager): int
{
$username = config('tenancy.rls.user.username');
@ -49,14 +66,9 @@ class CreateUserWithRLSPolicies extends Command
// Enable RLS scoping on the table (without this, queries won't be scoped using RLS)
DB::statement("ALTER TABLE {$table} ENABLE ROW LEVEL SECURITY");
/**
* Force RLS scoping on the table, so that the table owner users
* don't bypass the scoping table owners bypass RLS by default.
*
* E.g. when using a custom implementation where you create tables as the RLS user,
* the queries won't be scoped for the RLS user unless we force the RLS scoping using this query.
*/
DB::statement("ALTER TABLE {$table} FORCE ROW LEVEL SECURITY");
if (static::$forceRls) {
DB::statement("ALTER TABLE {$table} FORCE ROW LEVEL SECURITY");
}
}
/**