Managing users
Add, remove, reshape, and audit the people in your organization from a single table at /admin/users.
The Users page is the most frequently used surface in the admin console. It lists every user whose email domain matches the organization, lets you make point edits from a row menu, and lets you act on many people at once with bulk operations.
The Users table
The table at /admin/users shows one row per user with these columns:
- User — display name plus email. The display name is the SSO name unless an admin has set an override.
- Role — the role assigned to the user. The built-in
adminrole is shown in bold; other roles render as the role name in grey. - Groups — the groups the person belongs to. This column only appears when your organization has at least one group.
- DB Permission — the user's default database permission tier (
viewer,editor, oradmin). This column only appears when the SQL Server extension is allowed for your organization. See Roles and permissions for what each tier allows. - License —
Billed(counts on the subscription) orFree(a free license, not billed). - Status —
ActiveorDisabled. Disabled users cannot sign in and have all sessions revoked. - Last active — relative time since the user's last request (refreshed at most once every 20 seconds by the session middleware).
The table draws 100 people at a time, with Show 100 more and how many are not shown, so it stays quick at any size of organization. The search box above it (Search by name, email or group…) searches the whole organization as you type, and when your organization has groups, Filter by group narrows the list to one.
Click Manage on any row to open the user-manage modal.
The user-manage modal
The modal has up to five tabs:
- Profile — display name override (with a name lock and an avatar lock), role assignment, account status, license, per-user rate limit override, and (with Manage billing) a monthly spend limit, counted in estimated model usage, with a line saying what limit applies to them today and where it comes from (this field, a group or the organization's default) and their estimated usage this month.
- Access — enable or disable individual extensions and connectors for this user, set per-user capability overrides (Analysis, Sub-agents, Sub-agent approvals, Jira writes, Confluence writes), AI model access, and per-connection database access.
- Data & sessions — the user's groups and where their permissions come from, Force sign out (all devices), and three per-user data actions: wipe memory, delete all conversations, and export all data.
- Usage — links out to the user's full billing profile at
/admin/usage/<userId>(full-width charts and tables live there). This tab only appears if your role grantscanViewUsage. - Agents — every scheduled agent this user owns, plus the per-user agent governance controls (lock creation, allowed tools mask).
Setting a display name
Display name in the Profile tab overrides the Microsoft SSO name; leave it blank to use the SSO name. It saves when you leave the field and is audited as user.display_name_changed. The new name shows at once in the dialog's title and everywhere Strata names the member: the Users table, Sessions, Usage, the agents they own, announcements and their read receipts, API key activity, exports, and the invitations they send. The organization's Let members change their display name switch (Organization settings → Profile → Member profiles) does not undo it: while that switch is off, Strata shows the directory name in place of names members set for themselves in Settings, but keeps a name an admin set here. A name an admin saved before late September 2026 counts as the member's own until it is saved here again — clear the field and leave it, then type the name back and leave the field again. Name lock stops Microsoft SSO updates, and the member, from changing the name.
Changing a user's role
In the Profile tab, pick a new role from the Role dropdown; it saves as soon as you pick it. The change is audited as user.role_assigned with the from-role and to-role IDs.
Two safety rails apply:
- Last-admin guard. If demoting this user would leave the organization with zero effective admins, the request is rejected with
Cannot remove the last admin — promote another user to admin first.An effective admin is any active user whose direct role grantscanAccessAdminor who belongs to a group with an admin-granting role bound to it — so a user kept as admin only through a group still counts, and the guard also fires when unbinding that role or removing them from that group would zero the org's admins. - Extension sweep. If the new role allows fewer extensions than the old one, any in-flight OAuth tokens for now-disallowed extensions are revoked on the next request. Jira and Confluence share one Atlassian connection, so that token survives as long as either product is still allowed.
If the new role leaves out a model one of their agents uses, the change still saves, and a toast names those agents — <N> agents will pause — each of which pauses on its next unattended run unless the model is allowed again or the agent is moved to another model; Run now is refused. Only the agents this change newly leaves without their model are named, not ones an earlier change already did. Changing their groups on the Data & sessions tab warns the same way, and so does the bulk Change role action, which names the agents once, when it finishes.
The user's session permissions rehydrate within roughly 30 seconds, and their sidebar picks the change up without a reload the next time their Strata tab comes back into view or focus (at most once a minute). To make the change land immediately, use Force sign out (all devices) in the same modal.
Disabling an account
Account status in the Profile tab switches the user between Active and Disabled. Choosing Disabled asks you to confirm (Disable user), then revokes all their sessions and blocks future sign-ins. If Strata refuses — the user is the organization's last admin, or the account is your own — the select goes back to Active, the server's reason appears under it (Cannot remove the last admin — promote another user to admin first. or You can't disable your own account.), and nothing changes. If Strata can't be reached, the line reads Could not reach Strata, so nothing changed. Try again. Cancelling the confirmation also leaves the user active.
Setting a per-user rate limit
The Rate limit override field takes a number per hour; leave it blank to inherit the cascade. It has no unit of its own: it counts in the unit of the level it overrides — the role's when the role sets a number, otherwise the organization's. While the padlock on Limit per member, per hour under Organization → Member defaults is closed, overrides are ignored. The full cascade is:
user.rate_limit_override → role.default_rate_limit → org.default_rate_limit → env CHAT_RATE_LIMIT_PER_HOUR → 60 chats
See Rate limits and quotas for the complete cascade and what users see when capped.
Per-user capability overrides
The Access tab carries per-user overrides that narrow what a single person can do below their role and the org default.
- Extensions — toggle each integration (SQL Server, Outlook, OneDrive, SharePoint, Microsoft Teams, Web search, Jira, Confluence), and each connector your organization added, on or off for this user. Unticking only narrows what their role and the organization allow; ticking never grants more. A disabled extension or connector disappears everywhere in their UI and is withheld in web chat, the Outlook add-in, Microsoft Teams, their scheduled agents and API keys bound to them. For the Microsoft extensions, and for a per-member connector, turning one off also revokes their stored sign-in. Each box saves as you click it; if Strata refuses the change, the box goes back and the reason appears under that row — Could not check. Try again. when Strata could not check. Jira and Confluence are governed separately but ride one Atlassian connection: turning either off withholds that product's tools from this user's chat and from the agents they own, without disconnecting anything. Their stored Atlassian token is dropped only when neither Jira nor Confluence is allowed for them. See Atlassian extensions.
- Analysis —
Inherit role / org,Allowed, orDenied. The effective value resolves user → role → org default, so this control can grant or deny sandboxed code execution for one user regardless of their role. See Analysis. - Sub-agents —
Inherit role / org,Allowed, orDenied, resolved the same way as Analysis. See Sub-agents. - Sub-agent approvals —
Inherit from role and organization,Members can choose any mode,Up to Do not ask, refuse instead,Up to Ask before anything leaves,Up to Ask only when risky, orAlways ask, shown with the Sub-agents control. It only narrows: the member gets the most restrictive of organization, role and this setting, and the hint under the control shows the result. It saves as soon as you pick a value and is audited asuser.subagent_approval_access_changed. See The Approvals setting. - Jira writes —
Inherit role / org,Allowed (if the org allows), orDenied. See Restricting one user's Jira writes below — the semantics differ from the Analysis control. - Confluence writes — the same three values, resolved the same way but entirely independently of Jira. A member can be free to file issues and blocked from creating pages, or the reverse. See Restricting one user's Confluence writes below.
- AI models — restrict which models this user can pick.
- Database access — a Permission select and an Auto-approve writes select for each org SQL connection. Role default (…) follows their role and names the level it gives them today, for example Role default (Editor); for auto-approve, Role default (On) or Role default (Off) comes from their own role alone. Each select saves on its own; a refused save goes back and says why under the table. Where your organization counts group roles, a role bound to one of their groups can raise the role-default level; where it doesn't yet, Where their permissions come from on the Data & sessions tab says Group roles don't change database access in your organization yet. With no organization connections, the Database access section on this tab reads No organization connections yet. Add one in Organization › Database connections first. See Control who can use a connection.
Restricting one user's Jira writes
Jira writes looks like the Analysis control but does not behave like it. Analysis resolves user → role → org and the most specific level wins, so Allowed there can grant. Jira writes is an intersection: it can only narrow the organization's Let Strata create issues and comment toggle, on the Atlassian extension page (Settings → Apps → Atlassian → Manage, described in Organization).
- Allowed (if the org allows) grants nothing. It means "this user is not narrowed". With the organization's writes off, a user set to Allowed still cannot write — which is what the label is warning you about.
- Denied is the only value here that changes anything: Strata never creates an issue, posts a comment, changes an issue's status or edits an issue's fields on this user's behalf, in chat, in the agents they own, in Teams, or through an API key bound to them.
- Inherit role / org behaves exactly like Allowed.
The role's own Jira writes capability (see Roles and permissions) narrows in the same way, and a Denied at either layer is enough. If an admin has turned on Apply to everyone, with no exceptions for Jira on the Atlassian extension page, this control stops applying entirely and the org toggle is the whole answer.
The help text under the picker shows the resolved answer — Currently enabled for this user or Currently disabled for this user — and rewrites itself as soon as you change the selection, so you can confirm the outcome without reasoning through the layers. Saving is audited as user.jira_write_access_changed with the before and after. The change takes effect on the next request; no session refresh is needed.
If Strata cannot resolve the value — a database error, or a user with no matching record — writes are off. The control fails closed.
Lifting a Denied does not change an Atlassian connection the member already made while it was in place: that connection can still only read Jira until they reconnect, which their Atlassian extension page asks them to do. See Connections made while writing was off. The same applies to Confluence writes.
The same values are readable and settable through GET and PATCH /api/admin/users/:userId/jira-write-access (both require canManageUsers). The PATCH body takes jira_allow_writes_override as "inherit", "allow", or "deny"; the response returns the stored override alongside the resolved effective answer.
Restricting one user's Confluence writes
Confluence writes behaves identically — an intersection that can only narrow, failing closed, with its own per-product Apply to everyone, with no exceptions lock — but it resolves against the organization's Let Strata create pages and comment toggle in the Confluence group of the Atlassian extension page, and against the role's own Confluence writes capability. Nothing crosses over: denying a user Jira writes leaves their Confluence writes untouched, and denying Confluence writes leaves Jira alone. Saving is audited as user.confluence_write_access_changed.
Strata never edits a page that already exists: the only writes it can make are creating a new page and adding a comment, so Denied here is what stops a member's chat or agents from doing either.
Restricting a user's AI models
Strata runs a DB-driven Model Catalog that Kronisys curates centrally; each organization enables the subset it wants from Organization → Models → Model Catalog. See Organization. The models a user can actually pick are the intersection of what the org has enabled, what their role allows, and this per-user override.
In Access → AI models, you see a checkbox per org-enabled model. A model their role doesn't allow — counting roles bound to their groups — is shown unticked with Not allowed by their role and can't be ticked here; widen the role instead. Whatever was stored for it is kept, so if the role later allows it, the user gets it back as before. Built-in roles don't restrict models, so a member on one has no such rows. The line under the list counts the models the user can actually run (This user can use N of M models.). The effective rule is:
- Leave everything checked (or check the full set) — the user inherits the org/role models. No override is stored.
- Uncheck one or more models — the user is limited to the checked set, which can be narrower than the org or their role, but never broader.
- Unchecking every box you can change also resolves to inherit — Strata never locks a user out of every model. The line under the list then reads Nothing is ticked, so this user gets every model their role allows: N of M.
Saving is audited as user.model_access_changed with the before/after model lists. The change applies to chat, agents, the Microsoft Teams bot, and API keys — disabling a model anywhere is enforced everywhere. Unlike turning a model off for the whole organization, which asks first, saving here goes through when this user's agents use a model you untick, and a toast names the agents this save newly leaves without their model: <N> agents will pause — <agent>, <agent>, <agent> and <N> more, owned by <owner>, run on a model this change no longer allows. They pause the next time they run on a schedule, a webhook or another agent, until moved to another model; Run now is refused. Their owner is told. (three names at most; for one agent, <agent>, owned by <owner>, runs on… and Its owner is told.) Such an agent is paused the next time its schedule, a webhook or another agent starts it, and its owner's Inbox says Agent model "<model name>" is not in your own model list. An admin can allow it on your record in Organization › Users, or you can edit this agent to use one of: … (Run now is refused without pausing it). Resume on the agent starts it again once the model is allowed or the agent uses another one; before that, Resume is normally refused with This agent can't resume. … (Voice mode runs on a fixed realtime model the org deploys separately, so the chat-model allowlist doesn't gate it.)
NoteThis is an allowlist that only narrows access. To make a model available in the first place, enable it for the whole organization in the Model Catalog; to widen a role, edit the role's allowed models under Roles and permissions.
Per-user data actions
Three buttons under Data management in the Data & sessions tab cover the most common privacy and offboarding workflows:
- Wipe memory. Clears the user's persistent memory entries and free-text memory blob. Audited as
user.memory_wiped. The user keeps their conversations, settings, and connections. - Delete all conversations. Hard-deletes every conversation and every message belonging to the user. Artifacts cascade. Activity log entries are preserved for org analytics. Audited as
user.conversations_deletedwith the deleted count. - Export all data. The Email me button. Strata builds one ZIP in the background with the user's profile, settings and memory, extension connections (never tokens), groups, every conversation and message, checklists, sub-agent tasks, their own usage figures and the list of their files, across all time, and emails you a download link that expires 24 hours after it is sent. It is the same job as the admin data export for this one member (
POST /api/admin/exportwith their id), so the ZIP holdsmanifest.jsonand one folder for them. Messages are read from every storage tier, archived and cold-stored ones included, and chats the user deleted are included and flagged until they are purged. While it asks, the button reads Requesting…; then a line under the row says Building the export. A download link will be emailed to <your email> when it is ready; it expires 24 hours after it is sent. Nothing downloads in the browser, so a large account no longer runs into the browser's time limit. Because the file carries full message content, this action requires thecanManageCompliancepermission and the org's member-chat-oversight setting must be on. When oversight is off nothing is requested: a line under the row says it needs member chat oversight turned on in Data and privacy (a link, if your role can open it), and that the user can export their own data from Settings › Privacy. If a part of the data could not be read, the ZIP still comes and the member'sexport_info.jsonnames what is missing. The request shares the per-admin limit on bulk actions (20 exports, deletions and other bulk actions per 5 minutes); over it, the row says Too many exports, deletions and other bulk actions in the last few minutes. Try again in a few minutes. Any other failure reads Couldn't request the export. Try again. It is logged asadmin.users_exportedwith scopeselected_users_full_content.
The button labeled Delete user permanently at the bottom of the modal removes the user row plus every related record. See "Deleting a user" below.
Promoting and demoting users
The system uses case-insensitive UUID comparison everywhere the actor matches a target — SQL Server stores UUIDs uppercase while randomUUID() and URL parameters produce lowercase. This matters because:
- You cannot delete your own user. The check
String(userId).toLowerCase() === String(actor.userId).toLowerCase()blocks the request and returnsYou can't delete your own account. - When you demote yourself from admin, the last-admin guard protects you from locking the org out.
- A self-revoke session ("Sign me out" on your own session row) skips the cross-org guard since you are the target.
Groups
A person can also belong to any number of groups — Engineering, On-Call. Groups appear as chips on the user row, can be assigned from the row or in bulk, and the roster can be filtered by them. A group starts as a pure label, but an admin with Manage roles can bind roles to a group so its members inherit those permissions — so adding someone to a group can change what they may do. Adding a member to a group that grants elevated permissions is gated behind the same escalation ceiling as roles. A group is still not a role: see A group is not a role and Binding roles to a group.
Bulk actions
Select one or more user rows with the checkboxes; a bulk action bar appears at the bottom of the page with a > toggle that opens these actions. The header checkbox ticks the rows shown. When more people match than are shown, a line above the table offers Select all <N> that match, which selects every one of them (then All <N> people that match are selected., with Clear selection). A selection that includes people who aren't shown, after a search moved on, is said the same way (<N> selected, <M> not shown.), and unticking the header clears the whole selection, shown or not. Searching again drops an "all that match" selection. The Disable and Activate confirmations say how many of the selected people are already in that state.
- Activate — set
is_active=1for the selected users. - Disable — set
is_active=0; revokes all sessions immediately. - Change role — opens a single-select dialog of every role in your org; applies that role to every selected user (last-admin guard still applies per user).
- Add to group / Remove from group — in the More menu, shown only when your org has at least one group. Adds or removes the selected users to or from a group in one action. Adding to a group that grants elevated permissions is gated by the same escalation ceiling as roles: the action is refused unless you hold every permission that group would confer. Removing users from an admin-granting group is refused if it would strip the org's last effective admin. The confirmation says what a group with roles bound does: They will also get what the role bound to it gives. Their own roles are unaffected. when adding, They will lose what the role bound to it gives them. Their own roles are unaffected. when removing (the N roles bound to it give when several are bound). For a group with no roles bound, it says the action applies or removes an organizational label. One result follows: how many people were added or removed and how many were already in (or out of) the group; when the server refuses, the result carries its reason and says the people were not changed. Removing warns like a single removal when it leaves one of their agents without its model (<N> agents will pause).
- Export data — emails you a link to a ZIP of everything Strata keeps about each selected user, one folder per user (what it holds). At most 200 people, or everyone, through Select all that match with no search or filter when every one of them is active. The link works only for you, for 24 hours. Requires the
canManageCompliancepermission, and the org's member-chat-oversight setting must be on (the export discloses full message content). - Delete — hard-deletes the selected users with a confirmation dialog. Last-admin guard applies; self-delete is blocked.
The Users page bulk endpoint is rate-limited to 20 requests per 5 minutes per admin to prevent UUID enumeration. Hitting the cap returns Too many bulk requests. Please wait a few minutes before trying again. with a Retry-After: 300 header.
The Activate, Disable, Change role, and Delete actions run through the bulk endpoint, return {successCount, errorCount, errors}, and are audited as user.bulk_<action> with the per-user outcomes. Export data is handled by a separate endpoint that starts a background job (answering 202 with {ok, message, count, emailTo, jobId}) and is audited as admin.users_exported.
Deleting a user
Use Delete user permanently in the Manage modal, or the bulk Delete action, when you need to remove someone for good.
A delete hard-removes the user row plus:
- Sessions
- Extension permissions and OAuth tokens
- Database access rows
- User settings
- Conversations and messages (artifacts cascade)
- Personal database connections
- Personal files, skills, and deployed agents (agents can be transferred to another active member instead of deleted — see below)
- Inbox notices addressed to them alone (finished agent runs, system notices) and their saved announcement drafts. Announcements they published stay in everyone's Inbox and become organization-managed.
- The connectors they turned on for themselves, and their own connector sign-ins
Transferring a leaver's agents
A transfer moves each agent's definition (its instructions, schedule and settings) to the member you choose. Its run history does not move: those runs used the leaver's connections and can hold their mail or file content, so they are deleted with the rest of the leaver's data, and the new owner's agent starts a fresh history.
- Agents on the leaver's personal connections move unbound and paused, because those connections are deleted with the user. The new owner chooses a connection and turns the agent back on. Agents on organization connections keep theirs and keep running.
- What the agents send stops going to the leaver: their address is removed from each agent's To, Cc and Bcc. An agent left with no recipient sends to its new owner.
- Names stay unique per owner. An agent whose name the new owner already uses is renamed with (transferred) at the end.
- The new owner is told in their Inbox which agents they received, with an Open agents button that opens their Agents page.
- The agent limit per member applies. A member who would go over it cannot receive the agents; the request is refused with
409, andGET /api/admin/users/:userId/offboard-preview(requirescanManageUsers) lists the leaver's agents, which of them use a personal connection or email the leaver, and which members have room.
Activity-log entries are anonymized rather than removed — the user link and PII columns (the prompt text, response preview, prompt embedding, conversation link, IP) are nulled, while the metered columns the org needs (org_id, model_id, token counts, cost, source, timestamps) are kept, so org-wide usage/cost totals stay correct.
Audit log entries actioned by the deleted user are preserved (other admins still need to see "user X was disabled by deleted-user Y" history). Org-level connections and shared resources are untouched.
For GDPR or HR offboarding workflows that need a record of the user's data, run Export all data before deleting, and download the ZIP from the email before the link expires.
What can go wrong
| Error | What it means |
|---|---|
Admin access required | Your role does not grant canAccessAdmin. |
Permission required: canManageUsers | Your admin role can view the page but cannot make changes. |
Cannot remove the last admin — promote another user to admin first. | You tried to demote, disable, or delete the only remaining active admin. |
You can't delete your own account. | Self-delete is blocked. Have another admin do it. |
You can't disable your own account. | Self-disable is blocked. Have another admin do it. |
"<id>" is not an extension or connector in this organization. (under an extension) | That connector was removed after the admin page loaded, so its box is out of date. Reload the page and open the user again. |
Could not check. Try again. (under an extension) | Strata could not read your organization's connectors, or could not be reached, so the change was not saved. Try again. |
Not found (404) | The user UUID does not exist in your org. Usually a stale link to a deleted user. |
Too many bulk requests. Please wait a few minutes before trying again. | More than 20 bulk requests in 5 minutes from your account. |
Max 200 user_ids per export. Run in batches. | Split the export into multiple smaller batches. |
Action failed for this user (in a bulk result) | A real error happened for that specific user; the rest of the batch continued. Server logs have the real reason. |
See Audit log for the trail of every user change, Sessions for force-sign-out, and Roles and permissions for the role model.
Related
- Roles and permissions
- Groups — labels, and binding roles to a whole team
- Organization — the Model Catalog and org-wide allowed models
- Active sessions
- Per-user agent governance
- Atlassian extensions — the three layers that decide who may write to Jira and Confluence