Hi,
i found a "strange" bug that i was finally able to reproduce on different containers about the local admin creation (troubleshooting was done in relation `Set-PSUIdentity -Password` does not update `PasswordLastSet` (the reset page does) - Devolutions Forum )
ENVIRONMENT
PowerShell Universal: 2026.2.5
Host: Linux container (Rocky-based image), PowerShell 7.6.3
Database: SQLite, empty (first run)
Configuration: PSUDefaultAdminName / PSUDefaultAdminPassword set via environment
SUMMARY
On a first run against an empty database, PowerShell Universal creates the local
administrator account from PSUDefaultAdminName / PSUDefaultAdminPassword roughly 110
seconds after the service starts (slow developer notebook with a lot of containers too).
If an authentication request using that same user name reaches the API before then (READ or Get-PSUIdentity), the
ClaimsEvaluator inserts a claims identity under that name, and the first-run creation
afterwards fails:
ClaimsEvaluator psu_admin is not in the database. Adding identity.
System.Exception: Identity 'psu_admin' already exists.
at PowerShellUniversal.Authentication.IdentityService.CreateIdentity(Identity identity)
in .../PowerShellUniversal.Authentication/IdentityService.cs:line 120
The instance is left with an identity of that name that is not a local account and has no
password. Nobody can log in with it, and a restart does not repair it, because
PSUDefaultAdmin* are only consulted while no administrator account exists - and now one
does. The database has to be recreated.
THREE RUNS, SAME IMAGE, ONLY THE EARLY REQUEST DIFFERS
Run During startup Identity table afterwards
----------- --------------------------------- --------------------------------------
control nothing psu_admin LocalAccount=1, password set
API basic auth as psu_admin at ~t+79s psu_admin LocalAccount=0, no password
browser repeated visits to the login page psu_admin LocalAccount=1, password set
The browser run could not reproduce it, and that appears to be by design: for the whole
startup window GET /login answers 302 to /first-run, which shows "PowerShell Universal is
starting..." and offers no login form. The user is simply held there until the account
exists.
Basic authentication against the API has no such gate. Polled every 3 seconds from the
first second, GET /api/v1/accessible with the admin name and password returned:
t+ 0s 401 (server not up)
t+ 79s 200 <-- account does not exist yet; this is the request that breaks it
t+148s 401
STEPS TO REPRODUCE
1. Start an instance with an empty database and PSUDefaultAdminName/Password set.
2. From the first second, send basic-auth requests with that user name to any API
endpoint - we used GET /api/v1/accessible.
3. Let startup finish, then inspect the Identity table or try to log in.
EXPECTED
An authentication attempt should not be able to prevent the account from being created.
Either the first-run creation wins, or it completes the existing identity into a local
account. A 200 for an account that does not exist yet also looks wrong on its own.
IMPACT
Easy to hit unintentionally on a new deployment: a health check, a monitoring probe or a
deployment script that authenticates as the admin during the first two minutes is enough,
and the damage is permanent for that database. We hit it with an automated readiness
check; interactive users never did, because the /first-run gate protects them.
QUESTION
Is there a supported way to recover an instance already in this state, short of
recreating the database - for example removing the identity and restarting?
Thanks,
René