Auth (browser session)
The Auth OpenAPI tag covers browser-oriented identity: reading the current Kratos session (or null), checking lightweight provisioning state, and clearing session cookies. These routes are not the same as Authentication (API keys and Authorization: Bearer …).
Callers using only an API key may still invoke GET helpers where the server allows anonymous access; POST /auth/logout and POST /auth/sign-out are meaningful when the HTTP client retains session cookies from a dashboard or hosted login flow.
Operations vs wire routes
Section titled “Operations vs wire routes”| Concern | HTTP | operationId | Notes |
|---|---|---|---|
| Session / identity | GET /auth/whoami | get_auth_whoami | Session JSON or null (200). |
| Session (alias path) | GET /auth/session | get_auth_session | Same payload; public (anonymous allowed). |
| WAF-safe session path | GET /auth/kratos-identity | get_auth_kratos_identity | Same as get_auth_session; avoids some proxies that block session / whoami segments. |
| Provisioning probe | GET /auth/provisioned | get_auth_provisioned | 204 if provisioned, 401 if not (no DB; relies on gateway X-User when provisioned). |
| Clear session cookie | POST /auth/logout | post_auth_logout | 204 — browser logout. |
| Sign out (alternate) | POST /auth/sign-out | post_auth_sign_out | 204. |
Response shapes for the GET introspection endpoints follow the session schema in the API reference (see Auth tag operations).
SDK coverage
Section titled “SDK coverage”| Capability | Python | Rust (openapp_sdk) | Go | TypeScript (AsyncClient) |
|---|---|---|---|---|
whoami / session / kratos_identity | client.auth.whoami() · session() · kratos_identity() | client.auth().whoami() · session() · kratos_identity() | AuthAPI.GetAuthWhoami · GetAuthSession · GetAuthKratosIdentity | Not on façade yet |
| Provisioning probe | client.auth.provisioned() | client.auth().provisioned() | AuthAPI.GetAuthProvisioned | Not on façade yet |
| Logout / sign-out | client.auth.logout() · sign_out() | client.auth().logout() · sign_out() | AuthAPI.PostAuthLogout · PostAuthSignOut | Not on façade yet |
Typical errors
Section titled “Typical errors”401 on get_auth_provisioned when the principal is not provisioned (expected for that probe). Introspection **GET**s return 200 with a JSON null body when there is no session — not an HTTP error. 401 may still appear when using an invalid or revoked API key on clients that attach bearer credentials by default. See Errors & retries.
Examples
Section titled “Examples”Read current session (whoami)
Section titled “Read current session (whoami)”session = await client.auth.whoami()GetAuthWhoami returns (*http.Response, error) — decode JSON from Body when the status is 200 (body may be null when there is no session).
httpResp, err := client.AuthAPI.GetAuthWhoami(ctx).Execute()if err != nil { return err}defer httpResp.Body.Close()use openapp_sdk::Client;
let client = Client::builder() .api_key("https://api.openapp.house/api/v1_openapp_YOUR_SECRET") .build()?;
let session = client.auth().whoami().await?;const session = await fetch("https://app.openapp.house/auth/whoami", { credentials: "include",}).then((r) => r.json() as Promise<unknown | null>);Browser callers rely on the ory_kratos_session cookie set by Kratos and credentials: "include" (CORS must echo the origin). For Node, swap fetch for an undici.Agent + tough-cookie wrapper or pass an explicit Cookie header captured from the login flow — see the cookie-aware section below. The Node façade does not expose /auth/* yet — you can also use Python, Rust sources, Go sources, or call the REST routes from your HTTP stack. Replace with AsyncClient.getAuthWhoami once the Node façade exposes it.
Session alias paths (GET /auth/session, GET /auth/kratos-identity)
Section titled “Session alias paths (GET /auth/session, GET /auth/kratos-identity)”Same session payload as get_auth_whoami — use /auth/session for a path some CDNs cache as public, or /auth/kratos-identity when a WAF blocks whoami / session segments.
via_session = await client.auth.session()via_kratos = await client.auth.kratos_identity()httpResp, err := client.AuthAPI.GetAuthSession(ctx).Execute()if err != nil { return err}defer httpResp.Body.Close()
httpResp2, err := client.AuthAPI.GetAuthKratosIdentity(ctx).Execute()if err != nil { return err}defer httpResp2.Body.Close()use openapp_sdk::Client;
let client = Client::builder() .api_key("https://api.openapp.house/api/v1_openapp_YOUR_SECRET") .build()?;
let via_session = client.auth().session().await?;let via_kratos = client.auth().kratos_identity().await?;const viaSession = await fetch("https://app.openapp.house/auth/session", { credentials: "include",}).then((r) => r.json());
const viaKratos = await fetch( "https://app.openapp.house/auth/kratos-identity", { credentials: "include" },).then((r) => r.json());Identical session payload — pick /auth/session when a CDN treats it as a public, cacheable path, or /auth/kratos-identity when a WAF blocks the session / whoami segments. Replace with AsyncClient alias helpers once the Node façade exposes them.
Provisioning probe
Section titled “Provisioning probe”from openapp_sdk.errors import ApiError
try: await client.auth.provisioned()except ApiError as err: if err.status == 401: ...GetAuthProvisioned returns Execute() error when the server responds 401.
_, httpResp, err := client.AuthAPI.GetAuthProvisioned(ctx).Execute()if err != nil { // inspect httpResp.StatusCode == 401 for "not provisioned" return err}defer httpResp.Body.Close()provisioned returns Err when the server responds 401.
if client.auth().provisioned().await.is_ok() { // provisioned (HTTP 204)}const res = await fetch("https://app.openapp.house/auth/provisioned", { credentials: "include",});
if (res.status === 204) { // Provisioned — gateway already mapped the Kratos identity to an OpenApp user.} else if (res.status === 401) { // Not provisioned — usually a freshly signed-in identity awaiting the first // dashboard hit that triggers provisioning.}This route deliberately returns 204 vs 401 instead of a JSON body — branch on res.status rather than parsing. Replace with AsyncClient.getAuthProvisioned once the Node façade exposes it.
Cookie logout
Section titled “Cookie logout”await client.auth.logout()httpResp, err := client.AuthAPI.PostAuthLogout(ctx).Execute()if err != nil { return err}defer httpResp.Body.Close()client.auth().logout().await?;await fetch("https://app.openapp.house/auth/logout", { method: "POST", credentials: "include",});Browser callers must use the same origin / credential mode as the login flow so the ory_kratos_session + csrf_token_* cookies are echoed and cleared. Node callers should drive the request through the same tough-cookie jar that captured login — see the cookie-aware section below. Replace with AsyncClient.postAuthLogout once the Node façade exposes it.
Alternate sign-out (POST /auth/sign-out)
Section titled “Alternate sign-out (POST /auth/sign-out)”Same 204 empty-body semantics as post_auth_logout — some gateways or frontends wire this path instead of /auth/logout.
await client.auth.sign_out()httpResp, err := client.AuthAPI.PostAuthSignOut(ctx).Execute()if err != nil { return err}defer httpResp.Body.Close()client.auth().sign_out().await?;await fetch("https://app.openapp.house/auth/sign-out", { method: "POST", credentials: "include",});Same 204 semantics as /auth/logout — pick whichever path your gateway exposes. Replace with AsyncClient.postAuthSignOut once the Node façade exposes it.
Cookie-aware HTTP clients (ory_kratos_session, csrf_token_*)
Section titled “Cookie-aware HTTP clients (ory_kratos_session, csrf_token_*)”These routes resolve identity from the ory_kratos_session browser cookie that Oathkeeper / Kratos issues at the end of a login flow. The default SDK transports are tuned for API key (bearer) workflows and do not persist a per-call cookie jar across requests, so you have a few options when calling /auth/* from server-side code:
- Run a real browser flow once (or proxy the user’s browser) and forward the
Cookie:header verbatim into a one-shot SDK call. - Build a cookie-aware HTTP client (Python
httpx.AsyncClient(cookies=jar), Rustreqwest::Client::builder().cookie_store(true), Gohttp.Client{Jar: jar}, TSfetch(..., { credentials: "include" })in the browser) and drive Kratos directly, then use the resulting cookie for/auth/whoami,/auth/logout, etc. - Skip the browser session entirely and use API keys (Authentication) for non-interactive workflows — that is what most SDK callers should be doing.
Kratos issues a fresh csrf_token_<hex> cookie per flow (login, recovery, verification, settings). When you POST a flow back to Kratos you must echo the flow’s JSON csrf_token and keep its matching cookie in the same jar — otherwise Kratos returns security_csrf_violation. POST /auth/logout here clears the active ory_kratos_session cookie and any stale csrf_token_* cookies it sees in the request (host-only and Domain= variants), so a successful logout response always carries multiple Set-Cookie lines you should let your jar absorb.
import httpx
cookies = httpx.Cookies()async with httpx.AsyncClient( base_url="https://app.openapp.house", cookies=cookies, follow_redirects=False,) as http: pass
session = await client.auth.whoami()The internal httpx.AsyncClient already carries cookies across calls; reuse the same client for the Kratos self-service flow + /auth/whoami so that the ory_kratos_session cookie set by Kratos is presented automatically.
import ( "net/http" "net/http/cookiejar"
openapiclient "github.com/tomers/openapp-sdk/go")
jar, _ := cookiejar.New(nil)cfg := openapiclient.NewConfiguration()cfg.HTTPClient = &http.Client{Jar: jar}cfg.Servers = openapiclient.ServerConfigurations{{URL: "https://app.openapp.house"}}client := openapiclient.NewAPIClient(cfg)
httpResp, err := client.AuthAPI.PostAuthLogout(ctx).Execute()if err != nil { return err}defer httpResp.Body.Close()The cookie jar absorbs Set-Cookie lines from /auth/logout so subsequent /auth/whoami calls observe the cleared session. To send an existing ory_kratos_session cookie from a non-browser context, jar.SetCookies(u, []*http.Cookie{ ... }) before issuing the request.
use openapp_sdk::{Client, transport::RequestSpec};use reqwest::Method;use serde_json::Value;
let client = Client::builder() .api_key("https://api.openapp.house/api/v1_openapp_YOUR_SECRET") .build()?;
let session: Value = client .transport() .request_json(RequestSpec { method: Method::GET, path: "/auth/whoami", extra_headers: &[("Cookie", "ory_kratos_session=…".to_string())], ..Default::default() }) .await?;The SDK’s transport does not enable reqwest’s cookies feature, so per-request cookie state is your responsibility. For round-trip flows, build a separate reqwest::Client::builder().cookie_store(true).build()? and issue the Kratos self-service requests against it — then forward the resulting Cookie: header into extra_headers on the SDK call.
const session = await fetch("https://app.openapp.house/auth/whoami", { credentials: "include",}).then((r) => r.json());In Node use tough-cookie + a fetch wrapper (or undici with a custom Dispatcher) that persists set-cookie across requests; in the browser, credentials: "include" is enough as long as CORS is configured.
Login itself: continue_with and where these endpoints stop
Section titled “Login itself: continue_with and where these endpoints stop”The Auth tag is introspection-only. Actually obtaining an ory_kratos_session cookie requires driving Kratos’s self-service public API (e.g. POST /self-service/login) — that is not part of OpenApp’s OpenAPI surface, so you call Kratos directly. A typical sequence:
GET /self-service/login/browser(or/api) on the Kratos public URL → response carries a flow id, the JSONcsrf_token, and oneSet-Cookie: csrf_token_<hex>=….POST /self-service/login?flow=<id>with the user identifier + password and thecsrf_tokenin the JSON body, sending thecsrf_token_<hex>cookie back.- Successful flows return either
session+session_tokendirectly (/apiflow) or acontinue_witharray — entries likecontinue_with[].action == "set_ory_session_token"or"show_verification_ui"tell the client what to do next (set the cookie, push to verification, etc.). Browser flows mostly redirect; API flows expect the caller to interpretcontinue_withthemselves. - Once the cookie jar holds
ory_kratos_session,GET /auth/whoami(or/auth/session//auth/kratos-identity) returns the resolved session JSON;GET /auth/provisionedreturns 204 if the gateway has provisioned an OpenApp user for the Kratos identity.
For non-interactive backends, prefer API keys (Authentication). Reach for the cookie-and-Kratos path only when you genuinely need to act as a specific human user (impersonation, support tooling, headless dashboard tests) — and even then, mint a short-lived API key on behalf of that user when you can.