Auth
- Endpoints
POST /v1/auth/loginPOST /v1/auth/token/refreshPOST /v1/auth/sso/{provider}/callbackPOST /v1/users/{id}/mfa/totpPOST /v1/auth/logout
Resolved — see Decisions → Identity provider. Native email/password is implemented in-house and real from Phase 1. SSO (per-Organization, broker-based) is architected for now — the UserIdentity/SSOConnection shape below is built to not need a breaking change — but the actual broker integration is deferred; POST /v1/auth/sso/{provider}/callback is a real route today, with its request/response shape still open.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/auth/login |
Exchange a credential (password, or a federated assertion once SSO is live) for a session. |
POST |
/v1/auth/token/refresh |
Exchange a refresh token for a new access token. |
POST |
/v1/auth/sso/{provider}/callback |
Complete an SSO login. Deferred — see the note above. |
POST |
/v1/auth/logout |
Invalidate the current session. |
POST |
/v1/users/{id}/mfa/totp |
Enroll TOTP-based MFA for a password UserIdentity. Optional, user-initiated — see Decisions → Identity provider. |
POST /v1/auth/login
// Request
{ "email": "jordan@example.com", "password": "..." }
// Response — 200
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "rtk_01JAG8K4Q9R0S1T2U3V4W5X6Y7",
"expires_in": 900,
"user_id": "usr_01JAG3Z9X8QS3F6K2M4N5P6R7S"
}
access_token is a platform-level JWT for talking to this API — distinct from the per-app JWT described in Trust Model, which is issued separately at app-launch time and scoped to one Application’s aud.
POST /v1/auth/token/refresh
// Request
{ "refresh_token": "rtk_01JAG8K4Q9R0S1T2U3V4W5X6Y7" }
Returns the same shape as login. Refresh tokens are single-use — each refresh issues a new one and invalidates the old.
POST /v1/auth/sso/{provider}/callback
Completes a federated login, creating or matching a method: sso UserIdentity against the Organization’s SSOConnection. The exact request/response shape depends on the broker integration, which is deliberately not built yet — see Decisions → Identity provider. The response, once implemented, returns the same AuthSession shape as login — SSO is a different way to obtain a session, not a different kind of session.
POST /v1/users/{id}/mfa/totp
// Request — enroll
{}
// Response — 200
{ "secret": "JBSWY3DPEHPK3PXP", "qr_code_url": "https://api.substratalapps.com/v1/users/usr_.../mfa/totp/qr" }
Self-service only — a password UserIdentity opts itself into TOTP; nothing here is admin-initiated. Confirming enrollment (a follow-up PATCH with the first valid code) flips mfa_enabled: true on that identity. Meaningless for a method: sso identity — an Organization’s own IdP owns MFA policy for its federated members, not this endpoint.
POST /v1/auth/logout
// Request
{}
// Response — 204
Invalidates the current access/refresh token pair. Does not affect per-app JWTs already issued to downstream apps — those expire on their own short TTL per Trust Model; logging out of the hub does not retroactively revoke them. If immediate cross-app session kill on logout is a requirement, it needs the webhook path described there, not this endpoint.