Sign-in methods reference
The sign-in methods of a TaleArt install: what each is, what an admin configures for an identity provider, the environment variables, the endpoints, the error codes and the security properties. For the steps to set them up, see the Sign-in methods guide.
Methods
| Method id | Label | Kind | Turned on | What is stored |
|---|---|---|---|---|
passkey | Passkey | passkey | On from a fresh install. | A passkey per device, with its public key; the private key stays on the device or in a password manager. |
password | Username and password | password | Off until an admin turns it on. | A scrypt hash of the password, and the lower-case username. |
google | Google (a preset) | Added and turned on by an admin. | Client ID and scopes in plain text; the client secret encrypted. | |
apple | Apple (a preset) | apple | Added and turned on by an admin. | Client ID, Team ID and Key ID in plain text; the .p8 private key encrypted. |
oidc:<slug> | A generic OpenID Connect provider | oidc | Added and turned on by an admin, under a slug the admin picks. | Issuer, client ID and scopes in plain text; the client secret encrypted. |
A fresh install has the passkey on and the password off. Each admin can turn the passkey and the password on or off in Settings > Sign-in methods. At least one method must stay on, and every admin must keep one usable method.
Provider settings
An admin adds a provider in Settings > Sign-in methods > Add a provider. The kind is Google, Apple or Generic OpenID Connect. The redirect URI to register at the provider is PUBLIC_API_URL/api/v1/auth/callback/<slug>, for example https://api.example.com/api/v1/auth/callback/google, and it appears in the drawer once the provider is saved. Secrets are write-only: the API never returns them, only whether one is set.
| Field | Kinds | Required | Where it is stored |
|---|---|---|---|
| Slug (the URL name, e.g. company-sso) | Generic OpenID Connect | Yes, lower-case letters, digits and hyphens, up to 40 | Plain (the provider key) |
| Button name (display name) | All | Yes, up to 80 characters | Plain |
| Issuer URL (issuer) | Generic OpenID Connect | Yes, https (http only for localhost outside production) | Plain |
| Client ID (clientId) | All | Yes, up to 255 characters | Plain |
| Scopes (scopes) | Generic OpenID Connect, Google | No; default openid email profile; must include openid; up to 200 characters | Plain |
| Team ID (teamId) | Apple | Yes, 10 letters and digits | Plain |
| Key ID (keyId) | Apple | Yes, 10 letters and digits | Plain |
| Client secret, or the Apple .p8 private key as PEM (secret) | All | Yes, to make the provider usable; up to 8,192 characters | Encrypted (AES-256-GCM, TALEART_SECRET_KEY); never returned by the API |
Environment variables
| Variable | Required | Value | Effect |
|---|---|---|---|
TALEART_SECRET_KEY | To save any provider secret | Base64 of 32 random bytes, e.g. openssl rand -base64 32. | Encrypts provider secrets. Without a valid key the API still runs but refuses to save a secret (503 secret_key_missing). |
TALEART_SETUP_PASSWORD | No | Only the literal true enables it. Default off. | On an empty install, the first admin may set up with a username and password. |
PUBLIC_API_URL | Set it for any real install | The public address of the API, default http://localhost:3333. | The redirect URI is PUBLIC_API_URL plus /api/v1/auth/callback/<slug>. |
RP_ORIGIN | Set it for any real install | The dashboard origin, default http://localhost:4200. | Where the dashboard lives; passkeys and the cookie Secure flag follow it (Secure when it starts with https:). |
RP_ID | Set it for any real install | The dashboard host name, default localhost. | Passkeys are bound to this host name. |
NODE_ENV | Set to production for a real install | Any value; production turns something off. | Outside production, a provider issuer may be plain http on localhost. In production it must be https. |
Endpoints
The Sign-in methods tag of the API reference. Every path is listed here.
| Method | Path | Who may call | Purpose |
|---|---|---|---|
GET | /auth/account/methods | A signed-in user (session cookie) | The user's passkeys, password username and linked provider identities. |
PUT | /auth/account/password | A signed-in user | Set a password, or change it (the current password is needed when one is set). |
DELETE | /auth/account/password | A signed-in user | Remove the password, if another method stays usable. |
DELETE | /auth/account/passkeys/{passkeyId} | A signed-in user | Remove one of the user's passkeys, if another method stays usable. |
DELETE | /auth/account/identities/{identityId} | A signed-in user | Unlink one of the user's provider identities, if another method stays usable. |
GET | /auth/settings | An admin | Which methods are on, and whether the server has the secret key. |
PUT | /auth/settings | An admin | Turn the passkey and password methods on or off. |
GET | /auth/providers | An admin | The providers, with usable, hasSecret and the redirect URI. Never a secret. |
PUT | /auth/providers/{slug} | An admin | Add a provider, or replace its settings; send or remove its secret. |
DELETE | /auth/providers/{slug} | An admin | Remove a provider and its secret. |
POST | /auth/users/{userId}/password-reset | An admin | Issue a one-time reset link for a user (shown once). |
GET | /auth/providers/{slug}/start | Anyone, without a session (purpose link needs a session) | Start a sign-in, setup, invitation or link with a provider; redirects to the provider. |
GET | /auth/callback/{slug} | Anyone; the taleart_oauth cookie and the state must match | The redirect back from a provider. |
POST | /auth/callback/{slug} | Anyone; the same checks as the GET callback | The form-posted redirect back from Apple (response_mode=form_post). |
POST | /auth/providers/{slug}/test | An admin | Run the provider's discovery and report the issuer and endpoints. The secret is not used. |
None of these accept an API token: a request with an Authorization header is refused. Admin endpoints need an admin session.
Error codes
Every error answers the standard body, with a code field such as {"error":{"code":"sign_in_failed"}}. The codes of sign-in are:
| Code | Meaning |
|---|---|
sign_in_failed | A sign-in was refused. The same answer for an unknown user, a wrong password, a method that is off, or a provider that is not usable. |
password_rejected | The password does not meet the policy (12 to 128 characters, not the username or the email's local part, not a common password). |
username_taken | The username is already in use. |
password_incorrect | The current password is wrong when changing a password. |
password_reset_invalid | The reset link is unknown, used, or past its 24 hours. |
sign_in_method_disabled | The method is turned off. |
last_sign_in_method | The change would leave no method usable: TaleArt will not remove the last one. |
sign_in_lockout | The change would leave an admin with no way to sign in. |
secret_key_missing | The server has no valid TALEART_SECRET_KEY, so a provider secret cannot be saved. |
provider_not_found | No provider has that slug. |
identity_in_use | The provider identity is already linked to another account. |
email_not_verified | The provider did not verify the email, so the identity cannot redeem an invitation. |
email_mismatch | The provider's verified email is not the email typed on the invitation page. |
session_required | A link needs a signed-in user. |
discovery_failed | The discovery document could not be read, or its issuer is not the configured one. |
provider_unavailable | The provider's keys or endpoints could not be read. |
invitation_invalid | The invitation is unknown, used, or past its 7 days. |
setup_closed | The first admin already exists, so setup is closed. |
passkey_failed | The passkey ceremony was refused or did not check out. |
rate_limited | Too many attempts from this address. Wait, then try again . |
not_found | The item does not exist, or it is another user's. |
Security properties
- Stored as hashes or encrypted: passwords as scrypt hashes; session and reset tokens as SHA-256 hashes; provider secrets as AES-256-GCM ciphertext. The API never returns a password, a reset token or a provider secret.
- Passwords: 12 to 128 characters, with no composition rules; not the username or the email's local part; not one of about 100 common passwords. scrypt with N=2^15, r=8, p=1, a 64-byte key and a random 16-byte salt. Compared in constant time; an unknown username is checked against a dummy hash, so timing does not reveal it.
- Throttling: 5 failed password sign-ins for a username wait 30 seconds, doubling per failure, up to 15 minutes; failures are forgotten after an hour. Per address: 10 password sign-ins in a burst, then 10 a minute. Provider sign-ins: 20 in a burst, then 20 a minute. The throttle is in memory, per API process.
- Session revocation: a password change or a reset ends the user's other sessions; the session making the change stays signed in. A reset ends every session and starts a new one.
- Provider flows use PKCE (S256), a state and a nonce of 32 random bytes each, stored server-side and bound to the browser by the taleart_oauth cookie (http-only, SameSite=Lax, path /api/v1/auth, 10 minutes). Each challenge is single use.
- ID tokens: only RS256, ES256 and PS256 signatures are accepted (never none or HS*); issuer, audience, expiry and nonce are checked, with 60 seconds of clock skew.
- Discovery: the document's issuer must equal the configured issuer exactly; endpoints must be https (plain http only on localhost outside production); 5 second timeout; 256 KiB size cap; redirects are refused. The JWKS is cached for 5 minutes.
- Apple: the client secret is an ES256 JWT signed with the .p8 key, with the key ID in its header, created for each sign-in with a 5-minute lifetime and never stored.
- Email: a provider email is used only when the provider verified it. A provider identity never creates an account by itself, and an account is never matched by email alone. An identity attaches to a user only when redeeming an invitation (the verified email equals the email typed on the invitation page), in the first-admin setup, or when a signed-in user links it.
- Registration is by invitation only, plus the first admin on an empty install. There is no open sign-up and no domain auto-join.
- Password recovery is an admin-issued link: 32 random bytes, valid once for 24 hours, a new link replaces the unused earlier ones, and it is shown once. TaleArt sends no email.
- Sessions: 7 days, a random token in an http-only cookie (taleart_session, SameSite=Strict, Secure on https). API tokens are unchanged and are not used for sign-in.
API tokens are unchanged: a token still calls the Management API as its user, and sign-in methods are never reached with one. See API tokens.