QSCSCore HTTP API, Identity Auth Endpoints
On this page 1 sections
Identity Auth Endpoints
QSCS binds identity to a per-request ed25519 signature rather than to a cookie or bearer token. These endpoints establish, query, and clear that binding. They are normally driven by the browser substrate (qscs-crypto.js + the 17 KB WASM module) on your behalf; you only invoke them directly for headless automation or a custom client integration.
Every authenticated request, including /auth/login itself, carries four headers:
X-QSCS-Client-Uuid, 32 lowercase hex.X-QSCS-Ts, decimal milliseconds since Unix epoch.X-QSCS-Nonce, 32 lowercase hex; the (UUID, nonce) tuple is accepted at most once.X-QSCS-Sig, base64 of a detached ed25519 signature overMETHOD\nHOST\nURI\nBODY\nTS\nNONCE.
See Signed Request Format for the canonical message rules and Identity Gate for the architecture.
POST /auth/login
Authenticate the calling client UUID against the origin's identity provider. The request itself must be signed by the privkey matching the pubkey in the body (proof of possession). QSCSCore verifies the signature, calls the control plane, then persists (client_uuid, origin, pubkey) in the local identity store and replicates the binding to peers via the identity Delta channel.
Request
POST /auth/login\nHost: example.com\nContent-Type: application/json\nX-QSCS-Client-Uuid: <32 hex>\nX-QSCS-Ts: <ms>\nX-QSCS-Nonce: <32 hex>\nX-QSCS-Sig: <base64>\n\n{\n \"username\": \"alice\",\n \"password\": \"...\",\n \"client_uuid\": \"<32 hex>\",\n \"pubkey\": \"<64 hex>\"\n}Response, success
{ \"ok\": true, \"uuid\": \"<32 hex>\", \"origin\": \"example.com\" }Errors
All error paths return HTTP 200 with ok:false; branch on ok rather than the status code.
| Body | Cause |
|---|---|
{\"error\":\"missing required fields: username, password, client_uuid, pubkey\"} | Body missing one of the four fields. |
{\"error\":\"invalid pubkey length\"} | Pubkey not 64 hex characters. |
{\"error\":\"malformed pubkey\"} | Pubkey contains non-hex characters. |
{\"error\":\"signature invalid\"} | Headers missing or expired, nonce reused, or signature does not verify against the supplied pubkey. |
{\"error\":\"authentication failed\"} | Username/password rejected by the control plane. |
{\"error\":\"control plane unreachable\"} | Control plane lookup failed at the network layer. |
{\"error\":\"identity auth not configured\"} | Node has no control plane or identity store wired up. |
Example
curl -X POST -H 'Host: example.com' \\\n -H 'Content-Type: application/json' \\\n -H \"X-QSCS-Client-Uuid: $UUID\" -H \"X-QSCS-Ts: $TS\" \\\n -H \"X-QSCS-Nonce: $NONCE\" -H \"X-QSCS-Sig: $SIG\" \\\n -d \"{\\\"username\\\":\\\"alice\\\",\\\"password\\\":\\\"...\\\",\\\"client_uuid\\\":\\\"$UUID\\\",\\\"pubkey\\\":\\\"$PUBKEY\\\"}\" \\\n https://example.com/auth/loginPOST /auth/logout
Erase the (client_uuid, origin) binding for the calling UUID and discard its per-UUID nonce ring. The caller is identified by X-QSCS-Client-Uuid; the signature is verified against the stored pubkey, so a third party cannot log another client out.
Request
Empty body. Signed headers required.
Response
{ \"ok\": true, \"erased\": true }Returns {\"ok\":true,\"erased\":false} when no binding existed for the UUID (idempotent), or {\"ok\":false,\"error\":\"signature invalid\"} when verification fails.
GET /auth/status
SPA probe used by the browser bundle to choose between the login overlay and the panel view. Returns authenticated only when the calling X-QSCS-Client-Uuid has a valid binding for the request Host. This endpoint sits inside the /auth/* carve-out, so an unsigned request simply receives authenticated:false instead of a 401.
Response, authenticated
{ \"authenticated\": true, \"username\": \"alice\", \"uuid\": \"<32 hex>\" }Response, not authenticated
{ \"authenticated\": false }GET /api/identity/status
Public lookup of a single identity record by UUID. Used by cluster tooling and the control plane; does not require signed headers.
Query parameters
uuid | string | Client identity UUID to look up (32 hex). |
Response, found
{\n \"uuid\": \"...\",\n \"origin\": \"example.com\",\n \"authenticated\": true,\n \"last_seen\": 1715520000,\n \"found\": true\n}Response, not found
{ \"uuid\": \"...\", \"authenticated\": false, \"found\": false }Errors
{\"error\":\"missing required parameter: uuid\"} | No uuid query parameter supplied. |
{\"error\":\"identity store not configured\"} | Node has no identity store wired up. |
Related
- Concept: Identity Gate, architecture and threat model.
- HTTP API: Signed Request Format, wire reference for the four headers and the canonical message.