Every access-control system I've tested during red-team work, under NDA and outside it, breaks the same way eventually: not because the model of who's allowed to do what was wrong, but because granting access and revoking it were never built as the same operation. Granting is a single write: add a row, set a flag, issue a token. Revoking has to find every place that grant propagated to and undo it there too, and almost nobody builds revocation with the same care they build grant.
That asymmetry is the whole vulnerability class. It doesn't need a clever payload. It needs patience and a decent map of where a system's permission model and its permission implementation have quietly drifted apart.
Attack Vector: Stale Authorization After Revocation
Remove a user's access at the source of truth, the role table, the admin panel, the IdP group, and check what still works. Cached authorization tokens with a long TTL, session state that was hydrated before the change and never re-checked, downstream service mirrors that sync on a schedule instead of an event: all of these keep honoring a grant that no longer exists anywhere a human would look. The tell is a system with one visible place to manage permissions and three or four invisible places that also cache them. Test revocation the same way you'd test authentication: immediately, and again after the cache TTL you'd expect, and again after a service restart.
Attack Vector: Parent-ACL Overgrant
Permission systems love inheritance because it's convenient to administer: grant at the folder, tenant, or workspace level and let it cascade. The break shows up at the edges of that convenience. A child object created before a restrictive policy was applied to its parent often keeps its original, looser permissions, because the inheritance engine runs on writes, not retroactively on every existing descendant. Sharing links are the sharpest version of this: a link generated while a folder was public frequently keeps working after the folder is locked down, because the link is a capability, not a live permission check. Anywhere a system distinguishes "policy" from "the actual set of things that currently satisfy the policy," that gap is real and it's usually untested.
Attack Vector: Sibling-Tenant Credential Reuse
In multi-tenant systems, isolation is supposed to be a hard boundary, but it's frequently implemented as a soft one: a shared signing secret with a tenant ID embedded in the token payload rather than a per-tenant cryptographic boundary, or a database query that filters by tenant ID but trusts the caller to supply the right one instead of deriving it server-side from the authenticated identity. A session or API key minted for tenant A, replayed with tenant B's identifier substituted somewhere the client controls, validates cleanly because the signature only ever proved "this came from someone with a valid key," never "this came from someone authorized for this specific tenant." This is the multi-tenant version of an IDOR, and it's the first thing worth checking in any SaaS product built fast.
Blue Team Defense: Make Revocation an Event, Not a Cleanup Job
Every system that grants access needs a symmetric, tested code path that revokes it, propagated through every cache, mirror, and downstream consumer, on the same timeline as the grant itself. If granting access is instant and revoking it is "eventually, on the next sync," that gap is a standing vulnerability, not an acceptable latency tradeoff. Treat revocation propagation time as a monitored SLA, the same way you'd monitor authentication latency.