# A feature flag cohort is not authorization

A feature flag or experiment cohort decides which UI or code path you see. It is not a grant to read or change a specific object.

## The trap

You gate a new “export invoices” button with `flags.on('invoice_export_v2')`, then the export handler runs `SELECT * FROM invoices WHERE org_id = :org` with no per-row authorization for the caller.

That proves the cohort includes this session. It does not prove this user may export every invoice in the org, including ones policy would hide in the old UI.

## Why flags fail as authz

- Flags are product rollout and experimentation, not access policy.
- Cohort membership is usually coarse (user, org, percentage), not object-scoped.
- Direct API, jobs, and admin tools can hit the same endpoints without the flagged UI.
- After you remove someone from a role, they may still sit in the experiment cohort until flags refresh.

## Tiny checklist

1. Does every sensitive handler authorize the actor on each resource id, even behind a flag?
2. Can a flagged user call the API with a sibling’s object id and succeed?
3. After access is revoked, does cohort membership still unlock the export?
4. Do unflagged clients (mobile, partners, cron) use the same object checks?

Keep feature flags for shipping safely. Put authorization on the server next to every sensitive read and write.
