Epure

Authentication

Epure uses three auth mechanisms. Pick one per request — they do not stack.

What is DSN vs session vs PAT?

The DSN authenticates ingest. Dashboard /api/v1/* uses a session cookie and RLS app.current_org_id. MCP and epure-cli use a personal access token on the same /api/v1/* paths (plus /api/v1/agent/* shortcuts), gated by scopes.

SurfacePathsCredentialScope
Ingest/api/{project_id}/envelope/, /store/, /releases/…/files/, /user-feedback/DSN public key (sentry_key)Project (and parent org) from the key
Dashboard (browser)/api/v1/* (except public auth routes)Session cookieOrg from session; RLS app.current_org_id
Automation (MCP / CLI)/api/v1/* including /api/v1/agent/*Authorization: Bearer epure_pat_…read:agent, optional write:triage, write:admin

Sending a session cookie to ingest does nothing. Sending DSN headers to /api/v1/issues returns 401. Bearer PAT on ingest returns 401.

Create PATs at Settings → Agent tokens: MCP and epure-cli · Agent API.

How does DSN ingest auth work?

Credentials come from a project DSN key. Create or rotate one in the UI, or via /api/v1/projects/{id}/dsn-keys. Copy the DSN from Settings → SDK connection.

Official Sentry SDKs use a public-key-only DSN. Epure (v0.1.5+) accepts sentry_key alone. You do not need a secret key in Sentry.init or in curl.

Preferred outside browser SDKs:

X-Sentry-Auth: Sentry sentry_version=7, sentry_key={public_key}

DSN URL shape

http://{public_key}@{host}/{project_id}

The path {project_id} must match the key’s project (numeric segment for official SDKs).

StatuserrorWhat to do
403project_mismatchUse the project id from the DSN
403dsn_revokedCreate or rotate a key
401invalid_dsnCheck sentry_key / header spelling. On builds older than v0.1.5, upgrade — pre-v0.1.5 rejected public-key-only auth

CORS

Ingest routes answer OPTIONS for browser SDKs. Allowed request headers include X-Sentry-Auth, Content-Type, Content-Encoding. Origins: Configuration.

How does session auth work?

After password or Google login, the server sets an HttpOnly cookie backed by Postgres tower-sessions.

ModeCookie name
Secure (EPURE_SESSION_SECURE=1, default prod)__Host-epure.sid
Local HTTP (EPURE_SESSION_SECURE=0)Epure.sid

Attributes: HttpOnly, SameSite=Lax, Path=/, inactivity expiry 14 days.

No bearer tokens in localStorage.

Login

curl -sS -c cookies.txt -D - -o /dev/null -X POST \
  "http://localhost:8080/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"your-password"}'
ResultMeaningWhat to do
204 + Set-CookieSession establishedReuse -b cookies.txt on /api/v1/*
401Bad email/passwordRegister, or ./scripts/seed.sh --email … --password …
403 on POST /registerEPURE_REGISTRATION is closedSign in, or register with an invite_token. Configuration
429 plain text20 req / IP / 60sWait

Public /api/v1/auth routes

MethodPathNotes
GET/api/v1/auth/config{ google_enabled, password_enabled, registration_enabled }
POST/api/v1/auth/registeremail + password (+ optional invite_token). 403 when registration is closed and there is no invite
POST/api/v1/auth/loginemail + password → 204
GET/api/v1/auth/googleOIDC start
GET/api/v1/auth/google/callbackOIDC callback
GET/api/v1/auth/mecurrent session (requires cookie)
POST/api/v1/auth/logoutclear session
POST/api/v1/auth/accept-invitation{ invite_token }
PATCH/api/v1/auth/profile{ display_name }
PATCH/api/v1/auth/passwordchange password
DELETE/api/v1/auth/accountdelete account

Login body:

{ "email": "you@example.com", "password": "your-password", "invite_token": null }
Login succeeds but later /api/v1 calls are 401?

The browser rejected the cookie over an HTTPS vs EPURE_SESSION_SECURE mismatch. Local HTTP needs 0 (Epure.sid); HTTPS needs 1 (__Host-epure.sid). DSN headers on this path also return 401, so use the cookie. See Troubleshooting.

Can I use the DSN as a bearer token?

No, and there are no bearer tokens in localStorage either. The DSN covers ingest only: envelope, store, release files, user feedback. Issues and Events need the login cookie. The tables above list which header belongs on which path.

Do I need a DSN secret key?

No for official Sentry SDKs. Sentry treats the secret as deprecated; modern clients send only sentry_key. Epure v0.1.5+ matches that. Paste the public-key DSN from Settings → SDK connection into Sentry.init.