Skip to content

How sign-in works

How a client hands an already-authenticated member into Doshi with no second login and no shared secrets.

Your app has already authenticated your customer. When they open Doshi inside your app, they should not be asked to log in again.

This standard, jwt_sso, is how that happens for the iframe, the SDK and a webview. Your backend signs a short-lived assertion with a key only you hold, swaps it server-to-server for a short-lived member token, and your page hands that token to Doshi. There is no shared secret anywhere, and your signing key never reaches a browser.

Integrating is one to two days of backend work: add a key in your console, sign a JWT, call one endpoint. The hosted link needs none of it, because members sign in to Doshi there.

The silent-login round tripYour page asks your backend for a coach token. Your backend signs a 60-second assertion and sends it to the Doshi exchange, which verifies it against the key in your console and returns a 15-minute member token. Your backend passes that token back to your page, which hands it to the embed. The numbered steps below the figure describe the same flow in full.1 "I need a coach token"2 assertion, 60 s3 member token, 15 min4 getToken() resolvesYour pagethe embed lives hereYour backendholds your private keyDoshi exchangechecks your key
Your side in grey, Doshi in purple. The assertion never transits a browser.
  1. You add a signing key in your Doshi console. By default the console generates it in your browser and keeps the public half; or you bring your own, as a public key or a JWKS URL. You rotate keys on your own schedule; we never hold your private key.
  2. Your backend signs an assertion — a JWT naming your issuer, your own stable customer id, and the token exchange endpoint. See The assertion and Sign an assertion.
  3. Your backend calls the token exchange, which verifies the assertion against your key, finds or creates the member, and returns a member token. See The token exchange.
  4. Your page answers Doshi’s token requests from your backend. Doshi caches and renews on its own — see Hand over the token.

The assertion never transits a browser. Step 3 is backend-to-backend, and that is what lets the whole standard work with no replay defence and no second credential in the page.

  • A backend that can hold a private key and sign a JWT. Any language; the signing snippet is TypeScript.
  • Access to your console, where you add your key and your pages’ origins and copy your iss, your aud, the key’s kid and your client slug. See Getting access.

There is no second login, no refresh token, no session API and no logout call — logging out means removing Doshi from your page. The reasoning behind the things we left out is published in What we deliberately don’t do.