Skip to main content
Sinas supports three authentication modes for end-user login, plus API keys for programmatic access. The mode is set per-deployment via the AUTH_MODE environment variable and cannot be changed at runtime.

Auth Modes

ModeWhat’s required to log inWhen to use
otp (default)Email + 6-digit OTPDefault. Proves email control on every login. Requires SMTP.
passwordEmail + passwordAirgapped or no-SMTP deployments. No email round-trip.
password+otpEmail + password + OTPMost secure. Treats the OTP as a liveness check on the email account — useful when you need to lock out ex-employees by revoking their work mailbox. Requires SMTP.
Clients (custom frontends, the JS/Python SDKs, the official console) discover the active mode via the unauthenticated GET /info endpoint and branch their login UI accordingly.

Login Flows

otp

  1. Client posts email to POST /auth/login
  2. Sinas sends a 6-digit code (valid 10 min by default)
  3. Client posts code to POST /auth/verify-otp and receives access + refresh tokens

password

  1. Client posts email + password to POST /auth/login
  2. Sinas verifies and immediately returns access + refresh tokens

password+otp

  1. Client posts email + password to POST /auth/login
  2. On password match, Sinas sends a 6-digit OTP and returns an OTP session id
  3. Client posts code to POST /auth/verify-otp and receives access + refresh tokens

Tokens

All modes issue the same JWT pair:
  • Access token — short-lived (default 15 min), sent as Authorization: Bearer <token>
  • Refresh token — long-lived (default 30 days), exchanged at POST /auth/refresh
POST   /auth/login                # Start login (mode-dependent payload)
POST   /auth/verify-otp           # Verify OTP for otp / password+otp modes
POST   /auth/refresh              # Get new access token
POST   /auth/logout               # Revoke refresh token
GET    /auth/me                   # Get current user info

Superadmin Bootstrap

The first admin user is seeded from environment variables on backend startup:
  • SUPERADMIN_EMAIL — email of the user to create / promote to Admins
  • SUPERADMIN_PASSWORD — only used when AUTH_MODE is password or password+otp. Setting this on a running deployment and restarting the backend will reset the password — the escape hatch for “admin lost their password.”

Password Reset

For modes that include passwords:
  • User-initiated — not implemented when AUTH_MODE=password (no email channel guaranteed). Use admin reset.
  • Admin-initiated — an admin generates a one-time reset link from the user management page in the console and delivers it out-of-band (Slack, in person).
  • Lost-superadmin escape hatch — set SUPERADMIN_PASSWORD in the env and restart the backend.

API Keys

For programmatic access (scripts, CI/CD, integrations), create API keys instead of using short-lived JWT tokens. Each key has its own set of permissions (a subset of the creating user’s permissions). API keys work identically across all auth modes.
POST   /api/v1/api-keys           # Create key (plaintext returned once)
GET    /api/v1/api-keys           # List keys
GET    /api/v1/api-keys/{id}      # Get key details
DELETE /api/v1/api-keys/{id}      # Revoke key
API keys can be used via Authorization: Bearer <key> or X-API-Key: <key> headers. Keys can have optional expiration dates.