Skip to content

Identity and OIDC

Many self-hosted platforms handle identity with a user/password table. Flui delegates identity to an OIDC provider running on the control cluster, with what comes with it: sessions, federation, machine accounts, password reset and MFA. Flui keeps no user database of its own. The identity provider decides who can sign in, and Flui uses what it issues.

The whole picture

The identity provider runs on the control cluster, and it is where people sign in. The Flui API checks every request it receives: a sign-in token by its signature, a Flui key by its fingerprint, and then what the role and the scopes allow. The dashboard carries a sign-in token. The CLI gets a token from the identity provider once, and trades it with the Flui API for a key it keeps. An agent carries a key with scopes. Your applications can use the same sign-in: an internal app is reached only after signing in to Flui, and a catalog app can sign its own users in with a client Flui created.

Control cluster signs in Flui dashboard a sign-in token The CLI a token once, then a key An agent a scoped key, from the Flui API Identity provider accounts, sign-in, MFA, federation public keys Flui API checks every request 1 A sign-in token? signature checked with the provider's keys 2 A Flui key? its fingerprint, looked up in the database 3 Then role and scopes allow, or refuse Internal app reached only after signing in;its ingress asks the API Catalog app signs its users in with aclient Flui created
Who signs in where, and how the Flui API checks every request. The rest of this chapter takes each piece in turn.

The problem identity has to cover

The control plane of an installation needs to handle:

  • Sign-in for the platform: the dashboard, the CLI and the API.
  • Sign-in for the applications deployed on the platform.
  • Long-lived access for automation: CI pipelines, scripts, third-party integrations.
  • Federation with corporate identity providers, when you need it.
  • Account lifecycle work: password reset, MFA, an audit log of sign-in events.

Building any one of these is feasible. Building all of them and maintaining them for years is a large job, so Flui delegates the whole stack to an OIDC provider.

How it works

The identity provider is installed on the control cluster with the rest of the platform and is the single sign-on authority for everything the installation runs.

What you get out of the box:

  • One login for the dashboard, the CLI and the API.
  • Long-lived machine-to-machine keys for automation, scoped and revocable independently of any human user.
  • A base you can connect to a corporate identity provider. Federation is a configuration change on the identity provider, with no change to Flui’s code.

The interactive login is the standard flow: the CLI or dashboard sends you to the identity provider, you authenticate, and the result is a session the platform trusts.

The same sign-in can protect your applications. An application published on its gated address, <application>.internal.<zone>, is reached only after signing in to the installation, with nothing to configure in the application itself; see DNS integration.

Catalog apps can use the identity provider directly. When a composed catalog app is installed in OIDC auth mode, Flui creates an OIDC web client on the identity provider at install time, with no manual client registration. It records the client and project ids against the install so it can remove them when the app is uninstalled. The app gets single sign-on without the operator touching the identity provider.

How flui auth login works

The CLI needs an authenticated session for every operation that reaches the Flui API of an installation. Read-only local commands (managing contexts, inspecting configuration) do not.

To get that session, you run flui auth login. The CLI opens a browser to the installation’s identity provider, you authenticate there, and the CLI receives the result through a local callback. The CLI does not keep using the short-lived OIDC bearer the flow produced. It exchanges it at once for a long-lived machine-to-machine key that identifies the workstation, and saves that key in the active context. From then on the CLI authenticates with that key, and the interactive login runs only when you log in again.

The OIDC bearer is short-lived by design (minutes), and the CLI needs a session that lasts as long as you are working. A named M2M key gives that, and can be revoked on its own without affecting the human user it was issued for.

What a key is, once it is issued

A login lasts as long as somebody is at the keyboard. A key lasts longer. It goes into a configuration file on a workstation, into a build pipeline, or into the environment of an agent that runs unattended for months.

Two questions follow: what happens if somebody reads the key where it is stored, and how much can it do when it is presented?

Flui cannot give a key back to you

Flui stores a fingerprint of each key, not the key itself. A copy of the database therefore contains no live credential: the stored value opens nothing, and sign-in still works because Flui fingerprints whatever the caller presents and compares that.

You have to plan around one consequence. The key itself exists only in the response that creates it, and nothing on the installation can hand it back afterwards. The listing does not include it: flui auth api-keys shows the name, whether the key is active, revoked or expired, and its scopes (--output json adds when it was created and when it expires), but never the key.

So save the key when you mint it. If you lose it, revoke it with flui auth revoke-api-key <id> and mint another. Revoking stops that one key immediately and affects nothing else.

You rarely handle this yourself, because flui auth login mints a key for you and writes it straight into the active profile.

A key is worth its scopes, on every path

A key is issued as its person. Everything that person may do, the key can do, unless the key declares scopes, which can only take permissions away.

The rule holds on every path a key can take: the agent toolbox, the plain API with curl, and a live-updates connection. A read-only key is read-only everywhere.

A key with no scopes has no ceiling and loses nothing. Keys made by flui auth login work this way, and so do the platform’s own internal identities. Scopes only ever narrow; no scope on any key lets anybody do something they were not already allowed to do.

Who can reach what describes this rule in full, together with the other half of the question: what the key’s holder may reach.

Scopes come in groups

When people choose scopes one at a time, least privilege tends to fail: a dozen checkboxes get granted out of fatigue, and the person clicking cannot say afterwards what they agreed to.

So the unit you switch on is a group, defined by two choices:

  • The area the agent is trusted with: applications, observability, backups, migrations, mail, access, the infrastructure, or the platform itself.
  • The depth it may go to: look, change or destroy.
area × depth look change destroy Applications See applications Deploy and operate applications Delete applications Observability Read logs and health Backups See backups Run backups Migrations See migrations Run migrations Abort and tear down migrations Mail See mail delivery Access See who has access Grant and revoke access a group of its own, in no other Infrastructure See the infrastructure Operate the infrastructure Remove infrastructure never a whole cluster Platform Update the platform Every scoped key can also read how this installation is run.
The sixteen groups. Each is one area at one depth; the empty cells are combinations that do not exist.

There are sixteen groups, and each carries one sentence written for the person about to approve it. The sentence describes everything the group carries, beyond the name of its area: “Deploy and operate applications” also reads logs and metrics, because an agent that can deploy but cannot read why the deploy failed is of no use.

A group is granted or refused whole. It never comes back smaller than requested, so what somebody consented to and what the key carries match. A group naming something the issuer does not hold is refused, and the refusal names which group caused it, so you know what to fix.

Three rules apply whatever you pick:

  • “Grant and revoke access” is a group of its own and appears inside no other. It never comes along with “deploy my applications”.
  • No agent key can be given cluster deletion, whatever groups are combined.
  • Every scoped key also gets one thing nobody switches on: the ability to read the instructions for operating this installation, since an agent that cannot read the rules cannot follow them.

The terminal does not offer groups. flui auth generate-api-key takes --scope (repeatable) or --unscoped, and refuses if you name neither, so a key never gets its owner’s full permissions by accident. Groups exist in the API and the dashboard.

The trap: agent scopes on a person’s account

Because the identity provider is the authority, scopes can also come from it, as roles on an account rather than on a key Flui issued. That works, and it is a valid way to cap an agent.

There is one catch. If you put those roles on a person’s account, intending them for that person’s agent, they cap every token that account is ever issued, including the person’s browser session. The dashboard turns read-only for no visible reason.

This is correct behaviour: the credential is that account, and a declared ceiling applies wherever it is presented. The refusal says where the scopes came from, so the cause is on the screen.

Agent scopes belong on a machine account, not on a person. The identity provider handles machine accounts well, and Flui mints one for an agent on request: a machine user carrying agent scopes and nothing else. It never gets a role from the access ladder, because a scope narrows and a role would give the agent standing of its own. Its secret, like a key, is returned once.

Where this chapter goes from here

  • Who can reach what: the second question, and the one a refusal is usually about.
  • The control cluster: the identity provider as a platform component on the control cluster.
  • CLI: Authentication: the command-by-command reference for logging in and generating machine-to-machine keys.