Checking access after an Airtable migration
When migration is chosen, I record collaborator access and the rules people rely on, then compare effective permissions in the destination. Row-level policies need to preserve those restrictions. A migration should not grant new access unintentionally.
I use this reference example to explain the method and checks to try. It includes no client names, schemas, data, or reported results.
How do I compare access before and after migration?
When migration is chosen, I record collaborator access and the rules people rely on, then compare effective permissions in the destination. Row-level policies need to preserve those restrictions.
Method
- Export the collaborator list per base and per interface, including external and read-only collaborators.
- Write down the implicit rules too: the view someone was told not to open is a permission requirement.
- Model roles in a dedicated roles table, never as a column on the user or profile record.
- Enable row-level security on every table and write policies per role, granting only what a policy allows.
- Diff effective access per person before and after, and require sign-off on any widening.
-- for each person, what can they read after migration?
select u.email, t.table_name, has_table_privilege(u.db_role, t.table_name, 'SELECT') as can_read
from migrated_users u cross join migration_tables t
order by u.email, t.table_name;What can go wrong
- Granting broad table access because RLS policies are not written yet.
- Forgetting field-level restrictions that Airtable enforced through hidden fields in a view.
- Using a privileged service account for ordinary reads bypasses row-level policies.
Checks to try
- Per-person access diff shows no unintended widening.
- A test user in each role is denied everything outside their policy set.
Questions this pattern answers
How do I compare access before and after migration?
When migration is chosen, I record collaborator access and the rules people rely on, then compare effective permissions in the destination. Row-level policies need to preserve those restrictions.
What steps does this method use?
Export the collaborator list per base and per interface, including external and read-only collaborators. Write down the implicit rules too: the view someone was told not to open is a permission requirement. Model roles in a dedicated roles table, never as a column on the user or profile record. Enable row-level security on every table and write policies per role, granting only what a policy allows. Diff effective access per person before and after, and require sign-off on any widening.
How can I check the result?
Per-person access diff shows no unintended widening. A test user in each role is denied everything outside their policy set.
What can go wrong with this approach?
Granting broad table access because RLS policies are not written yet. Forgetting field-level restrictions that Airtable enforced through hidden fields in a view. Using a privileged service account for ordinary reads bypasses row-level policies.
Related patterns
Inspecting Airtable dependencies →
The inventory includes forms, scripts, automations, and people’s work.
Preserving Airtable linked records →
Relationship checks compare linked records across systems.
Mapping Airtable automations and scripts →
Each automation has a documented trigger and target.
Comparing migrated data with Airtable →
Counts, checksums, and samples check the copied data.
I explain this method here. The Airtable Rescue Decision Sprint can recommend staying, repairing, connecting tools, or migration. TechTide AI publishes current scope, prices, and terms.
Airtable Rescue Decision Sprint at TechTide AI→© 2026 Alex Cinovoj · TechTide AI · Columbus, OH