External users
An external user is a person of a host application whose identity a trusted issuer vouched for. They never sign in to the Console dashboard and never hold API tokens: they reach Console through your application, either by acting for a user on the client API, or through an embedded portal. This page explains what an external account is, how it gets its access (through delegated groups), and how to manage the accounts and groups an application brings in.
Requires a Console release with the IAM engine
External accounts, delegated groups and the External badge in the IAM center exist in releases that include the IAM engine.
What an external account is
Console knows three kinds of accounts:
| Kind | Signs in to the dashboard | Holds API tokens | Typical use |
|---|---|---|---|
| Person | Yes (password, LDAP or SSO) | Yes | A teammate |
| Service account (Programmatic User) | No | Yes | A bot, CI job or integration that owns API tokens |
| External | No | No | A person of a host application, created when an application's signed statement names someone Console has not met |
An external account:
- cannot sign in to the dashboard and cannot own API tokens;
- always has the User role and has no personal permissions;
- is never added to a project itself: what it can open comes from the delegated groups it is in;
- is left out of member lists and pickers;
- is found only by its identity (issuer and subject), never by email address;
- has a profile that follows the statement (name and email), unlike a member's, which is never rewritten;
- counts toward the licence user limit (
seat_limit), like any account.
The workspace owner and administrators can never become external accounts: an application's statement cannot sign in as an owner, nor as an administrator by role or by a group that grants the role.
Where external accounts come from
An external account is created the first time a verified statement names a person Console has no account for, when the mapping says so:
- API tokens: set When nobody matches to An external account in the token's Acting for users setup.
- Portals: the portal's embed mapping offers the same choice (create an external account).
The choices for a person nobody matches are:
| Choice | What happens |
|---|---|
| Nobody | The person must already have an account; otherwise the call is refused (unknown_principal). This is the safe default. |
| An external account | An account of kind external is created, managed by the application. |
| A person managed by the identity provider | An ordinary person account without a password, created from a verified email address nobody else uses. It can sign in only through your identity provider. |
See and manage them in the IAM center
In Settings → IAM center → Principals → People:
- People of host applications carry an External badge. A counter next to the list (N external) tells you how many exist; select it to list them. They are otherwise left out of the people list, so they do not clutter member pickers.
- Open one to see its Access details: an external account follows the issuer that vouches for it, has no personal permissions, joins no project and holds no API tokens, plus the Activity section: usage by service (with the tokens it came through) and the latest audit rows it is the subject of.
- Over the API:
GET /api/iam/principals?type=user&kind=externallists them; the response carriesexternalTotal.
Give external users access: delegated groups
An external person has no memberships of their own. What they can open comes from the delegated groups they are in. An external person who is in no group that was given the project the token is bound to is refused with 403 project_not_accessible.
Groups that follow the statement
With a group map in the token's Acting for users setup (identity provider group => console group), the person's memberships follow the statement's groups claim, but only in groups created for that issuer:
- The groups are created the first time somebody arrives with the claim, named as you mapped them. They are marked as managed by a directory (their members cannot be edited by hand:
409 group_directory_managed), and they carry no grants. Their description reads Members follow the group claim of followed by the issuer. - A local group, or a group of an LDAP or SSO directory, is never filled or emptied from a statement, whatever its name. An issuer cannot add anybody to a group an administrator made.
- A group that has been given a workspace role or service permissions is not filled either: an application must not hand out what a group grants. Such groups are skipped.
- The claim is the truth for the groups of this issuer: leaving the claim (or removing the mapping) removes the membership.
- Every change is written to the audit trail with the issuer as the actor (
delegated:<issuer>), as the samegroup.member.addandgroup.member.removerows the screens write. Creating the account, linking it and creating a group are audited asuser.jit.create,user.identity.linkandgroup.jit.create. - Two portals (or an API token) that trust the same issuer fill the same groups: the groups belong to the issuer, not to one token or portal.
The map allows at most 100 entries; an identity provider group name is at most 200 characters and a console group name at most 120 characters without surrounding spaces.
Steps: give an application's users access
Example: your support product sends groups: ["support"] for its agents, and you want them to use the agents of one Console project.
- Set up acting for users on the application's token (steps), with When nobody matches set to An external account and a group map entry
support => Support (app). - Bind the token to the project the people should work in, and give the token a scope so the people are capped by it.
- Send a first call for a person who carries the
supportgroup. Console creates the account and, because of the group map, the group Support (app). That first call is refused withproject_not_accessible(the group has no project yet): the account and group stay. - Open Settings → Projects, the project's Members, and assign the group Support (app) to it with the project role you want.
- Optionally attach policies and limits to the group like to any other group (IAM center → Policies, IAM center → Limits). Do not give the group a workspace role or service permissions; it would then stop being filled from the statement.
- The next call for the person goes through. Check IAM center → Principals for the account (badge External) and Access check for what they can do.
The project check is made on every call, so taking a group's project away applies at once on this node (other nodes within about 15 seconds).
Rules and limits at a glance
| Role | Always User |
| Dashboard sign-in | Never |
| API tokens | Never |
| Project membership | Only through delegated groups |
| Group changes from a statement | Only in groups created for that issuer, and only groups that carry no grants |
| Match by email | Never; an external account is found only by identity |
| Licence user limit | Every created account counts; over the limit the call is refused with seat_limit |
| Owner and administrators | Never acted for through a portal; through a token only when Allow administrators is on, and the owner never |
| Disabled account | Refused (disabled) before anything is written for it |
| Cache | The account an identity resolved to is remembered, but the account is read again on every call |
Security notes
- A statement is only as trustworthy as its issuer. Console verifies the signature, issuer, audience and lifetime, and pins the algorithm. It never trusts a claimed address that was not verified, and
ctxis signed but untrusted data. - Do not let an application hand out grants. That is why groups that carry a role or service permissions are never filled from a statement. Attach policies, limits and project access to the groups instead.
- Prefer a narrow token. The token's scope and project cap every person it acts for, including external ones.
- Owners and administrators are out of reach. The workspace owner can never be acted for. For an administrator the setup has to say so explicitly (and a portal never does).
- Audit. Account creation, identity links, group creation and every membership change made from a statement are in the audit log with the issuer as the actor.
Troubleshooting
The person is refused with project_not_accessible. They are in no delegated group that has the token's project. Check that the statement carries the group, that the group map names it, and that the group is assigned to the project (Settings → Projects → Members).
The group exists but nobody is added to it. The group may have been given a workspace role or service permissions (it is then skipped), or the statement does not carry the claim. Remove the grants from the group, or use another group for the grants.
A new person is refused with seat_limit. The licence user limit counts every account, external ones included. Free a seat or upgrade the licence.
I cannot edit the members of a delegated group. By design (group_directory_managed): the membership follows the statement.
I do not see external people in the member list. They are left out of member lists and pickers. Use the External counter in IAM center → Principals → People, or the API with kind=external.
An external person's name or email changed. An external account's profile follows the statement. A member's never does.
What's new
- Accounts of kind external, created from a verified statement of a trusted issuer.
- Delegated groups that follow the statement's
groupsclaim, audited with the issuer as the actor. - The External badge, counter and API filter in the IAM center.

