Docs

Accounts

The admin users of the platform — invited by email, activated by the user, governed by exactly one role.

Overview

Invite-based admin users, each governed by exactly one role.

Organization accounts are the people who sign into the admin UI and manage roles, spaces, agents and the other org resources. Each account carries a globally unique email, optional first/last name (set by the user themselves when they register, and changeable later only by that user), exactly one role, and a status. What an account can see and do is entirely determined by its role — KeenAgents refuses to attach an account to a role that does not exist, so permissions always trace back to a real, current role. Passwords are stored irreversibly hashed and are never returned by any read.

Accounts are invite-based: an administrator creates one with just an email and a role, KeenAgents emails a confirmation link, and the invited user finishes registration themselves — setting their own name and password on the confirmation page. Every rule on this page is enforced by the platform itself; the admin UI mirrors the same rules early for a better experience, but they cannot be bypassed by calling the API directly.

Core Concepts

Account record
Reads return id, createdAt, updatedAt, lastLoginAt, email (unique), firstName/lastName (empty until the user confirms), role, confirmed and blocked. The credential is never included in any response, and the account list also omits blocked — only the single-account detail includes it.
Statuses
New — invited but not yet registered. Active — the user set their name and password via the emailed link. Blocked is a separate flag shown on the detail page. Status in lists and filters derives purely from whether the account is confirmed.
One role per account
The assigned role must always exist — an unknown role is refused with No such role!. Renaming a role follows through to every account holding it automatically. Deleting a role moves its accounts to the default role and force-logs-out any session still carrying the deleted role, so no session ever keeps permissions from a role that is gone.
Protected accounts
Every change is checked against a requester hierarchy: a requester with no role is refused; an owner requester may not act on the owner account; an admin requester may not act on owner or admin accounts (all answer Not allowed!). Your organization has exactly one owner, created at initial setup — even the owner cannot change the owner account's role, so the top of the hierarchy can never be accidentally demoted.
Emailed links
The confirmation and set-password pages require no login by design — the emailed link itself is the credential. Links are encrypted, expire after 24 hours — the initial owner activation link included — and are single-use: redeeming one invalidates it, and a newer invite or reset supersedes any older link. All failures answer the general 406 Action forbidden! so a failed attempt never reveals whether an email exists.
Reliability & audit
During platform maintenance an account operation may answer 503 — simply retry shortly. The automatic cleanup after a role deletion is never lost: it applies as soon as the platform is available again, even across a maintenance window. Every mutating action is recorded in the audit trail with both the requester's and the target account's identity.

The Account Lifecycle

From invite to Active — and what a password reset really does.

  1. An admin creates the account with an email and a role. KeenAgents checks the requester hierarchy, then stores the account unconfirmed — the emailed confirmation link is its only credential until the user registers.
  2. A confirmation email is dispatched with a link valid for 24 hours. The account shows New; its name fields stay empty until the user confirms.
  3. The user opens the link. On the Confirm Account page they enter the email the invitation was sent to (the link itself carries only a code), first name, last name, password and password confirmation — the two passwords must match. KeenAgents validates the link against the invited account, stores the chosen password irreversibly hashed, saves the names and marks the account confirmed. A wrong, expired or already-used link — or a different email than the one invited — fails with Confirmation failed. Check the email and use the latest mail link. (the API answers the general Action forbidden!).
  4. The account is now Active and can log in — the login page greets them with Account confirmed. Sign in with your new password. Names are set by the user at confirmation and cannot be changed from the Accounts pages — the person changes their own names from the avatar menu → Account (Profile card).
  5. A later admin-issued password reset invalidates the current password immediately — it stops working when the reset email is sent, not when the link is redeemed. The Set New Password page asks for the email the mail was sent to, the new password and its confirmation, and accepts a new password only for a confirmed account; afterwards the login page shows Password set. Sign in with your new password.
Never reset a New account's password
On an unconfirmed account the pending confirmation link is the account's only credential. Issuing a reset replaces that credential — killing the emailed confirmation link — and the reset link itself refuses unconfirmed accounts, so the account is stuck until a fresh invite. The admin UI hides the Reset button on New accounts for exactly this reason; if you drive the API directly, do not issue a reset for a New account. (The self-service Send Reset Mail on My Account is only reachable by a signed-in — hence confirmed — user, so it cannot hit this trap.)
Recovering a locked-out admin
There is no self-serve "forgot password" on the login screen. A locked-out admin asks another admin — or the owner — to press Reset Password for them. Between that reset and opening the emailed link to set a new password, neither password works, so open the email right away. Anyone who is still signed in — the owner included — can reset their own password without an admin: avatar menu → Account → Send Reset Mail (same rule: the current password stops working the moment the mail is sent). The owner account has no Reset Password button on the Accounts pages, and the initial activation screen closes for good once the organization has an account — an owner who is locked out and not signed in contacts support.

Your Own Account

What every signed-in admin — the owner included — can do for themselves.

Every signed-in admin has a My Account page under the avatar menu → Account. Its Profile card lets you change your own first and last name; the Details card shows your email, role and status read-only (only an administrator changes those, from Accounts); the Password card has a single Send Reset Mail button — a reset link goes to your email and your current password stops working the moment you press it, so open the mail straight away and set the new password there.

  • A name you change here becomes your display name across the admin; the header picks it up on the next session refresh.
  • This is the one self-serve path to a new owner password — the owner account cannot be reset from the Accounts pages.
  • An MCP account has no My Account page — it has no email or password to manage. See MCP Accounts.

Signing In & Your Session

How signing in works day to day, and why a password prompt sometimes reappears.

You sign in with your email and password. For security your session is time-limited — after a stretch of inactivity a password prompt appears in place, right where you were working. Re-enter your password and you continue exactly where you left off: nothing you had open or in progress is lost.

  • The prompt is a security safeguard, not a preference — there is no toggle to turn it off.
  • How often the prompt appears depends on how your KeenAgents environment is configured.
  • The prompt is a dialog titled Session Expired — "Your session timed out. Sign in again to continue right where you left off." Your email is pre-filled; enter your password. After three failed attempts it returns you to the login page.
  • Re-entering your password continues the current session in place — it is not a fresh login and does not send you back to the start of what you were doing.
You never lose your work to the prompt
The inactivity prompt re-authenticates you exactly where you were — it is a security re-check, not a reset. Fully signing out, or a session that has genuinely ended, is what returns you to the login screen instead.
You can also be signed out without acting
When an administrator changes your role, edits the permissions of the role you hold, deletes that role or deletes your account, your session ends at once and the login page shows Your access changed — please sign in again. Sign back in to continue with the new permissions.

Rules & Limits

  • Email — valid format, globally unique; a duplicate answers 403 This account is already created!. The admin UI caps length at 254 characters.
  • Role — required, must be an existing role; an unknown role answers No such role!. The protected targets are owner and admin; owner is never offered in any role select.
  • Registration — on the confirmation page the invited email, first name, last name, password and password confirmation are all required; the two passwords must match. The Set New Password page (after a reset) asks for the email the mail was sent to, the new password and its confirmation.
  • Paging — page defaults to 1 (0 is treated as 1); page size defaults to 20; the items parameter sets it. Past-the-end pages clamp to the real last page, and the reply always reports the page you actually landed on — sync your pager off that, not off the page you asked for.
  • Filters — at most 10 filter rows per request; operators are equal | not | greater | less | like | not like | in | not in; values must be non-empty strings and in/not in take a comma-separated list. Anything off-vocabulary answers 406 Invalid filter!.
  • Sorting — fields name | mail | status | role | id | created at, directions asc | desc; off-vocabulary answers 406 Invalid sort!. Default order is email descending; name sorts by first name then last name with not-yet-named (New) accounts always at the bottom, and ordering is fully deterministic so pages never shuffle between requests.
Filter typeBehavior
nameCase-insensitive; matches either first or last name for positive operators, and requires neither part to match for negative ones — accounts that have no name yet (New) never match a negative name filter.
mail / id / roleCase-insensitive string matches; role is matched by its slug.
statusOnly active and new; operators equal | not | in | not in.
created at / created fromDay-granular UTC windows over the creation date; operators equal | not | greater | less.

account list URL grammar

<type>[.<operator>]=<value>     bare key = equal              name=jame
                                multi-word operators dot-join  name.not.like=jame
                                dated types use underscores    created_at, created_from
sort=<field>[.<direction>]      direction defaults to asc      sort=created_at.desc
page=<n>                        pager position                 page=2

In the Admin UI

  • Account List — a paged table (20/page) with sortable columns Name, Email, Role, Status, Created At and a Visit link per row (headers cycle asc → desc → off). Page, filters and sort all live in the URL — refresh, share and back/forward restore the exact view — and a page flip keeps the previous rows visible under a dim + spinner overlay.
  • Filter panel — repeatable rows of type + operator + value: free text for name/mail/id, fixed Active/New choices for status, live role choices (label = title, matched by slug) and a date picker for the created-at types. Apply is enabled only on a real change and always lands on page 1; the current sort survives a filter change and vice versa.
  • Create Account — email input (254-char cap) plus a role select fed by the live roles list excluding owner. Success toasts, notes that the confirmation email was sent, and redirects to the new account's detail page.
  • Account Details — header badges for role, Active/New status (green/purple), Blocked (red) and protection state: protected — read only for the owner, protected — role locked for admin accounts (role change locked, password reset and delete remain available). Email and names are read-only; the role select has a dirty-gated Save; Reset Password appears only on confirmed, non-owner accounts; delete is a two-step control hidden entirely for the owner.
  • Owner visibility — a non-owner requester never sees the owner account in the list; the row is excluded from both the results and the total count.

Good to Know

  • Changing an account's role signs that person out on the spot — the login page tells them Your access changed — please sign in again. and their next sign-in carries the new permissions. Editing a role's permissions does the same for everyone signed in under that role, and deleting a role signs out everyone who held it. An MCP account is never signed out: it picks a role change up at its next authentication.
  • Deleting an account immediately terminates any live session that account had — the delete and the logout are one action from your point of view.
  • The Accounts pages — and My Account — are for people only. An MCP account (an AI agent's login) is refused here whatever its role, with MCP accounts may not access this resource; it can never create, edit, reset or delete a human account. See MCP Accounts.
  • A mail client that cuts a link short lands on This link is incomplete — "The mail link was cut short by the mail client. Open the mail again and use the full link (or copy the entire address)."
  • The blocked flag renders as a red badge on the detail page, but no admin action currently sets or clears it.
  • In a hand-edited list URL, unknown filter keys and operators are silently ignored (a typo'd key simply does nothing), and only the first filter per type is honored.
  • Emailed links are invalidated by supersession: issuing a new reset or a fresh invite is what actually kills an older link — the newest link is always the only one that works.
Debugging a failed confirmation or delete
Errors on sensitive and public paths are deliberately general — Action forbidden!, Not allowed!, bare 406s — revealing the failure class, never details such as whether an email exists; this keeps probing attackers blind. Check the platform's audit log instead of expecting the API message to explain.

Previous

Platform Overview

Next

MCP Accounts

Keen Agents 2026

Documentation

Release 15