CONNECT

Connect with Tesska (OAuth)

Integrate your app with Tesska over standard OAuth 2.0: the authorization-code flow with mandatory PKCE (S256). One click on the consent page gives your app a per-user, revocable, scoped token — your code never touches a password.

Overview

Connect Tesska is the standard way for third-party apps to act on behalf of a Tesska user. You redirect the user to our consent page; once they approve, you exchange the authorization code for an access_token — a per-user, revocable, scoped key you can use as a Bearer token against every /v1/* endpoint. Available scopes:

  • broker:login — call credentials the user has granted (exchanged for short-lived tokens; never sees a password)
  • grants:read — list which accesses the user has granted
  • approvals:read — view pending approval requests (metadata only)
  • approvals:write — submit approval decisions on the user's behalf (deny only; approving still happens on the user's own device)

Register a developer app

Register your client self-serve in the console under “Developer apps”: pick a name and register one or more redirect URIs (matched exactly at exchange time).

  • The client_secret is shown exactly once, at creation — store it securely right away.
  • Confidential clients (server-side apps) authenticate with client_secret; public clients (SPAs, mobile) omit it and rely on mandatory PKCE.
  • Unknown client_ids and unregistered redirect URIs are stopped before the consent page — the redirect is never performed (open-redirect protection).

Step 1 — Send the user to /oauth/authorize

Generate a PKCE pair, then redirect the user to GET /oauth/authorize. They see a consent page with your app name and the requested scopes; on approval, we redirect back to your redirect_uri with ?code=…&state=….

  • response_type=code — fixed
  • scope — space-separated; must stay within the scopes your app registered
  • state — random string, echoed back on the redirect; use it to prevent CSRF
  • code_challenge_method must be S256 — plain is always rejected; code_verifier must be 43–128 characters (RFC 7636)
# 1) Generate a PKCE pair code_verifier = base64url(random_bytes(32)) # 43-128 chars code_challenge = base64url(sha256(code_verifier)) # 2) Redirect the user to the consent page https://tesska.com/oauth/authorize ?response_type=code &client_id=YOUR_CLIENT_ID &redirect_uri=https://app.example.com/callback &scope=broker:login%20grants:read &state=RANDOM_STATE &code_challenge=CODE_CHALLENGE &code_challenge_method=S256

Step 2 — Exchange the code for a token

From your server, POST the code to /oauth/token. Authorization codes are single-use and expire after 5 minutes. Client credentials can go in the form body or in an HTTP Basic header.

  • invalid_client — client authentication failed
  • invalid_grant — code expired or already used, redirect_uri mismatch, or PKCE verification failed
  • unsupported_grant_type — grant_type must be authorization_code
curl -X POST https://tesska.com/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d grant_type=authorization_code \ -d code=AUTH_CODE_FROM_CALLBACK \ -d code_verifier=CODE_VERIFIER \ -d redirect_uri=https://app.example.com/callback \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=YOUR_CLIENT_SECRET # confidential clients only # 200 OK { "access_token": "...", "token_type": "Bearer", "expires_in": 31536000, "scope": "broker:login grants:read" }

Step 3 — Call the API as the user

The access_token is a scoped key bound to (your app × this user). Use it as a Bearer token on any /v1/* endpoint: POST /v1/login to broker short-lived access, GET /v1/grants to list available grants, GET /v1/approvals/:id to poll approval results.

curl https://tesska.com/v1/grants \ -H "Authorization: Bearer ACCESS_TOKEN"

Your app never sees a password.The token is a revocable, scoped key — original secrets stay in the user's vault. Approval-mode (B) credentials still require the owner to approve each use on their phone, with end-to-end encrypted delivery.

Revocation and safe defaults

  • Tokens are issued per user × app; revoking one connection never affects another.
  • Users can revoke your app any time under “Connected apps” — revocation takes effect immediately.
  • Re-authorizing the same app invalidates the previously issued token.
  • A new connection starts with zero credential access: the user still has to explicitly grant specific vault credentials to it.
  • Every token issuance and API call is audited (metadata only, never plaintext).

Official SDKPlanned

There is no official SDK yet. The whole flow is just two HTTPS requests — any HTTP client (curl, fetch, requests) plus the examples on this page is enough. We'll update this page when the SDK ships.