Feature Specification: Accounts and ownership

Created: 2026-09-23

Status: Implemented

Input: Reconstructed from the code of panel/ at 0bf4ecd36, pull requests #966, #967, #1129, #1248 and #1645, issues #241 and #313, api/specification.md, and the design notes of the maintainers.

User Scenarios & Testing (mandatory)

User Story 1 - Log in (Priority: P1)

An operator logs in to the panel with single sign-on (OpenID Connect) through the identity provider of the hosting provider. Without an identity provider, the operator logs in with a local user name and password. With single sign-on, the panel finds the account by the email address, or makes a new account, and takes the user name from the identity provider.

Why this priority: the account is the key of all ownership in the panel. Development and small setups have no identity provider.

Independent Test: unit tests of the login page with and without an identity provider, and of the account match.

Acceptance Scenarios:

  1. Given a complete identity provider configuration, When an operator opens the login page, Then the page offers single sign-on and keeps the page that the operator wanted to open.
  2. Given an incomplete identity provider configuration, When an operator opens the login page, Then the page offers only the password login.
  3. Given a new identity with the email address of an existing account, When the operator logs in, Then the panel uses the existing account.
  4. Given a logged-in operator, When the operator logs out, Then the panel session ends, and the session at the identity provider stays.

User Story 2 - See only my own deployments (Priority: P1)

Each deployment has one owner. An operator sees and changes only the deployments that they own.

Why this priority: the panel is multi-tenant. A leak between tenants is a security failure.

Independent Test: a unit test where a second operator tries each page and action on a deployment of the first operator.

Acceptance Scenarios:

  1. Given two operators with deployments, When one operator opens the list, Then the list shows only the deployments of that operator.
  2. Given a deployment of another operator, When an operator opens, saves, duplicates or deletes it, Then the panel answers that the deployment does not exist, and changes nothing.

User Story 3 - See the history of my account (Priority: P2)

The account page links to the history of the account: the last actions of the operator on all their deployments, from the audit events of api, newest first. The history also shows the actions that api or the panel refused, with the reason, and the actions on deployments that the operator deleted.

Why this priority: an operator can see what their account did, also when a deployment is gone, and can find actions that they did not do.

Independent Test: unit tests of the history page with an api that gives events, and with an api that does not answer.

Acceptance Scenarios:

  1. Given an operator that signed in with single sign-on, When the operator opens the history, Then the panel asks api for the events of the OpenID Connect subject and issuer, and of the internal key of the account without an issuer, and shows the last events of the two lists together, newest first.
  2. Given an event on a deployment of the operator, When the history shows it, Then it shows the name of the deployment with a link. A deployment that is gone, or that the operator does not own, shows as its identifier.
  3. Given that api does not answer, When the operator opens the history, Then the page shows a notice that the history can be incomplete.
  4. Given a superuser, When they open the history of another account by its user name, Then the panel shows the history of that account, with the account of each event, and the names of the deployments of that account without a link. An unknown user name gives a not-found answer.
  5. Given an operator that is not a superuser, When the operator opens the history of another account, Then the panel refuses, and does not call api.

Edge Cases

  • The client secret is missing: the panel starts and offers only the password login. Other read errors of a secret give a warning in the log.
  • The client secret changes: the panel restarts and uses the new secret.
  • An administrator removes the account of an owner: the panel first asks api to queue the destroy of each deployment of the account, and then removes the account and its deployments. If api does not queue a destroy, the removal does not occur, and the administrator sees the error.

Requirements (mandatory)

Functional Requirements

  • FR-001: The panel MUST offer single sign-on only when the issuer, the client identifier and the client secret are all set.
  • FR-002: The panel MUST keep the password login available.
  • FR-003: The panel MUST keep the ownership of a deployment in its own database. It MUST use the stable internal keys of accounts and deployments, not user names, in deployment identifiers, event channel names and tokens. The subject that it gives to api MUST be the OpenID Connect subject of an account that signed in with single sign-on, together with the issuer of the provider, else the internal key of the account.
  • FR-004: The panel MUST limit each page, action and proxied call to the deployments of the operator that is logged in.
  • FR-005: The panel MUST NOT take the identity of a user from api.
  • FR-006: The panel MUST match a deployment identifier or an event channel only to the exact identifier of a deployment of the operator. It MUST check all identifiers of one call in one lookup.
  • FR-007: When the account of an owner is removed, the panel MUST destroy the deployments of that account, and their live infrastructure, through api.
  • FR-008: The panel MUST show an operator the audit events of their own identities only, and MUST NOT show the name of a deployment that the operator does not own. A superuser MAY see the history of each account, and the history MUST then show the account of each event.

Key Entities

  • Operator: a user account of the panel. Its internal key is the key of ownership.
  • Deployment: a record of intent that one operator owns.
  • Deployment identifier: a UUID that the panel makes. api treats it as opaque.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: No page, action or proxied call gives data of a deployment to an operator who does not own it.
  • SC-002: An operator can log in with single sign-on, or with a password when no identity provider is configured.

Assumptions

  • The identity provider gives a stable preferred user name. Ownership does not depend on the user name, so a change of a user name keeps the deployments of that user. A trusted backend that calls on behalf of a user names the user by the user name.

Known Deviations

None.