Identities
End users of your application — Account-level rows that hold credentials and federation hints, granted access into specific Applications and Environments through memberships and role assignments.
Overview
An identity represents a single end user of your application. Each identity belongs to exactly one Account — the same email can exist in multiple Accounts as completely separate identities, and authentication always requires an Account context. An identity carries an email, first and last name, optional metadata, and an optional external_id for federated identities. Identities are the subject of the RBAC system — every permission check resolves whether an identity has a permission at a given node in a given Environment. An identity row can exist before the person ever signs in — for example, when an admin pre-provisions accounts for a launch — and stays around after they're deactivated, so the assignment history is preserved.
Scope
Identities span three scopes
Unlike permissions and roles, an identity isn't a single per-Environment record. The same identity reaches across your Account through three layers, and each layer answers a different question.
This is why a Promote operation moves the configuration of an Environment (permissions, roles, hierarchy) but leaves identities and their assignments alone — those are operational state you choose per env.
Layers in practice
Each layer is a separate row type with its own home in the dashboard. The table below maps the concept to the concrete row and the screen where you create or edit it.
| Layer | Row type | Where to manage | What it holds |
|---|---|---|---|
| Account | Identity | Tenant > Identities | Email, name, optional external_id, is_active. The directory of every end user in your Account; this row exists independently of any App or Environment. |
| Application | AppMembership | Identity drawer > Memberships tab | A row linking one identity to one Application. Decides which Apps the identity can sign into. No role attached — access inside the App is granted by Environment-level assignments. |
| Environment | Role assignment | Access Control > Identities (per Environment) | A row linking identity + role + hierarchy node, with optional start/end dates. Decides what the identity can do in that Environment and where in the hierarchy that access applies. |
An identity can sit at the Account layer with no AppMembership and no assignment — that's a directory-only row, useful for pre-provisioning, federated lookup, or staged onboarding. Adding an AppMembership lets the person sign into that App; adding role assignments in an Environment grants them concrete access.
Lifecycle
Each identity row has an is_active column. The dashboard surfaces it as one of three states:
Deactivation is reversible and audit-preserving — that's the recommended path. Deletion is supported but hard: the row is removed and assignment history goes with it.
Authentication
Identities authenticate two ways. Hosted login via OAuth2/OIDC (/oauth/authorize) is the standard path — your app redirects, Canopy handles the password ceremony, and you get back a signed JWT. Direct API (/v1/identity/auth/*) is the lower-level surface for apps that want to own the login UI; the same JWT comes back. Password validation, email verification, password reset, and session management run on the platform either way. Your app never stores credentials when you delegate authentication to Canopy — alternatively, you can handle authentication yourself and use Canopy purely for authorization.
How to add identities
Pick the path that matches how identities enter your system. The dashboard options are best for admin-driven onboarding handled by a person clicking through the UI; the API options are best for automated, scripted, or self-serve flows kicked off by your own backend. Each card links to a walkthrough.
Dashboard invite
Admin clicks Invite & Assign in the dashboard; Canopy emails the invitee a link to set their own password.
Dashboard create
Admin opens the Create Identity dialog; the identity row is written immediately, with an optional starting password.
Dashboard CSV import
6-step wizard for batch provisioning from a CSV — preview, map columns, validate against live Account data, then submit up to 200 rows per request.
API invite
Programmatic invitation flow — your backend issues invites, Canopy sends the email (or hands back the link for self-delivery).
API create
Server-to-server identity creation through the public API — no email, no acceptance ceremony.