Identity token signing requires a secure random key. Configure it through environment variables or a secrets manager and keep it out of committed appsettings files.
- Code-first hosts using `Identity:Tokens` should set `Identity__Tokens__SigningKey`.
- Shell-based hosts should set the shell feature path, for example `CShells__Shells__Default__Features__Identity__SigningKey`.
- Production startup rejects missing keys, keys shorter than 32 ASCII characters, and known public defaults. Known public defaults are tolerated only in the explicit `Development` or `Demo` environments.
Elsa supports bootstrapping an initial admin role and user through the `DefaultAdminUser` feature.
This is the recommended way to initialize identity access now that user-management endpoints are permission-based and no longer rely on the `SecurityRoot` policy.
See `doc/adr/0010-default-admin-user-bootstrap-for-initial-identity-access.md` for the architectural decision.
### New shell functionality (recommended)
When using shell-based configuration (`CShells`), configure the `DefaultAdminUser` shell feature.
- Localhost requests no longer satisfy `SecurityRoot` by default. Legacy localhost bootstrap requires an explicit opt-in: call `EnableLocalHostPermissionGrantForSecurityRoot()` in code-first configuration or set `EnableLocalHostPermissionGrant` on the shell `DefaultAuthentication` feature; prefer `DefaultAdminUser` instead.
New identity passwords, client secrets, and API keys are hashed with PBKDF2-SHA256 using 600,000 iterations, a per-record salt, and version metadata. Existing legacy SHA-256 hashes remain valid and are upgraded opportunistically after a successful user login or API-key validation.