---
title: "Console access"
description: "Let directory users use the EZGH console as a bot, with exactly that bot's permissions, signed in through your directory, and get temporary API keys that end with their SSO session."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ezghcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Console access

Console access lets the people in your directory use the EZGH console without becoming members of
your organization. A directory user signs in at your portal, opens the **EZGH Console** tile, and
uses the console **as a bot** that trusts them, with exactly that bot's permissions. It works like
AWS's `AssumeRoleWithSAML`, with a bot in place of the role.

They stay directory users. They're never members, never count as members, and have no member
account, so there's nothing to link and no conflict with an email address that's also a member's
or belongs to another organization.

## Who decides what

| Decision | Made by |
| --- | --- |
| Who may open the console | The directory: the console application's [assignments](/sso/assignments), and whether the user is active and signed in at the portal |
| Which bots a person may use | IAM: each bot's **trust**, a list of directory groups and users |
| What they may do in the console | IAM: the bot's policies, attached to it directly and through its IAM groups |

A person needs both: an assignment (directly or through a group) to open the console, and at
least one bot that trusts them (directly or through a group). A **mapping** on the Console access
page sets both at once. Group membership is read from the directory on every request, so adding
someone to a mapped group gives them access straight away.

Everyone using the same bot has the same access, and shares what belongs to the bot, such as its
API keys. [Trails](#auditing) records which person acted.

## Set up console access

Enabling console access needs `sso.applications.create`. Adding mappings needs
`bots.updateTrust` on each bot and `sso.assignments.update`; seeing them needs `bots.list` and
`sso.assignments.list`. The bots must already exist: create one for each set of permissions,
such as `ops-admin` with `AdministratorAccess` and `ops-readonly` with `ReadOnlyAccess` (see
[Bots](/iam/bots)).

### Console

1. Open **EZGH SSO** > **Console access** and select **Enable console access**.
2. Enter the **Tile name** (default **EZGH Console**) and the **Session length** (15 minutes to
12 hours; default 12 hours). Review, then select **Enable**.
3. Under **Group mappings**, select **Add mapping**.
4. Choose a directory group or user, then the **Bots** it may sign in as. Review, then select
**Save**.

Saving adds the group or user to each bot's trust, and assigns it to the console application so
its members see the tile.
### API

Create the console application, an `ezgh` application with the product `console`. See
[CreateApplication](/sso-api/CreateApplication/).

```sh
curl https://sso.ezghcloud.com/v1/organizations/$ORG_ID/sso/applications \
  -H "Authorization: Bearer $EZGH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "EZGH Console", "kind": "ezgh", "ezgh": {"product": "console", "consoleSessionSeconds": 43200}}'
```

Add the directory group to the bot's trust, by the group's resource name. See
[AddBotTrust](/orgs-api/botTrust/AddBotTrust/).

```sh
curl -X POST "https://orgs.ezghcloud.com/v1/organizations/$ORG_ID/bots/$BOT_ID/trust/ezgh:us-west-1:org_k3f9a0x2m7qp:dir_4k2m9x0a7qpe:dgp_7d3e9a1b2c4f" \
  -H "Authorization: Bearer $EZGH_API_KEY"
```

Then assign the group to the console application with
[AddAssignments](/sso-api/AddAssignments/), or with the CLI:

```sh
ezgh sso assignments add "EZGH Console" --group sre
```

### The console application

The console application is an `ezgh` application. It appears under **EZGH SSO** >
**Applications**, and its page links to Console access.

| `ezgh` field | Description | Default |
| --- | --- | --- |
| `product` | `console`. A directory has at most one console application: a second is `409 console_application_exists`. Can't change. | Required |
| `consoleSessionSeconds` | How long a console session lasts: 900 to 43,200 (15 minutes to 12 hours). | 43,200 |
| `launchUrl` | Always `https://<alias>.sso.ezgh.app/console/start`, where the tile goes. Read-only: send it as `null` or leave it out. | |
| `resourceTokenLifetimeSeconds` | Not used: the console application issues no resource tokens. Always 3,600. | |

A new session length applies from the next sign-in. Like other EZGH applications, the console
application can't have [outbound provisioning](/sso/provisioning).

## Manage mappings

The **Group mappings** table on the Console access page lists each directory group or user with
the bots it may sign in as, and whether it's assigned to the console application:

- **Sees the tile but can't sign in**: assigned, but no bot trusts it.
- **Can't open the console**: a group that bots trust, but that isn't assigned.
- **Not directly**: a user that bots trust, who isn't assigned on their own. They can open the
  console if one of their groups is assigned.

Select **Edit** to change a row's bots, or **Remove** to remove them all. Either can also remove
the group or user from the console application, so they stop seeing the tile. Their console
sessions as a removed bot end on their next request, unless they're mapped to it another way.

### A bot's trust

A bot's trust is part of the bot, in IAM. Open **IAM** > **Bots**, select the bot, and open the
**Trust** tab: it lists the EZGH SSO groups and users who may sign in to the console as the bot.
Select **Add** to add some, or **Remove** on a row. Seeing the trust needs `bots.get`; changing it
needs `bots.updateTrust` on the bot.

Trust alone doesn't assign anyone. A group you add on the Trust tab must also be assigned to the
console application to open the console; Console access does both.

| Operation | Does |
| --- | --- |
| [GetBotTrust](/orgs-api/botTrust/GetBotTrust/) | Returns the bot's trust, with the bot's `ETag`. |
| [UpdateBotTrust](/orgs-api/botTrust/UpdateBotTrust/) (`PUT`) | Replaces the whole trust with `{ "trust": [{ "principalType", "resourceName" }, …] }`. `principalType` is `ssoGroup` or `ssoUser`. |
| [AddBotTrust](/orgs-api/botTrust/AddBotTrust/) (`POST`) | Adds one group or user, by resource name. |
| [RemoveBotTrust](/orgs-api/botTrust/RemoveBotTrust/) (`DELETE`) | Removes one group or user, by resource name. |
| [ListBotTrust](/orgs-api/botTrust/ListBotTrust/) | Lists every trust entry in the organization, for the bots you may list; `principal=<resource name>` filters to one group or user. |

- Writes take `If-Match` with the bot's `ETag`. If the bot changed since you read it, the write is
  `412 precondition_failed`.
- Each group or user must be in your organization's directory. A bot trusts at most 100.
- Deleting a directory user or group removes it from every bot's trust.
- `IAMFullAccess` includes `bots.updateTrust`. Whoever has it can let people act as the bot, so
  treat it like `bots.createApiKey`.

## Sign in

Directory users sign in to the console in either of two ways:

- At the portal, `https://<alias>.sso.ezgh.app`, select the **EZGH Console** tile.
- At [login.ezghcloud.com](https://login.ezghcloud.com/sign-in), select **Sign in with EZGH SSO**,
  enter the **Directory alias**, and select **Continue**. They sign in at the portal if they
  aren't already, and continue to the console. When they started from an `ezgh` CLI login, they
  return to its approval page instead (see [The CLI](#the-cli)).

With one bot that trusts them, they're signed in to the console as it. With several, they choose
one on **Choose a bot** within 5 minutes. The account menu shows the bot and the person, such as
**ops-admin · ada@acme.com via EZGH SSO**, with **Switch bot** (back through the portal to the
bot picker) and **Sign out**.

Signing in to the console as a bot replaces a member's console session in the same browser.

| What they see | Why |
| --- | --- |
| No bots are mapped to you yet. | They're assigned, but no bot trusts them or their groups. Recorded as a failed `AssumeBot` (`none_mapped`). |
| You aren't assigned to the EZGH Console in your organization's EZGH SSO, or your SSO session has ended. | They aren't assigned to the console application, directly or through a group, or their portal session ended. |
| That bot no longer trusts you. | The bot they chose stopped trusting them. Recorded as a failed `AssumeBot` (`not_trusted`). |
| This sign-in has expired. | They took more than 5 minutes to choose a bot. |
| Too many attempts. | More than 10 console sign-ins a minute from one IP address. |

## Sessions

A console session lasts the console application's session length, and never past the end of the
portal session it came from (the directory's [session length](/sso/directory#sign-in-policy)). It
ends earlier, on the next request, when:

- the person signs out of the portal, or their portal session reaches its idle timeout;
- you sign them out ([Sign out everywhere](/sso/users#sessions)), suspend them or delete them;
- they're no longer assigned to the console application, or you disable console access;
- the bot is deleted, or no longer trusts them or any of their groups.

Using the console counts as activity on the portal session, so the idle timeout doesn't end it
while they work. **Sign out** in the console ends only the console session: the person's
[temporary API keys](#temporary-api-keys) keep working until they expire or the portal session
ends.

## Permissions

A console session has exactly the bot's access: the policies attached to the bot and to its IAM
groups, checked on every request like any bot's. Policies attached to directory users and groups
don't apply to it. A bot is never the root user.

What belongs to a member's own account isn't available:

- Profile and password.
- Your own API keys: the console shows the bot's API keys instead.
- Creating, leaving or deleting an organization, making another user root, and invitations
  received. Those are `403 forbidden`.
- Other organizations: the session is in the directory's organization only.

The console session is for the console in a browser. For scripts and the CLI, get a
[temporary API key](#temporary-api-keys), which ends with the person's SSO session, or use a
lasting [API key](#api-keys) for the bot.

## Temporary API keys

A person signed in to the console as a bot can get a **temporary API key**: an API key that acts as
the bot, with exactly its access, for a set time and only while their SSO session lasts. It's
like the short-term credentials AWS IAM Identity Center gives for a permission set. Getting one
needs no IAM permission: the key can do nothing the console session can't already do.

1. In the console, open the account menu and select **Get temporary API key**.
2. Choose how long it **Lasts**: **1 hour**, **4 hours** or **12 hours**. Lifetimes past the end
   of the console session can't be chosen; when less than 12 hours are left, **Until your session
   ends** is also offered.
3. Optionally, enter a **Name**. The default is `Temporary key for <username>`.
4. Select **Get key**, and copy the key. It won't be shown again.

Use it like any API key, as a bearer token or in `EZGH_API_KEY` (see [API keys](/iam/api-keys#use-an-api-key)).
A temporary key lasts 15 minutes to 12 hours, and never past the end of the console session that
made it. It stops working earlier, on its next request, when:

- the person's SSO session ends: they sign out of the portal, it reaches its idle timeout or the
  directory's session length, or you sign them out ([Sign out everywhere](/sso/users#sessions));
- you suspend or delete the person, or they're no longer assigned to the console application;
- the bot no longer trusts them or any of their groups, or the bot is deleted;
- the key is revoked.

Signing out of the console doesn't end it. A key in use counts as activity on the portal session,
so the idle timeout doesn't end it while the key is used; the session length still does.

Admins see temporary keys on the bot's **API keys** tab with a badge naming the person, such as
**Temporary · ada@acme.com**, and revoke them like any key (`apiKeys.delete`). See
[Temporary API keys](/iam/api-keys#temporary-api-keys).

| What they see | Why |
| --- | --- |
| Your session ends in less than 15 minutes. | Less than 15 minutes are left in the console session. Sign in again through EZGH SSO. |
| This EZGH SSO session already has 20 temporary keys that haven't expired. | One SSO session has at most 20 live temporary keys. Wait for one to expire, or have one revoked. Recorded as a failed `CreateTemporaryApiKey` (`limit_exceeded`). |

### The CLI

`ezgh auth login` gets a temporary key when the browser that approves it is signed in to the
console through EZGH SSO. The approval page names the bot, the person and when the key ends:
"Sign in to **EZGH CLI** (made by EZGH Cloud) as **ops-admin** (ada@acme.com via EZGH SSO) until
20:00." The key lasts until the console session ends and can't be refreshed: when it expires, run
`ezgh auth login` again. `ezgh auth logout` revokes it. See
[Log in through EZGH SSO](/cli/authentication#log-in-through-ezgh-sso).

If the browser isn't signed in yet, select **Sign in with EZGH SSO** on the sign-in page and
enter the **Directory alias**. After signing in at the portal (and choosing a bot, if several
trust them), the person returns to the approval page instead of the console.

## API keys

A console session can create lasting API keys only as the bot, and only when the bot's policies allow it:

- Every key it creates is a key for a bot, checked as `bots.createApiKey` on that bot, never as
  `apiKeys.create`. Being the bot grants nothing: to create a key for itself, the bot needs
  `bots.createApiKey` on its own resource name. Revoking a key needs `apiKeys.delete`.
- The key belongs to the bot. It acts as the bot and keeps working after the person leaves the
  directory, like any bot key. Its creator is the bot, and the `CreateApiKey` event in Trails
  names the person in `sourceIdentity`. For a key that ends with the person's access, use a
  [temporary API key](#temporary-api-keys).

To stop bots creating keys for themselves, deny `bots.createApiKey` on `${ezgh:principal}`, which
means "the caller itself". One policy attached to an IAM group covers every bot in it. This one
lets each bot in the group create keys for other bots, but never for itself:

```json
{
  "statements": [
    { "effect": "allow", "actions": ["bots.createApiKey"], "resources": ["*"] },
    { "effect": "deny", "actions": ["bots.createApiKey"], "resources": ["${ezgh:principal}"] }
  ]
}
```

See [Resources](/iam/policies#resources) for how `${ezgh:principal}` is matched.

## Auditing

Everything done in a console session is recorded in [Trails](/trails) as the bot, with
`credential` `federation` and the person in `sourceIdentity`:

```json
"userIdentity": {
  "type": "Bot",
  "principalId": "0199a3c4-0d1e-7f20-8a3b-4c5d6e7f8091",
  "userName": "ops-admin",
  "isRoot": false,
  "accessKeyId": null,
  "sessionContext": {
    "credential": "federation",
    "sessionIssuedAt": "2026-10-02T08:00:00.000Z",
    "ssoProviderId": null,
    "mfaAuthenticated": true,
    "clientId": null,
    "directoryId": "0199a3f0-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
    "sourceIdentity": { "type": "SsoUser", "principalId": "0199a3f1-1a2b-7c3d-8e4f-5a6b7c8d9e0f", "userName": "ada@acme.com" }
  },
  "invokedBy": null
}
```

`mfaAuthenticated` says whether the person's portal sign-in used MFA. The console's event history
shows these events as the bot, on behalf of the person.

Requests made with a [temporary API key](#temporary-api-keys) are recorded the same way, except
that `credential` is `apiKey` and `accessKeyId` is the key's ID. The console's event history shows
their credential as **Temporary API key**.

| Event | Records |
| --- | --- |
| `AssumeBot` (`signin.ezghcloud.com`) | A console sign-in as a bot. `userIdentity.type` is `SsoUser` (the person), `resources` name the bot and the directory, and `responseElements` is `{ "botId" }`. A refusal has `errorCode` `none_mapped` (no bot trusts them) or `not_trusted` (the chosen bot doesn't). |
| `CreateTemporaryApiKey` (`signin.ezghcloud.com`) | A temporary API key made in the console or by an `ezgh auth login`. `userIdentity` is the console session's (the bot, with the person in `sourceIdentity`); `requestParameters` is `{ "expiresInSeconds", "clientId" }`, where `clientId` is `ezgh-cli` for the CLI and `null` for the console; `responseElements` is `{ "apiKeyId", "prefix", "expiresAt" }`; `resources` name the bot and the directory. A refusal has `errorCode` `not_trusted` (the bot no longer trusts them) or `limit_exceeded`. |
| `AuthorizeApplication` (`sso.ezghcloud.com`) | The portal sending the person to the console, or its refusal (`not_assigned`). See [Activity in Trails](/sso/trails). |
| `GetBotTrust`, `UpdateBotTrust`, `AddBotTrust`, `RemoveBotTrust`, `ListBotTrust` (`iam.ezghcloud.com`) | Reading and changing bots' trust. |

To find what one person did, look up events with `sourcePrincipalId` set to the directory user's
ID (see [Lookup parameters](/trails/lookup#lookup-parameters)), which covers their console sessions
and their temporary API keys; their `AssumeBot` events match `principalId`. In [Trails Query](/trails/query):

```sql
SELECT event_time, event_name, toString(user_identity.userName) AS bot
FROM trails
WHERE toString(user_identity.sessionContext.sourceIdentity.principalId) = '0199a3f1-1a2b-7c3d-8e4f-5a6b7c8d9e0f'
ORDER BY event_time DESC
LIMIT 100
```

SAML assertions, session tokens, authorization codes and API keys are never recorded.

## Disable console access

On the Console access page, select **Disable** (`sso.applications.delete`), or delete the console
application with [DeleteApplication](/sso-api/DeleteApplication/). The tile leaves the
portal, nobody can sign in to the console through EZGH SSO, and everyone signed in that way is
signed out. The console application and its assignments are deleted. Bots keep their trust:
remove the mappings first to clear it.

## Limits

| Limit | Value |
| --- | --- |
| Console applications per directory | 1 |
| Groups and users a bot trusts | 100 |
| Console session length | 15 minutes to 12 hours (default 12 hours), and never past the portal session's end |
| Time to choose a bot | 5 minutes |
| Console sign-ins | 10 a minute per IP address |
| Temporary API key lifetime | 15 minutes to 12 hours, and never past the console session's end |
| Live temporary API keys per SSO session | 20 |
| Organizations per session | 1, the directory's |

Source: https://docs.ezghcloud.com/sso/console-access/index.mdx
