Skip to content

iPXE boot menu cannot authenticate an OIDC account: add the device authorization grant #1189

Description

@mastacontrola

The gap

An install that has moved every account to an identity provider still has to keep a second, separate credential just for the iPXE boot menu. That is the opposite of what adopting SSO is for, and it is the shape most likely to hurt the installs that adopt it hardest — a school on Google Workspace does not want a local FOG password per admin purely so FOG_ADVANCED_MENU_LOGIN works.

Why it does not work today, and why it is structural

service/ipxe/advanced.php calls FOGCore::authenticateOnly($user, $pass)User::authenticate()User::passwordValidate(). That refuses any account with uAuthSource set unless a listener on USER_LOGGING_IN vouched for it.

What the menu can collect What the mechanism needs
LDAP a username and a password exactly that — the plugin binds to the directory on USER_LOGGING_IN and sets $authenticated = true
OIDC a username and a password a browser, to follow a redirect to the provider and return with an authorization code

So LDAP works at the boot menu and OIDC cannot. The OIDC plugin registers no USER_LOGGING_IN listener, and it should not: iPXE is a boot ROM drawing a text menu, there is nowhere to run a redirect.

This is worth stating plainly in the tracker because from the outside it reads as "OIDC login is broken at the boot menu" rather than "no browser, no authorization code".

The three options, with evidence

1. Resource Owner Password Credentials (grant_type=password) — FOG collects the credentials on its own prompt and forwards them to the provider. This is the intuitive answer and it is the wrong one:

  • Verified against Google's live discovery document (https://accounts.google.com/.well-known/openid-configuration, fetched 2026-08-18): grant_types_supported is ["authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:device_code", "urn:ietf:params:oauth:grant-type:jwt-bearer"]. No password. So it does not solve the case that motivated this.
  • It is removed in OAuth 2.1 and advised against in the OAuth Security BCP.
  • It defeats MFA, and it puts the user's provider password through FOG — which is the specific thing OIDC exists to prevent.

Keycloak does still offer it (verified locally: password is in its grant_types_supported), so it would appear to work in a lab and then fail at the customer.

2. Device authorization grant, RFC 8628 — the menu displays a short code and a URL, the admin approves it on a phone or laptop, iPXE polls the token endpoint until it is granted. This is how TVs and consoles do SSO, and it is the mechanism designed for exactly this input-constrained case.

Verified both providers advertise it, 2026-08-18:

Provider device_authorization_endpoint
Google https://oauth2.googleapis.com/device/code
Keycloak 26 .../realms/<realm>/protocol/openid-connect/auth/device

3. Keep a local or LDAP account for the boot menu — what installs do today. It works, and it is the honest answer until (2) exists.

Recommendation

Implement (2), gated on discovery the same way single logout already is: the OIDC plugin reads end_session_endpoint from the provider's metadata and does nothing when it is absent. device_authorization_endpoint gets the same treatment — offer the flow when the provider advertises it, fall through to the existing password prompt when it does not, so a provider without device support is no worse off than today.

Design questions this needs answering before it is codeable

  • The iPXE side. advanced.php returns an iPXE script. Polling means emitting a script that displays the user code, sleeps, and re-chains to a status endpoint until the grant lands or expires_in passes. Needs a real design, plus a way out when the user walks away.
  • Where the poll lives. FOG has to hold the device_code between chains — iPXE carries no session (see Make the iPXE advanced menu actually check the login it asks for #1111/Make the iPXE advanced menu actually check the login it asks for #1112), so the state has to be keyed on something the boot ROM can present back, and that key must not itself be a credential.
  • Which menu. FOG_ADVANCED_MENU_LOGIN is the obvious first target; whether the same applies anywhere else in the boot path should be decided rather than assumed.
  • Timeouts. A boot menu blocking on a phone approval is a new failure mode for someone standing at a machine that will not boot.

Marked ready-for-human: the iPXE-side interaction design and the timeout behaviour are product decisions, not mechanical work.

Not a blocker for anything shipped

Web UI OIDC login, single logout and forced redirect all work; this is only about the boot menu.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementready-for-humanNeeds hardware/env repro, infra access, or a product/design decision

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions