This is a personal proof-of-concept project. It is not intended for production use. Please refrain from using it.
Skip to content

Authentication

Every /api/v1 endpoint requires authentication. Only the health probes (GET /api/v1/health, GET /api/v1/health/ready), login (POST /api/v1/auth/login), and the first-run setup endpoints (GET/POST /api/v1/auth/setup, valid only while no users exist) are open. The dashboard signs in with email + password and holds a session JWT; CI, the MCP server, and scripts authenticate with a long-lived API token. Both are sent the same way:

Authorization: Bearer <jwt-or-api-token>

Run artifacts (per-step screenshots) are served from GET /api/v1/artifacts/... and are also authenticated, the dashboard passes the token as a ?token= query param because <img> tags can't send an Authorization header.

Repeated failed logins from one IP are rate-limited (10 failures / 5 min → 429). For multi-replica deployments, add rate limiting at your reverse proxy too.

First-run admin

A fresh instance has no users. The first time you open the dashboard it shows a "Create your admin account" screen, set an email + password and you're signed in as the admin. From there you can add everyone else (see Managing users).

For headless / Docker / CI, pre-seed the admin from the environment instead, when both are set on first boot, the admin is created automatically and the setup screen is skipped:

bash
UPLIFTR_ADMIN_EMAIL=admin@yourco.com
UPLIFTR_ADMIN_PASSWORD=change-me-now

Passwords must be at least 8 characters (enforced on the browser setup screen) and are hashed with argon2, never stored or logged in plaintext.

Roles

RoleCan do
adminEverything, including managing users and writing Settings (the integration credentials).
memberAuthor/run suites, view runs, issues, plans, and analytics. Cannot manage users or change settings.

Sessions (dashboard)

POST /auth/login with { "email", "password" } returns a JWT and the user record. The dashboard stores the token and attaches it to every request; a 401 clears it and bounces back to the login screen. Tune the session lifetime with UPLIFTR_JWT_TTL_SECONDS (default 7 days), and set UPLIFTR_JWT_SECRET in production so sessions survive a restart.

bash
curl -s localhost:8400/api/v1/auth/login \
  -H 'content-type: application/json' \
  -d '{"email":"admin@yourco.com","password":"change-me-now"}'
# → { "token": "eyJ…", "user": { "id": "…", "email": "…", "role": "admin" } }

API tokens (CI / MCP / scripts)

Create a token from Settings → API tokens in the dashboard, or via the API. The raw token (prefixed tw_) is shown once at creation, store it in your secret manager; only a hash is kept server-side.

bash
# create (uses your session JWT)
curl -s localhost:8400/api/v1/auth/tokens \
  -H "Authorization: Bearer $JWT" \
  -H 'content-type: application/json' -d '{"name":"ci"}'
# → { "id": "…", "name": "ci", "token": "tw_…" }   ← copy the token now

# then use it anywhere
curl -s localhost:8400/api/v1/suites -H "Authorization: Bearer tw_…"
MethodPathPurpose
POST/auth/tokensCreate a token (returns the raw tw_… once).
GET/auth/tokensList your tokens (metadata only, no secret).
DELETE/auth/tokens/{id}Revoke a token.

Managing users (admin)

From the dashboard, an admin provisions teammates under Settings → Team: enter an email + a temporary password, pick Member or Admin, and Add user. They sign in with those credentials; share the password with them and have them change it. (Members can author and run tests; admins can also change settings and manage users.)

The same is available over the API:

MethodPathPurpose
GET/auth/meThe current user.
GET/auth/usersList users (admin).
POST/auth/usersCreate a user { email, password, role } (admin).

Related: Settings & env · REST API · Deploying

Upliftr · AI-native, self-healing E2E testing. Terms · Privacy · Legal Notice