# Accounts and identity provider

> First admin, invitations, lost access, the Users screen and plugging an OIDC provider into the console.

Guide - Since version 1.0.0 - Flexway v1.7.1 - https://flexway.io/en/docs/operations-console-accounts/

> Operations guide: configure, deploy and observe the gateway. What the feature does, product side: [product guide](https://flexway.io/en/docs/product-overview/); calling it: [developer guide](https://flexway.io/en/docs/developer-overview/).

The console starts without any identity provider: its local accounts live in a state `Secret` it writes
itself. An OIDC provider is optional and coexists with them.

## Steps

### First run

As the chart's NOTES say it:

1. Read the first admin's generated password from the state `Secret`, base64-decoded:

   ```bash
   kubectl get secret <release>-flexway-console-state -o jsonpath='{.data.initial-admin-password}' | base64 -d
   ```

2. Sign in as `admin`, choose a password, enrol a TOTP app and keep the ten recovery codes.
3. Users -> Invite: a single-use invitation link (72 h by default, 24 h or 7 days at your choice) to pass
   on - the console sends no e-mail.

### Get access back

1. Lost access:

   ```bash
   kubectl exec deploy/<release>-flexway-console -- flexway-console users reset admin
   ```

   (`sts/` instead of `deploy/` without a backend).
2. A locked account: `... users unlock <login>`.

### Add an identity provider

Entra ID, Okta, Google, Auth0, Keycloak, Authentik...

1. Declare the OIDC client in the console's values:

   ```yaml title="values.yaml"
   oidc:
     issuer: https://login.example.com/realms/staff
     clientId: flexway-console
     redirectUrl: https://console.example.com/auth/callback
     displayName: Keycloak               # the "Sign in with Keycloak" button
     accountUrl: https://login.example.com/realms/staff/account   # optional: the link of My account
     rolesClaim: realm_access.roles      # where the role is read
     tenantFrom: claim                   # or role: flexway-viewer:acme gives the tenant acme -
                                         # roles users cannot create themselves (no self-service groups)
     tenantClaim: tenant                 # where a viewer's tenant is read
   existingSecret: console-secrets       # key client-secret, mounted as a file
   auth:
     local:
       mode: breakglass                  # accounts (default), breakglass (local admins, 1 h) or off
   ```

2. Put the client's secret in the `Secret` named by `existingSecret` (key `client-secret`).
3. Deploy, then sign in through the provider's button.

### Manage the accounts

What the Users screen does, and what it keeps:

| Need | Where | What happens |
| --- | --- | --- |
| A shorter or longer link | Invite, or "Reset the password" on an account | 24 h, 72 h (default) or 7 days; single use, shown once, replaced by any reset |
| Require a second factor of a viewer | The account's panel -> "Require a second factor" | Their sessions without one close; they enrol an app at their next sign-in |
| A new phone | My account -> "Change app" | Password **and** a code of the current app (or a recovery code); the old app works until confirmed, which hands out ten new codes and ends the other sessions |
| A sign-in you do not recognise | My account -> "End every other session" | Every other session closes within 5 s; this one goes on |
| A locked account | The account's panel -> "Unlock now" | **Every** lock of the account lifts: each address's, the progressive delay, the second factor's |
| A provider's identity to take off the list | The identity's panel -> "Forget" | It comes back at its next sign-in; its rights stay those of its token. Removing the access is done at the provider |

## Verify

- A provider's account without a recognised role has no access and sees the roles its token carried.
- A signed-in viewer reads their tenant only; naming another gives an explicit refusal.
- The Users screen shows the OIDC identities seen next to the local accounts, read only.

## Good to know

> [!CAUTION]
> Whoever can `exec` into the console's pod is its administrator: keep `pods/exec` on
> this Deployment to its operators (every action of the command is audited). Do not expose the
> console publicly. Behind an ingress, declare its network in `trustedProxies`: each client is then
> counted under its own address - five failures lock the attacker's address, never the owner's, who
> waits a minute at most.

**What the console keeps** - a bounded view of the accounts' activity (500 events, 64 KiB, 90
days: masked network /24 or /48, browser family, never an address nor the `User-Agent`) and the
OIDC identities seen (a fingerprint of issuer and subject, never the subject; login and name;
forgotten 90 days after the last sign-in), in keys of their own of the state `Secret`, read by
admins only. The console's log stays the full audit trail. The gauge
`flexway_console_store_bytes{key}` shows each key's weight: their sum stays under 900 KiB, the
activity then the registry giving way before an account. Language and theme stay in the browser.

*Local accounts and an optional provider since `1.0.0`; Users and My account redesigned, the accounts'
activity and the OIDC identities seen in `1.2.0`.*
