# Account Console

Give every user a self-service home for their profile, credentials, sessions, and privacy — no support ticket required.

## What it is

The Account Console is the end-user self-service app that ships with each realm. Signed-in users manage their own identity end to end: profile details, credentials, active sessions, the apps they have consented to, linked external logins, and their personal data under GDPR.

It lives under the realm at:

```
/realms/{realm}/account
```

There are two account consoles (see [Architecture](../getting-started/architecture.md#the-account-consoles)):

- **The server-rendered account console** at `/realms/{realm}/account`, served by helix-iam-server on its own host. This is the account page users are sent to.
- **A single-page account console** (`/account.html`) in the admin console image, on the console's origin, which calls the account API below through the console's proxy. It only exists where the [admin console](../getting-started/install.md#the-admin-console-as-its-own-deployment) is deployed.

Both edit the profile attributes the realm makes [self-editable](../operations/realm-settings.md#account-console).

Behind the app is a self-service **API** under `/realms/{realm}/account/**`. Unlike the [admin API](../getting-started/api-authentication.md) (session + CSRF), it is authenticated by the **user's own OAuth2 bearer token** — each user only ever sees and edits their own data.

## What users can do

| Area | Endpoint (under `/realms/{realm}/account`) | What it covers |
| --- | --- | --- |
| Profile | `GET · PUT /profile` | Name, email, and other profile attributes. A change needs a recent sign-in (else `403 {"error":"step_up_required","reauth":…}`) and is refused (`403`, audited) during an administrator's impersonation |
| Editable fields | `GET /editable-attributes` | The profile attributes this realm lets users edit (reserved names never included); the SPA shows a field for each and saves only those |
| Edit details | `GET` · `POST /details` (browser form, not JSON) | The server-rendered page's **Edit details**: an input for each self-editable attribute, the others read-only; after a recent sign-in, never during an impersonation. A field for any other attribute or a reserved claim refuses the form and writes nothing (`403`). Rate limited, audited `ACCOUNT_DETAILS_UPDATE` |
| Password | `PUT /password` | Change the account password |
| Credentials | `GET /credentials` · `DELETE /credentials/{type}/{id}` | Passwords, OTP, passkeys, and enrolled devices |
| Sessions | `GET /sessions` · `DELETE /sessions/{ssoSessionId}` | View active sessions and sign out remote ones |
| Consents | `GET /consents` · `DELETE /consents/{clientId}` | Review and revoke app consents |
| Identities | `GET /identities` · `DELETE /identities/{alias}` | Linked external / social logins (wallet links are managed in their own section, below) |
| EU Digital Identity Wallet | `POST /wallet/link` · `GET`/`POST /wallet/unlink?alias=` (browser forms, not JSON) | Link or unlink a wallet — *Beta*; linking needs a recent sign-in, unlinking a step-up. See [EU Digital Identity Wallet](../federation/eudi-wallet.md#account-linking) |
| Digital credentials | `POST /credentials/offer` · `POST /credentials/offers/{offerId}/open` (browser forms, not JSON) | Add a credential the realm issues to the user's wallet, or open an offer an administrator made (**Waiting for you**): shows a QR code, an **Open wallet app** link and a transaction code — *Preview*; needs a recent sign-in, refused while impersonated. See [Credential issuance](../federation/credential-issuance.md#offers-always-to-the-user) |
| Verified by wallet | `POST /verified-attributes/delete` (browser form, not JSON) | Attributes a verify-only wallet connection [kept on the profile](../federation/wallet-step-up-and-profile.md#keeping-verified-attributes): values, source, verification time and expiry, with Delete (one or all) — *Preview*; not shown in an impersonation. Included in the GDPR export |
| GDPR | `GET /gdpr/export` · `GET /gdpr/consents` · `DELETE /gdpr/consents/{clientId}` | Export personal data and manage consent records |

## In the console

Review the self-service surface under **Integration → Account console**. End users reach it directly at `/realms/{realm}/account` after signing in.

1. Ensure users can sign in — the Account Console uses the realm's normal [authentication](../authentication/index.md) flow.
2. Point users at `/realms/{realm}/account`; the app inherits the realm's login theming.
3. To drive it programmatically, obtain a user bearer token via an [OIDC login](oidc-quickstart.md) and call the `/account/**` API directly.

## Over the API

Every call carries the signed-in user's bearer token — no cookie jar, no CSRF header. A request without a valid token is rejected with `401 Unauthorized`.

### Read the signed-in user's profile

```bash
curl -s "$HELIX_URL/realms/$REALM/account/profile" \
  -H "Authorization: Bearer $USER_TOKEN"
```
```json
{
  "realmId": "acme",
  "userId": "684db0eb-4afe-44f9-ad16-37a64f3496ea",
  "username": "jane",
  "email": "jane@example.com",
  "enabled": true,
  "locked": false,
  "mfaEnabled": false,
  "roles": ["user"],
  "attributes": {},
  "createdAt": 1783339573376
}
```

The profile endpoint returns the same `UserAdminDto` shape as the admin users API, but scoped to the caller's own account. Use `GET /account/sessions` to list active sessions, `GET /account/credentials` to enumerate factors, and the matching `DELETE` calls to sign out a device or revoke a credential.

!!! tip "Branded to match your realm"
    The Account Console inherits the realm's login theming, so it feels like part of your product, not a bolt-on.

## Highlights

### Self-service credentials

Users add and remove their own factors — set up a passkey, enrol an OTP authenticator, register a device, or change their password — without admin involvement. This pairs directly with the realm's [authentication](../authentication/index.md) configuration.

### Session control

Users see every active session and can sign out any device they no longer recognise — a simple, effective response to "I left myself logged in on a shared computer."

### Privacy and consent

Consents lists the apps a user has authorized, with one-click revoke. The GDPR area lets users export their own data, helping you meet data-subject requests with no manual effort.

## See also

- [Authentication overview](../authentication/index.md)
- [Passkeys](../authentication/passkeys.md)
- [Sessions admin](../manage/sessions.md)
- [Users](../manage/users.md)
- [EU Digital Identity Wallet](../federation/eudi-wallet.md) · [Credential issuance](../federation/credential-issuance.md)
- [API reference](api-reference.md)
