# Prevent Privilege Escalation in SaaS Invite Flows

> Prevent invite-based privilege escalation by binding each invite to tenant, recipient, role ceiling, expiry, single-use state, and current delegation authority at acceptance.

Canonical URL: https://www.devobs.io/articles/saas-invite-flows-without-privilege-escalation/
By: Finn Larson
Published: 2023-10-29T06:47:47.060Z
Updated: 2026-09-06T10:18:15.722Z
Section: Authorization

An invitation is a pending authorization change, not merely an email link. Store the exact tenant, intended recipient, grantable role, inviter, expiry, and one-time state on the server. Check the inviter's authority when the invitation is created and check it again when it is accepted.

## Model the invitation as a state machine

Use states such as pending, accepted, revoked, expired, and superseded. Transitions should happen atomically. Acceptance should consume the token and create or update membership in one transaction, so two clicks cannot create conflicting roles. Store only a cryptographic hash of a high-entropy token, rate-limit verification, and give failures a response that does not reveal whether an email or tenant exists.

Bind the record to an immutable tenant ID and a role or permission bundle chosen at creation. Never accept a role from the acceptance request. If the product lets an invitee choose among teams, store the authorized set and validate the choice server-side. The [OWASP Authorization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html) recommends least privilege, deny by default, and creating tests that validate whether permissions are enforced as designed. Those rules apply to delayed invitation transitions too.

Define a delegation ceiling. A project admin may invite project members but cannot issue tenant-owner access. A tenant owner may delegate only roles allowed by platform policy. Evaluate indirect grants too: if the inviter can place someone in a group mapped to owner, the group operation is equivalent to assigning owner. The service that commits membership must enforce this, even when the UI hides stronger roles.

## Recheck authority at acceptance

The most important race is easy to miss. Ana creates an admin invitation on Monday; on Tuesday her own admin membership is revoked; the recipient accepts on Wednesday. If acceptance trusts only the signed token, Ana's old authority survives revocation. Load the current inviter or sponsoring authority and ensure it can still delegate the stored role. Otherwise revoke the invitation or route it to a new approver.

Choose deliberately what happens when the inviter leaves but the invitation is ordinary and low privilege. A tenant-owned sponsorship model can allow another authorized administrator to adopt pending invites. Record the adoption; do not silently change the actor in the audit trail.

Recipient binding also needs a policy. Email possession is useful delivery proof but may be weak identity proof for high privilege, forwarded mail, recycled addresses, or aliases. Current [NIST SP 800-63B digital identity guidance](https://pages.nist.gov/800-63-4/sp800-63b.html) defines authentication assurance levels and explains that stronger authentication is required at higher assurance levels. For sensitive roles, require the recipient to authenticate with the account explicitly named by the invitation and use authentication strength appropriate to your assurance requirement. The same [NIST SP 800-63B guidance](https://pages.nist.gov/800-63-4/sp800-63b.html) also states that when a higher assurance level is required, an authentication process may provide step-up authentication to raise the session's AAL.

## Keep account linking separate

If the recipient is signed in as a different identity, stop and explain the mismatch. Do not automatically merge accounts because email addresses match. Offer a controlled switch-account or account-linking flow that proves both identities. Prevent an existing low-privilege member from using an invitation intended for someone else to upgrade themselves.

Send notifications without embedding authority details unnecessarily. The link should reveal nothing until redeemed over TLS; the acceptance page can show tenant and role after authentication. Notify [tenant administrators](https://www.devobs.io/articles/delegated-tenant-admin-boundaries/) of privileged invitations and their acceptance. Audit creation, delivery attempts, revocation, adoption, acceptance, actor, target identity, tenant, role, and request correlation.

## Test hostile transitions

Test double acceptance, concurrent revoke and accept, inviter demotion, tenant deletion, role removal, token theft, email change, wrong signed-in account, and an invitation created just before policy changes. Assert the resulting membership and audit record, not only the HTTP status.

The next step is to write the transition table for your highest role and add the inviter-revoked-before-acceptance test. Reviewed 2026-09-06. Re-review when role delegation or authentication assurance changes.

## Source references

- <https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html>
- <https://pages.nist.gov/800-63-4/sp800-63b.html>
