with one click
db-impersonate
Set session claims to emulate authenticated user for RLS testing
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Set session claims to emulate authenticated user for RLS testing
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Execute story development with selectable automation modes to accommodate different developer preferences, skill levels, and story complexity.
Set up a Kord-aligned documentation baseline (no legacy frameworks)
Create Next Story Task methodology and workflow
Validate Next Story Task methodology and workflow
advanced-elicitation methodology and workflow
No checklists needed - this task facilitates brainstorming sessions, validation is through user interaction methodology and workflow
| name | db-impersonate |
| description | Set session claims to emulate authenticated user for RLS testing |
| agent | architect |
| subtask | false |
Set session claims to emulate authenticated user for RLS testing
Parameter:* mode (optional, default: interactive)
Purpose:* Definitive pass/fail criteria for task completion
Checklist:*
acceptance-criteria:
- [ ] Data persisted correctly; constraints respected; no orphaned data
type: acceptance-criterion
blocker: true
validation: |
Assert data persisted correctly; constraints respected; no orphaned data
error_message: "Acceptance criterion not met: Data persisted correctly; constraints respected; no orphaned data"
Strategy:* retry
Common Errors:*
Error:* Connection Failed
Error:* Query Syntax Error
Error:* Transaction Rollback
user_id (uuid): User ID to impersonateAsk user:
{user_id}CRITICAL WARNING*: This is for testing only. Never use in production application code.
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 <<SQL
-- Set JWT claims for current session
SELECT
set_config('request.jwt.claims',
jsonb_build_object(
'sub', '{user_id}',
'role', 'authenticated'
)::text,
true
) AS jwt_claims,
set_config('request.jwt.claim.sub', '{user_id}', true) AS sub,
set_config('role', 'authenticated', true) AS role;
-- Verify settings
SELECT
current_setting('request.jwt.claims', true) AS jwt_claims,
current_setting('request.jwt.claim.sub', true) AS user_id,
current_setting('role', true) AS role;
\echo ''
\echo '✓ Impersonating user: {user_id}'
\echo 'Run your test queries now.'
\echo 'To exit, close this session or run: RESET ALL;'
SQL
Open interactive psql for testing:
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1
User can now run queries as this user:
-- Test queries
SELECT * FROM my_table; -- Should respect RLS for this user
-- Check current context
SELECT
auth.uid() AS current_user_id,
current_setting('role') AS current_role;
-- Exit impersonation
RESET ALL;
Test that user CAN access their own data:
-- User should see their own records
SELECT * FROM users WHERE id = auth.uid();
-- User should see their own fragments
SELECT * FROM fragments WHERE user_id = auth.uid();
Test that user CANNOT access others' data:
-- Should return empty (not their data)
SELECT * FROM fragments WHERE user_id != auth.uid();
-- Should fail if trying to insert as another user
INSERT INTO fragments (user_id, content)
VALUES ('00000000-0000-0000-0000-000000000000', 'test');
-- Expected: RLS policy violation
If using org-based isolation:
-- Set org_id in JWT
SELECT set_config('request.jwt.claims',
jsonb_build_object(
'sub', '{user_id}',
'role', 'authenticated',
'org_id', '{org_id}'
)::text,
true
);
-- Test org isolation
SELECT * FROM projects; -- Should only see org's projects
-- 1. Apply new policy
CREATE POLICY "new_policy" ON table_name ...;
-- 2. Impersonate user
impersonate {user_id}
-- 3. Test access
SELECT * FROM table_name;
-- 4. Reset and test as different user
RESET ALL;
impersonate {other_user_id}
SELECT * FROM table_name;
User reports "can't see their data":
-- 1. Impersonate the user
impersonate {user_id}
-- 2. Try their query
SELECT * FROM table_name WHERE ...;
-- 3. Check what RLS policies are active
SELECT * FROM pg_policies
WHERE tablename = 'table_name';
-- 4. Verify user_id matches
SELECT auth.uid(), user_id FROM table_name LIMIT 5;
-- User A
impersonate {user_a_id}
SELECT COUNT(*) FROM fragments; -- Returns A's count
-- User B
impersonate {user_b_id}
SELECT COUNT(*) FROM fragments; -- Returns B's count
-- Verify isolation
SELECT user_id, COUNT(*) FROM fragments GROUP BY user_id;
-- Should only show current user in impersonation
Settings are session-local and reset when:
RESET ALL; is executedNever use this in application code:*
If using service role key, RLS is bypassed completely:
RLS policies respect these settings even in functions:
CREATE FUNCTION get_user_data()
RETURNS TABLE(...)
LANGUAGE sql
SECURITY DEFINER -- Function runs as owner
AS $$
SELECT * FROM table_name; -- Still respects RLS
$$;
To stop impersonating:
-- Reset all session variables
RESET ALL;
-- Or just close the psql session
\q
Problem*: Claims not set correctly
Fix*: Verify claim format and role setting
-- Check current settings
SELECT
current_setting('request.jwt.claims', true),
current_setting('role', true);
Problem*: Using service role or RLS not enabled
Fix*:
rls-auditProblem*: Role not set to authenticated
Fix*: Ensure role is set:
SELECT set_config('role', 'authenticated', true);
Typical testing workflow:
dry-run migration.sql - Syntax checkapply-migration migration.sql - Apply changesimpersonate {test_user_id} - Test as userimpersonate {other_user_id} - Test isolationrls-audit - Verify coverage🔒 This is a testing tool only*
Never bypass Supabase Auth in production. Always use: