Removed, but still inside
You removed a contractor from your team at 2:00pm. At 2:40pm they downloaded the customer list.
This answers: Why can a removed user still access data? No coding needed. 3 quick decisions.
- Who may see what
- Who is signed in
Step 1 of 3
Your security rule checks the role like this. Why did it still let them in?
create policy "team members read customers"on customers for selectusing ( (auth.jwt() ->> 'team_role') in ('admin', 'member') );Why can a removed user still access data?
If your security rules read the user's role from their sign-in token ( claims), the old role stays valid until that token expires, an hour by default in . Signing them out doesn't revoke a token already issued. Check team membership in the database inside your policies, so every request sees the current team list.
Breaks at Database: Rule trusts the role in an old token
Why AI tools write this bug
AI tools often follow tutorials that put roles in custom claims because it makes policies short and fast, without mentioning the revocation delay.
How to fix it
- Find policies that read roles with auth.jwt().
- Replace them with a lookup in the team members table.
- Index the membership table for fast checks.
- Test removal by removing a member and retrying at once.
Check your own app
Paste this into Lovable, Cursor or Claude Code:
Without changing anything, list every security rule (RLS policy) and server check in this project that decides access by role or team. For each, tell me whether it reads the role from the sign-in token (JWT claims) or looks it up in the database, and what would happen in the first hour after someone is removed from a team.
Common questions
- Should I shorten token lifetime instead?
- It narrows the window but doesn't close it, and causes more refreshes. Checking membership in the database removes the window.