Authentication
Ovok signs people in per tenant. Every project on Ovok is a tenant, and a short tenant code names it. A patient signs in to the tenant they belong to; a practitioner signs in once and then chooses which of their tenants to enter. Tokens are issued for one project, so what a user can reach is decided by the project they signed in to.
This section covers tenant authentication: the eight routes under /auth/tenant/. Use them for every new app.
How sign-in works
Sign-in has two steps so that a code stolen in transit cannot be turned into tokens. Your app creates a random code verifier, sends its hash (the code challenge) when it starts, and sends the verifier itself when it finishes. This is PKCE with the S256 method.
Registration returns tokens straight away, so a newly registered user is signed in without a second step.
The eight routes
Each audience has the same four routes under its own path.
| Step | Patient | Practitioner |
|---|---|---|
| Start sign-in | POST /auth/tenant/Patient/login/start | POST /auth/tenant/Practitioner/login/start |
| Verify the second factor | POST /auth/tenant/Patient/login/mfa | POST /auth/tenant/Practitioner/login/mfa |
| Finish sign-in | POST /auth/tenant/Patient/login/token | POST /auth/tenant/Practitioner/login/token |
| Register | POST /auth/tenant/Patient/register | POST /auth/tenant/Practitioner/register |
None of them needs a bearer token. The tenant is named by tenantCode in the body, except for the practitioner login/start and login/mfa steps, which come before a tenant is chosen.
Before you build: what the project needs
Sign-in and registration are controlled by project settings. Most default to on when unset, but registration needs more than a switch, and practitioner registration is off until you turn it on. Set each value deliberately; the project setup page walks through it.
| Flow | Settings it depends on | When unset |
|---|---|---|
| Patient sign-in | PATIENT_LOGIN_ENABLED | On |
| Patient registration | PATIENT_REGISTRATION_ENABLED, plus a default patient AccessPolicy on the project | On, but refused until the AccessPolicy exists |
| Business-email sign-up (optional) | CLINICIAN_INVITE_ON_BUSINESS_EMAIL, DEFAULT_PRACTITIONER_ACCESS_POLICY, PRACTITIONER_APP_URL, PATIENT_APP_URL | Off |
| Practitioner sign-in | PRACTITIONER_LOGIN_ENABLED | On |
| Practitioner registration | PRACTITIONER_REGISTRATION_ENABLED set to true, plus DEFAULT_PRACTITIONER_ACCESS_POLICY | Off |
GET /v1/project/settings reports false for a boolean that was never set, even where the flow behaves as on. See unset settings before you read that response as a switch.
Settings decide whether a flow can run, not what a signed-in user may do. That is the AccessPolicy's job; see settings are not permissions.
Find your tenant code
A tenant code is a short name, such as big-health-company, that your apps send in tenantCode.
- A signed-in user can read the code of their current project with
GET /organizations/code. - A practitioner's
login/startresponse lists thetenantCodeof every project they belong to. - A patient who has forgotten their code can be emailed all of theirs with
POST /organizations/code/email. The route always answers202, so it does not reveal whether the address has an account.
What you get back
A finished sign-in or a registration returns:
| Field | Meaning |
|---|---|
accessToken | Bearer token for API calls. Valid for one hour. |
refreshToken | Token for renewing the session. |
expiresIn | Lifetime of the access token, in seconds. |
project | reference and display of the project the tokens are for. |
profile | reference and display of the Patient or Practitioner who signed in. |
Send the access token as Authorization: Bearer <accessToken>. Renewing a session and signing out are outside this section.
Limits you will meet
Every route here is rate limited per route and per client IP address. Over the limit, the answer is 429.
| Route | Requests per minute |
|---|---|
login/start | 10 |
login/token | 30 |
login/mfa | 5 |
register | 5 |
Every error response from these routes is held back to take at least one second. This slows down guessing; it also means a slow failure is not an outage. Errors share one JSON shape, described in errors and troubleshooting.
Where to go next
- Set up your project: tenant code, settings and AccessPolicies.
- Patient sign-in and practitioner sign-in.
- Patient registration and practitioner registration.
- Errors and troubleshooting.