neosourceDocs
Search docs

Grant a sudo-mode window by re-verifying the password

POST/api/auth/sudo/password

sudoPassword

Authenticated (session-cookie) endpoint. Re-verifies the account password and stamps `sessions.sudo_until = now() + 5min` so the next request to a sudo-gated endpoint (TOTP enroll/disable, recovery-code regenerate, OAuth link/unlink, …) goes through. On wrong password OR an account with no password hash (OAuth-only / passkey-only) the response is `401 { error: "invalid_credentials" }` — the route deliberately doesn't distinguish so the response can't be used to fingerprint credentials. Bearer-PAT callers cannot sudo (sudo is a session-row column) — they're authenticated but the route still returns 400. Slice #6 adds a per-session rate limit: 5 attempts per 15 min, returning `429 Too Many Requests` with a `Retry-After` header on exhaustion. TODO(slice #7): the matching `/api/auth/sudo/passkey/{start,finish}` will land in this module.

Requires authentication using a session cookie — see tokens and scopes.

curl

curl -X POST 'https://neosource.dev/api/auth/sudo/password' \
  -b 'ns_session=$NEOSOURCE_SESSION' \
  -H 'Content-Type: application/json' \
  -d '{"password":"hunter2"}'

fetch

fetch("https://neosource.dev/api/auth/sudo/password", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  credentials: "include",
  body: JSON.stringify({"password":"hunter2"}),
});

Request bodyrequired

application/json

SudoPasswordRequest

object

Request body for `POST /api/auth/sudo/password`. The endpoint requires an authenticated session (NOT sudo — this is how the user *acquires* sudo) and re-verifies the account password before stamping `sessions.sudo_until = now() + 5min`. On wrong password OR an account with no `password_hash` (OAuth- only / passkey-only) the response is `401 invalid_credentials` — the route refuses to distinguish "wrong endpoint" from "wrong password" so the response can't be used to fingerprint which credentials an account has.

passwordrequired

string

example"hunter2"

additional propertiesnot allowed

Responses

200Sudo granted; window expires at `sudo_until`

application/json

SudoPasswordResponse

object

sudo_untilrequired

integerint64

Millis-since-epoch when the sudo window expires. The SPA can surface a countdown or just rely on retrying the original request — a fresh 403 means sudo has lapsed.

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bearer-token caller has no session to grant sudo on
  • 401Authentication required
  • 429Rate limited — retry after the `Retry-After` header
  • 500Internal server error
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget