Back to home
Security

How UserDesk protects your tenant

We built UserDesk with a zero-trust architecture. Even if our entire database were compromised, attackers cannot access your Microsoft 365 tenant.

We never store your credentials

UserDesk does not store Microsoft 365 passwords, admin credentials, or long-lived API keys. Authentication is handled entirely by Microsoft's OAuth 2.0 authorization code flow with PKCE. When a user signs in, they authenticate directly with Microsoft — UserDesk never sees or handles their password.

After authentication, Microsoft issues a short-lived access token (valid for ~1 hour) and a refresh token. These tokens are encrypted inside a signed JWT session cookie stored in the user's browser — not in our database.

What we store in our database

Our database contains only subscription and portal metadata:

  • Tenant IDYour Microsoft 365 tenant identifier (a GUID). This identifies your organization but grants no access on its own.
  • User email & nameThe email and display name of each person who has signed into the portal. Used for the audit log and role assignments.
  • Portal rolesWhether each user is an Admin, Member, or Viewer within UserDesk.
  • Subscription statusYour Stripe subscription ID and billing status (active, past due, canceled).
  • Audit log entriesA record of actions taken through the portal — who did what and when.
  • TemplatesOnboarding template configurations (department, job title, license SKU IDs, group IDs).
Key point:None of this data can be used to access your Microsoft 365 tenant. There are no passwords, no API keys, no client secrets for your tenant, and no stored access tokens in the database.

What happens if our database is breached

If an attacker gained full access to our database, they would find tenant IDs, email addresses, portal roles, and audit log entries. They would not find:

  • Access tokensStored only in encrypted browser session cookies, not in the database.
  • Refresh tokensSame — encrypted in the session JWT, never persisted server-side.
  • PasswordsWe never receive or store Microsoft 365 passwords.
  • Client secretsOur app's client secret is stored as an environment variable on Vercel, not in the database.

An attacker with our database alone cannot sign into your tenant, cannot call the Microsoft Graph API on your behalf, cannot reset passwords, and cannot read your users' data. The database is essentially a billing and audit ledger.

How authentication actually works

Here's the full authentication flow, step by step:

1

User clicks Sign in

The browser redirects to Microsoft's login page (login.microsoftonline.com). UserDesk never handles the password.

2

Microsoft authenticates the user

MFA, conditional access, and all your tenant's security policies apply. Microsoft issues an authorization code.

3

Code exchange (server-side)

Our server exchanges the authorization code for an access token and refresh token using our app's client credentials + PKCE. This happens server-to-server.

4

Session cookie created

The tokens are encrypted into a signed JWT and stored as an HttpOnly, Secure, SameSite cookie in the user's browser. The tokens never touch our database.

5

API calls use the user's token

When the user takes an action (e.g., reset a password), UserDesk calls the Microsoft Graph API using that user's access token. The action is performed as that user, with their permissions.

6

Token refresh

When the access token expires (~1 hour), UserDesk uses the refresh token to get a new one. This is transparent to the user.

7

Sign out

The session cookie is deleted. The tokens are gone. There is nothing persisted server-side to revoke.

Delegated permissions, not application permissions

UserDesk uses delegated permissions, not application permissions. This is a critical distinction:

  • DelegatedThe app acts on behalf of the signed-in user. It can only do what that user is allowed to do. If the user signs out, the app has no access. This is what UserDesk uses.
  • ApplicationThe app has its own identity and can access data without a user being signed in. UserDesk does NOT use this model.

This means UserDesk has zero standing access to your tenant. When no one is actively using the portal, there are no valid tokens and no way to access your data. The app cannot "phone home" or run background operations against your tenant.

Admin consent and permission scopes

During initial setup, a Global Admin approves the following Microsoft Graph permission scopes:

  • User.ReadWrite.AllRead and write user profiles (create accounts, update details, enable/disable).
  • Directory.ReadWrite.AllRead and write directory data (required for license assignment and group management).
  • Group.ReadWrite.AllRead and write groups (manage Teams, distribution lists, security groups).
  • UserAuthenticationMethod.ReadWrite.AllReset passwords (required for the password reset feature).

These scopes define the maximum set of actions the app can perform. Within UserDesk, the portal role system (Admin/Member/Viewer) further restricts what each individual user can do. A Viewer, for example, cannot take any write actions even though the permission scopes allow it.

Revoking access

Your Global Admin can revoke UserDesk's access at any time from the Azure Portal → Enterprise Applications → UserDesk → Properties → Delete. This immediately invalidates all tokens and removes the app's consent from your tenant. No data migration, no export needed — UserDesk doesn't hold any of your data.

Infrastructure security

  • HostingVercel (AWS-backed), with automatic HTTPS, DDoS protection, and edge caching for static assets.
  • DatabasePostgreSQL on Supabase with encrypted connections (SSL required), row-level isolation by tenant.
  • Security headersEvery response includes X-Frame-Options (DENY), HSTS, X-Content-Type-Options, XSS Protection, Referrer-Policy, and Permissions-Policy.
  • Rate limitingSensitive write operations (password resets, user creation) are rate-limited per IP to prevent abuse.
  • Audit trailEvery action is logged with the actor, target, timestamp, and metadata. Entries are immutable.
  • Session securitySession cookies are HttpOnly, Secure, SameSite=Lax. Tokens are encrypted in a signed JWT.

Questions?

If you have security questions or need additional detail for your compliance review, contact us at hello@getuserdesk.com. We're happy to walk through the architecture with your security team.

Ready to get started?

Connect your Microsoft 365 tenant in under 2 minutes. Your data stays in your tenant — we just help your team manage it.