Recovery CLI
The recovery CLI is a break-glass tool. It runs inside the container, using the configured database connection — there's no network surface, no auth bypass. It exists for the situations where the admin UI cannot help: no admin can sign in, the projections desynced after a schema change, a legacy client needs a Phase-2C retrofit, etc.
Every invocation is written to the auth log.
Entry point
dotnet Modgud.Api.dll recover <command> [args...] [--realm <slug>]The --realm flag defaults to system. Commands that don't need a tenant context ignore it.
Commands
list
List every active user with UserName · Email · Active · Admin · 2FA · Passkeys.
dotnet Modgud.Api.dll recover listAdmin means the user holds realm:admin (typically via the System Admin role inside the seeded Administratoren group).
reset-2fa <username>
Disable TOTP and Email-OTP, delete every stored passkey credential, and clear the grace-period stamp so the user gets a fresh secure-setup window on next login.
dotnet Modgud.Api.dll recover reset-2fa aliceset-email <username> <new-email>
Update the user's email and append a UserUpdatedEvent so projections
- SignalR-driven admin grids refresh live.
dotnet Modgud.Api.dll recover set-email alice alice@example.commagic-link <username>
Issue a one-time magic-link URL and print it to stdout. Useful for nudging a locked-out user back in without resetting their password.
dotnet Modgud.Api.dll recover magic-link alicerebuild-projections
Rebuild all Marten projections (inline + async). Bootstrap path for the first migration after a breaking schema change — runs without any admin authentication.
dotnet Modgud.Api.dll recover rebuild-projectionsbootstrap-admin
Create the first admin in a realm. Default realm: system. Two modes — Direct (password set immediately) and Invite (a magic-link URL is printed and emailed if SMTP is configured).
# Direct mode
dotnet Modgud.Api.dll recover bootstrap-admin \
--email admin@example.com \
--username admin \
--firstname Admin \
--lastname User \
--password 'ChangeMe1!'
# Invite mode (no --password)
dotnet Modgud.Api.dll recover bootstrap-admin \
--email admin@example.com \
--username adminFlags:
| Flag | Required | Notes |
|---|---|---|
--email | yes | Email — required in both modes. |
--username | no | Defaults to the local-part of the email. |
--firstname | no | Optional. |
--lastname | no | Optional. |
--password | no | If present: Direct mode. Validated against the configured Identity password rules. If absent: Invite mode. |
--realm <slug> | no | Defaults to system. |
migrate-cc-credentials
Phase-2C retrofit. For every OAuth client that still has the client_credentials grant without a LinkedServiceAccountId (i.e. pre-Phase-2C clients), auto-provision a Service Account named legacy.{clientId} and backfill the link so the standard SA-managed mutation guard applies.
Idempotent — already-linked clients are skipped; existing legacy.* SAs are re-used.
dotnet Modgud.Api.dll recover migrate-cc-credentials --realm systemrealm-list
List every active realm with its slug and configured domains. Useful first probe after a fresh deploy — shows the system realm's seeded localhost domains so you know which Host header to use.
dotnet Modgud.Api.dll recover realm-listrealm-add-domain
Add a domain to an active realm's Domains list. Typically used once after a fresh deploy to add the production hostname to the system realm.
dotnet Modgud.Api.dll recover realm-add-domain \
--slug system \
--domain auth.example.comFlags:
--slug <slug>— required.--domain <hostname>— required. Stored verbatim; case-insensitive match at request time.
realm-remove-domain
Remove a domain from an active realm's Domains list. No-op if not present.
dotnet Modgud.Api.dll recover realm-remove-domain \
--slug system \
--domain old.example.comhelp
Show the usage summary.
dotnet Modgud.Api.dll recover helpAudit trail
Every recovery invocation writes a Auth: Recovery <command> entry to the auth log via Serilog. Successful operations log at Warning level (to make them stand out in the log stream); failures log at Error.
When to reach for the CLI
- No admin can sign in →
bootstrap-admin(Direct mode) creates a fresh admin in one shot. - A user lost their 2FA device →
reset-2fa <username>thenmagic-link <username>so they can log in and re-enrol. - Production hostname doesn't route to a realm →
realm-listto confirm what's configured, thenrealm-add-domainto bind the new hostname. - Marten projections out of sync after a schema change →
rebuild-projections. - Legacy
client_credentialsclients fail mutation guard →migrate-cc-credentialsprovisions the linked SA they need.
For the operational story of first-time admin setup (when there's no admin yet to invite anyone), see First-time setup.