Skip to content
Coritan Docs

Sign in to the staff console

Sign in to the staff console with your organization account, use two-factor authentication, remember a browser, confirm risky actions and end your sessions.

View as Markdown

Your team signs in to the staff console on your storefront domain, at /staff/login, with the email and password of their Coritan account. The sign-in gives a console session for one organization, which carries the member's role and works until they sign out or it expires. Set up two-factor authentication here too, let a browser you trust skip the code, and learn the check the console makes before actions that move money or end things.

  • You need to be a member of the organization. Manage members and roles explains how an owner or admin adds you.
  • If you were invited, set your password first from the invitation email. Its link opens /staff/reset-password on your storefront domain and works for 2 hours.
  • Keep an authenticator app to hand if your organization requires two-factor authentication.
  1. Open /staff/login on your storefront domain, for example https://example.com/staff/login. The page is titled "Staff sign-in".
  2. Enter your email and password, and complete the challenge if the form shows one. Then choose "Sign in".
  3. If you use two-factor authentication, the page asks "Enter your code". Enter the 6-digit code from your authenticator app. Without your phone, enter one of your recovery codes in the same field. The code step waits 5 minutes; "Start over" begins again.
  4. To skip the code the next time you sign in from this browser, tick "Remember this browser" before you choose "Continue". Remember this browser explains it.
  5. If your organization requires two-factor authentication and you have not set it up, the console asks you to do it now, as in Set up two-factor authentication. You have 30 minutes, and the console opens once the first code is confirmed.

A wrong code clears the field so you can try again. The page links to "Forgot password" and to the customer sign-in.

The same sign-in opens the storefront as your own customer account, when you have one. Change a member's storefront account says which account that is.

Set up two-factor authentication

Section titled Set up two-factor authentication

With two-factor authentication on, you sign in with your password and a code from an authenticator app.

  1. Open My account (/staff/me) and choose "Security". The "Two-factor" panel says "Not set up yet".
  2. Choose "Set up two-factor…". The console shows a QR code. Scan it with your authenticator app, or choose "Show the setup key" and type the key in.
  3. Enter the 6-digit code from the app and choose "Turn on two-factor".
  4. Save the 10 recovery codes. The console shows them once, under "Shown once". Choose "Copy codes" or "Download codes". Each code signs you in once when your phone is not to hand.

Important

Keep the recovery codes somewhere other than your phone. Without the app and without a code, only an admin can reset your second factor, and the owner's cannot be reset from the console at all.

Once two-factor authentication is on, the panel shows "Since" and how many of the 10 "Recovery codes left" you have. To make new recovery codes, choose "New recovery codes…", enter a current code and choose "Make new codes"; the old set stops working at once. To turn two-factor authentication off, choose "Turn off…", enter your password and a current code, and choose "Turn off two-factor". Signing in then needs the password alone, and the step-up asks for your password instead of a code. You cannot turn it off while your organization requires it of every member: the button stays off. Ask an admin to reset it, then set it up again.

A browser that you remember skips the code at your next sign-ins, for as many days as your organization allows. It is for a computer or phone that only you use. The password is still asked every time.

  • Two-factor authentication must be on for your account. Remembering a browser stands in for the code, so without a code there is nothing to skip.
  • Your organization must remember browsers. An admin sets the number of days under Team, in the "Sign-in policy" panel, as Choose how long a browser is remembered explains. With "Never", the box is not on the code step.
  1. Sign in with your email and password. When the page asks "Enter your code", enter the code.
  2. Tick "Remember this browser for 30 days" under the code. The number of days is your organization's setting.
  3. Choose "Continue". The toast says "Signed in to staff · remembered browser" the next time you sign in from this browser without a code.

The same box is on the "Set up two-factor" step, when your organization makes you set up two-factor authentication at sign-in.

What a remembered browser changes

Section titled What a remembered browser changes
  • The next sign-in from it asks for your email and password only, and goes straight to the console. If the console cannot use the remembered browser, because it expired or you forgot it, it asks for the code as usual and you can remember the browser again.
  • A sign-in that skipped the code is not a step-up. The first action that moves money or ends something asks you for a code, as Confirm it is you explains.
  • A remembered browser belongs to you and to this organization, and is not tied to a network address.
  • You can remember up to 10 browsers. Remembering another forgets the oldest.

A browser stops skipping the code when any of these happens:

  • More days have passed since you remembered it than the organization allows. A shorter setting also shortens the browsers already remembered, and "Never" ends them all.
  • You forget it.
  • An admin signs you out everywhere, or resets your two-factor authentication.
  • Your password changes, or you turn two-factor authentication off or set it up again.

To forget one yourself, open My account (/staff/me), choose "Security" and find the "Remembered browsers" panel. It lists each browser with when it was remembered, when it was last used and when it expires, and marks the one you are on with "This browser".

  1. Choose "Forget…" on the browser's row, then "Forget browser" to confirm. To forget every browser, choose "Forget all…", which shows once you have two or more, then "Forget all".
  2. The forgotten browser asks for a code at its next sign-in. Its signed-in session stays.

Some actions ask you to confirm it is you, even though you are signed in. This check is a step-up: enter a code from your authenticator, or your password if you have no two-factor authentication. It lasts 10 minutes, and signing in counts as one, so the first 10 minutes after you sign in need no extra check. A sign-in from a remembered browser skips the code, so it does not count, and the first of these actions asks for a code.

The console opens a dialog titled "Confirm it is you" on top of whatever you were doing. With two-factor authentication on, it asks for a code and the button reads "Confirm with code". Without it, it asks for your password and the button reads "Confirm with password". Once you confirm, the console repeats the action you asked for.

These actions ask for it:

  • Customers: adding or taking away credit, resetting a password or second factor, changing an account's status, closing an account, exporting its data, and opening a support session that can make changes.
  • Billing: charging, refunding or marking an invoice paid, cancelling an unpaid invoice, deciding a refund request and terminating a service.
  • Servers: restoring or deleting a backup or snapshot, deleting a database or reading its password, and changing the startup settings.
  • Bulk actions that terminate, ban or schedule a deletion, on customers or on servers.
  • The team: changing a role, removing a member, signing them out, resetting their password or second factor, and changing their storefront account.

Only a console session has a step-up. A coritan.com access token reaches the same staff routes, but these actions refuse it, so do them signed in to the console.

  1. On the sign-in page, choose "Forgot password". The page "Reset your password" opens at /staff/forgot-password. Enter your email and choose "Send link".
  2. Open the link in the email within 2 hours. It opens "Set a new password" at /staff/reset-password on your storefront domain.
  3. Enter a "New password". It needs 8 to 128 characters, with a lowercase letter, an uppercase letter, a digit and a special character. Choose "Save password".

Setting the password signs you out of every console session, and the console sends you back to the sign-in page, so sign in again with it.

Signing out ends the console session and every storefront session it opened for you. The sign-out button is at the foot of the sidebar.

To end a session on another device, open My account (/staff/me), choose "Security" and find the "Sessions" panel. Each session shows when it was signed in, its client, where it signed in from and when it expires, and the one you are using is marked "This browser". Choose "Sign out…" on a row to end that session, or "Sign out everywhere else…", which shows once you have two or more, to end every session but this one. Ending sessions this way keeps your remembered browsers. When an admin signs you out, or resets your second factor, your remembered browsers are forgotten too.

To change your password, use the "Password" panel in the same place: enter your current password and the new one twice, then choose "Change password". The new password needs at least 8 characters, and changing it signs out every other session you have. It also forgets your remembered browsers.

You are in the console with your role, and the pages you see are the ones that role can use. Organization roles and permissions lists them.

Invalid credentials
The email is not a member of this organization, or the password is wrong. The answer is the same for both.
Set a password from the invite email before signing in
You were invited and have not set a password yet. Follow the invitation link, or ask an admin for a new one.
Account is suspended or closed
Your Coritan account cannot sign in. Contact Coritan support.
That code is not right
The code has expired or was mistyped. Codes change every 30 seconds, so check that your phone's clock is correct.
Finish signing in with your second factor
A session waiting for its code was used on another route. Enter the code first.
Confirm your password or a code from your authenticator to do this.
The action needs a step-up and your last one is more than 10 minutes old. Confirm and try again.
This brand requires two-factor for staff; ask an admin to reset yours instead
You tried to turn two-factor authentication off while your organization requires it.
Too many requests for this action. Try again later.
You tried 10 codes, or 10 step-ups, in 5 minutes. Wait a few minutes before you try again.
The code step has no "Remember this browser" box
Your organization does not remember browsers. An admin can change that in the "Sign-in policy" panel on the Team page.
A remembered browser asks for a code again
It reached the end of its days, or one of the events in Forget a remembered browser happened. Sign in with a code and tick "Remember this browser" again.
Remembering a browser says it needs two-factor authentication
The "Remembered browsers" panel shows this note while two-factor authentication is off. Set it up first, as in Set up two-factor authentication.

The console is built on these routes, under https://api.coritan.com/api/v1/orgs/{org_slug}/staff/auth/. The reference lists them all under Customer Authentication: staff.

Sign in with a password and a code

Section titled Sign in with a password and a code

Send the email and password. When your brand has a Turnstile challenge on its forms, turnstile_token is the answer from that widget, and without it the sign-in answers 403 with turnstile_failed, so a script cannot sign in on its own there.

Shell
curl -X POST https://api.coritan.com/api/v1/orgs/acme/staff/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "alex@example.com", "password": "your-password", "turnstile_token": "the-widget-answer"}'

A member without two-factor authentication gets the session at once:

JSON
{
  "access_token": "ost_...",
  "refresh_token": "ost_...",
  "expires_in": 86400,
  "token_type": "bearer",
  "role": "support_tier2",
  "mfa_required": false,
  "mfa_setup_required": false,
  "staff": {"id": 14, "email": "alex@example.com", "role": "support_tier2"},
  "customer_session": {"access_token": "...", "refresh_token": "...", "customer_id": 812, "customer_email": "alex@example.com"}
}

customer_session is a storefront session for the member's own customer account, or null when they have none. A member with two-factor authentication gets "mfa_required": true and an mfa_token that lasts 300 seconds instead. Send it with the code:

Shell
curl -X POST https://api.coritan.com/api/v1/orgs/acme/staff/auth/mfa/verify \
  -H "Authorization: Bearer $MFA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"code": "492817"}'

The answer is the same session, plus how (totp, or recovery for a recovery code) and recovery_codes_left. When the organization requires two-factor authentication of a member who has none, the sign-in answers "mfa_setup_required": true with an mfa_token that lasts 1800 seconds: use it for the enrolment below, and enable answers with the session under tokens.

After a right code, the member can have the device remembered, so that their next sign-ins from it skip the code. The staff console does this when a member ticks "Remember this browser": it keeps the token in the browser for each email address and sends it with the password at the next sign-in. A console you build does the same with the fields below. Add remember_device to the code step, with a device_label of up to 120 characters that the member will recognise in their list:

Shell
curl -X POST https://api.coritan.com/api/v1/orgs/acme/staff/auth/mfa/verify \
  -H "Authorization: Bearer $MFA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"code": "492817", "remember_device": true, "device_label": "Chrome on macOS"}'

The answer adds trusted_device, with its id, token, expires_at and days. We show the token once and keep only a hash of it. Keep it on the device, and send it with the password at the next sign-in:

Shell
curl -X POST https://api.coritan.com/api/v1/orgs/acme/staff/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "alex@example.com", "password": "your-password", "trusted_device_token": "otd_..."}'

While the device counts, the answer is the session, as for a member without two-factor authentication, with trusted_device holding its id and expires_at. Otherwise the answer is the code step with "trusted_device_rejected": true: drop the token, and remember the device again after the code if the member asks. enable takes remember_device and device_label too, for a member who sets up two-factor authentication while signing in.

Every code step answers remember_device_days, how long your organization remembers a device: 30 unless an admin changed it, and 0 when it remembers none. With 0, remember_device remembers nothing and trusted_device is null. A device stops skipping the code when any of these happens:

  • More days have passed since it was remembered than remember_device_days allows. Fewer days shortens the devices already remembered.
  • The member forgets it, or an admin signs the member out or resets their second factor.
  • The member's password changes, or they turn two-factor authentication off or set it up again.

A session opened with a remembered device has proved no code, so the actions behind a step-up ask for one. We tie a device to the member and the organization, and to no network address: a console that signs in from its own server reaches us from the server's address, not the member's. To hold a device to the member's address, check it in your console before you send the token.

Route What it does
GET /staff/auth/trusted-devices Your remembered devices that still skip the code, newest first, each with id, label, ip_address, user_agent, created_at, last_used_at and expires_at, plus remember_device_days.
DELETE /staff/auth/trusted-devices/{device_id} Forgets one of your devices, so its next sign-in asks for a code.
POST /staff/auth/trusted-devices/forget-all Forgets every device you remembered and answers how many in forgotten. Your sessions stay signed in.

A member keeps at most 10 remembered devices. Remembering another forgets the oldest.

Send the access token as a Bearer token on every staff route. It lasts 24 hours. Before it expires, trade the refresh token, which lasts 30 days, for a new pair; the old pair stops working.

Shell
curl https://api.coritan.com/api/v1/orgs/acme/staff/auth/me \
  -H "Authorization: Bearer $STAFF_TOKEN"

curl -X POST https://api.coritan.com/api/v1/orgs/acme/staff/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh_token": "ost_..."}'

GET me answers the member with their role, email and name, plus org_requires_mfa, reauthed_at (the last step-up) and the storefront account in customer_id and customer_link. A refreshed session has no step-up until you make one. PATCH me with {"name": "Alex Example"} changes your name.

POST /staff/auth/customer-session gives a new storefront session for your own customer account. It answers 409 You have no active customer account on this brand when you have none.

Shell
curl -X POST https://api.coritan.com/api/v1/orgs/acme/staff/auth/reauth \
  -H "Authorization: Bearer $STAFF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"code": "492817"}'

Send code when two-factor authentication is on, and password when it is off. The answer is {"ok": true, "reauthed_at": "...", "how": "totp", "max_age_seconds": 600}. An action that needs a step-up and has none answers:

JSON
{"detail": {"error": "reauth_required", "message": "Confirm your password or a code from your authenticator to do this.", "max_age_seconds": 600}}

with status 403. Each member may try 10 codes in 5 minutes, and make 10 step-ups in 5 minutes.

Turn on two-factor authentication

Section titled Turn on two-factor authentication
  1. POST /staff/auth/mfa/setup answers secret, otpauth_uri and qr_svg for the authenticator app.
  2. POST /staff/auth/mfa/enable with {"code": "492817"} turns it on and answers the 10 recovery_codes, once.

GET /staff/auth/mfa answers enabled, recovery_codes_left and org_requires_mfa. POST /staff/auth/mfa/recovery-codes with a current code makes a new set, and POST /staff/auth/mfa/disable with password and code turns it off.

Route What it does
POST /staff/auth/forgot-password Emails a reset link to email. It answers {"ok": true} whether or not the email is a member, and takes turnstile_token as the sign-in does.
POST /staff/auth/reset-password Sets password from the email's token, and ends every console session of the member.
POST /staff/auth/change-password Sets new_password after checking current_password, and ends your other sessions. It answers sessions_ended.
GET /staff/auth/sessions Your live sessions, newest first and at most 50, each with id, created_at, expires_at, ip_address, user_agent and is_current.
DELETE /staff/auth/sessions/{token_id} Ends one of your sessions.
POST /staff/auth/sessions/revoke-others Ends every session but this one, and answers how many in revoked.
POST /staff/auth/logout Ends this session and the storefront sessions it opened.

API operations on this page

MethodPathWhat it does
POST/api/v1/orgs/{org_slug}/staff/auth/change-passwordChange your own password
POST/api/v1/orgs/{org_slug}/staff/auth/customer-sessionA fresh storefront session for the member's own customer account
POST/api/v1/orgs/{org_slug}/staff/auth/forgot-passwordStaff forgot password
POST/api/v1/orgs/{org_slug}/staff/auth/loginStaff login
POST/api/v1/orgs/{org_slug}/staff/auth/logoutStaff logout
GET/api/v1/orgs/{org_slug}/staff/auth/meStaff me
PATCH/api/v1/orgs/{org_slug}/staff/auth/meStaff patch me
GET/api/v1/orgs/{org_slug}/staff/auth/mfaStaff MFA status
POST/api/v1/orgs/{org_slug}/staff/auth/mfa/disableTurn the factor off: password and a current code, both
POST/api/v1/orgs/{org_slug}/staff/auth/mfa/enableConfirm the code from the freshly scanned secret
POST/api/v1/orgs/{org_slug}/staff/auth/mfa/recovery-codesA new set of recovery codes against a current code; the old set is void
POST/api/v1/orgs/{org_slug}/staff/auth/mfa/setupStart (or restart) enrolment: a fresh secret, the otpauth URI and the QR code for it
POST/api/v1/orgs/{org_slug}/staff/auth/mfa/verifyThe second step of signing in
POST/api/v1/orgs/{org_slug}/staff/auth/reauthProve it is still you
POST/api/v1/orgs/{org_slug}/staff/auth/refreshStaff refresh
POST/api/v1/orgs/{org_slug}/staff/auth/reset-passwordStaff reset password
GET/api/v1/orgs/{org_slug}/staff/auth/sessionsStaff my sessions
POST/api/v1/orgs/{org_slug}/staff/auth/sessions/revoke-othersStaff end other sessions
DELETE/api/v1/orgs/{org_slug}/staff/auth/sessions/{token_id}Staff end my session
GET/api/v1/orgs/{org_slug}/staff/auth/trusted-devicesStaff trusted devices
POST/api/v1/orgs/{org_slug}/staff/auth/trusted-devices/forget-allForget every device you remembered, so each asks for a code at its next sign-in
DELETE/api/v1/orgs/{org_slug}/staff/auth/trusted-devices/{device_id}Forget one of your remembered devices: its next sign-in asks for a code again