refactor: keep tenant applications out of the administrator's reach

Claiming the system administrator role no longer grants access to every
application in the installation. Owning a tenant is what lets an administrator
administer it; entering the applications running inside it is a separate,
explicit grant that can be withdrawn again. Handing it out at claim time gave
every installation a standing administrator account inside every customer
application, which is the opposite of the boundary this product draws.

The behaviour suite now covers single sign-on between applications directly: a
second application on the same tenant must receive a code and identify the same
person with no sign-in page in between, once Go Loose already holds a session.

Also adds theme-token tests against the shared styling contract and store
coverage for application grants, and drops the redundant server and security
scheme declarations from the published specification.
This commit is contained in:
Daniel Noulet 2026-10-05 21:48:05 +02:00
parent 8d8970d5a7
commit 49ab89ae46
6 changed files with 319 additions and 20 deletions

View file

@ -98,6 +98,13 @@ func (s *Store) Install(ctx context.Context, installation Installation, demoUser
return tx.Commit()
}
// ClaimFirstSystemAdministrator promotes the first user to sign in to system
// administrator and gives them ownership of every tenant that exists at that
// moment. It is a no-op once an administrator exists.
//
// It grants console reach across the installation and nothing more: no
// application grant, so the new administrator cannot sign in to a tenant
// application until one is deliberately given to them.
func (s *Store) ClaimFirstSystemAdministrator(ctx context.Context, userID string) (bool, error) {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
@ -124,11 +131,14 @@ func (s *Store) ClaimFirstSystemAdministrator(ctx context.Context, userID string
ON CONFLICT DO NOTHING`, userID); err != nil {
return false, err
}
if _, err := tx.ExecContext(ctx, `
INSERT INTO user_application_access(application_id, user_id, granted_by)
SELECT a.id, $1, $1 FROM applications a ON CONFLICT DO NOTHING`, userID); err != nil {
return false, err
}
// Deliberately no application grant. Owning every tenant is what lets the
// administrator administer it; it is not a licence to enter the applications
// running inside it. Access to a client application is only ever an explicit
// grant, so an administrator who wants to use one attaches themselves the same
// way anybody else does, visibly, from the console, and it can be withdrawn
// again without touching the tenant. Granting it here instead would hand every
// installation a standing administrator account inside every customer
// application, which is the opposite of the boundary this product draws.
return true, tx.Commit()
}