Consultainer Docs

Core Concepts

Team & security

Roles, invites, cost rates, password resets, single sign-on, two-factor authentication and API keys

Everyone in Consultainer belongs to an organization with one of three roles: Owner, Admin or Member. This page covers what each role can do, how people join, and how to secure sign-in with single sign-on (SSO), two-factor authentication and passkeys.

Roles

MemberAdminOwner
Clients, contacts and links: add and editYesYesYes
Projects: create and editYes (projects they can see)YesYes
Delete clients and projectsYesYes
Add or remove a project's team members, set bill ratesYesYes
Create a confidential project, or mark one confidentialYesYes
See confidential projectsOnly ones they're onAllAll
Tasks (add, edit, assign, delete) on projects they can see, comments, own time entries and timersYesYesYes
Edit or delete other people's task commentsYesYes
Log expensesYes (need approval above the org's threshold)Yes (auto-approved)Yes (auto-approved)
Approve or reject expensesYesYes
See the whole team's time, log time for others, approve timesheetsYesYes
Add, edit, complete, reopen and delete milestonesYesYes
See invoicesAll except ones with a line on a confidential project they're not onAllAll
Generate draft invoices, edit line itemsYesYesYes
Send invoices (Email to client, Mark as sent), Mark as paid, Void, delete a draft invoice, push to QuickBooksYesYes
Client and project share links, retainers, billing cyclesYesYes
Reports, Settings → Alerts, Settings → Audit logYesYes
Change settings under General, Payments, Security, MembersView onlyYesYes
Connect Stripe, Mercury, QuickBooks, Linear; set up filingYesYes
Invite people, change roles, set default bill rates and cost rates, remove people (not owners; see The owner)YesYes
Enter instance-wide integration credentials (Settings → Integrations and Payments credential fields)Yes
Change the Instance URL (Settings → General)Yes
Create a password reset link for someone (see Password resets)Yes (not for owners)Yes
Turn Require two-factor authentication on or offYes
Keep password sign-in when SSO is requiredYes
Create their own API keysYesYesYes

Over the REST API and MCP server a key acts as the person who made it, with their role, with some extra limits: generating invoices (which members can do in the app), emailing invoices, marking invoices sent or paid, voiding them, approving expenses, reading pending timesheets and reading the audit log need an Admin or Owner key. A member's key also never sees the client or project shareToken (the secret in client links).

Client documents have their own access setting: Everyone, Owners & admins, or Specific people. The Owner and whoever uploaded a document can always open it.

The owner

The person who completes /setup becomes the organization's Owner. There is one owner, and the role can't be granted, changed or removed in the app (invites and SSO only create Admins and Members, and Make admin / Make member never grant Owner). The server enforces this too: admins can't change or remove an owner, and an organization's last owner can't be demoted or removed (An organization needs at least one owner.). The owner:

  • always keeps password sign-in, so a broken identity provider can't lock everyone out;
  • receives alert emails when Settings → Alerts has no email list;
  • is the only person who can change instance-wide settings, because they affect every organization on the server.

Invite people

Who can do it: Owner, Admin.

  1. Open Members

    Go to Settings → Members and click Invite member.

  2. Enter their email and role

    Type their email address, pick Member or Admin under Role, and click Create invite.

  3. Get the link to them

    If email is set up, they're emailed an invite. Either way the dialog shows the invite link with a Copy button, so you can send it yourself. The link expires in 14 days.

  4. They accept

    The link opens Join <your organization>. New people set their name and a password (at least 10 characters, with a letter and a number). Someone who already has an account on this server just accepts.

Check it worked: until it's used, the invite is listed under Pending invites on Settings → Members, with a copy button for the link and an × to revoke it. Once accepted, the person appears under Members and owners and admins get a notification.

There's no public sign-up. Besides invites, people can join through SSO with automatic account creation or auto-join by email domain.

Manage members

Who can do it: Owner, Admin. On Settings → Members, open the ⋯ menu next to a person to:

  • Make admin / Make member: change their role.
  • Mark as contractor / Mark as employee: contractors get a Contractor badge. Contractors can be asked to confirm their rate on a project, and Timesheet approval → Contractors (Settings → General) applies only to them.
  • Create password reset link: makes a one-time link for them to choose a new password. See Password resets.
  • Remove: takes them out of the organization. Their time entries and other work stay. Their API keys stop working for this organization.

The owner's row has no menu for admins. Another owner sees just Create password reset link there. Your own row has no menu: change your own password on Profile.

Owners and admins also see a No 2FA badge next to anyone who hasn't set up an authenticator app, so you can ask them to. It turns red while Require two-factor authentication is on. People who have to sign in with SSO don't get the badge.

Default bill rates

Each member row shows a Rate field: what that person bills per hour by default, in your organization's default currency.

  1. Go to Settings → Members.
  2. Type a number in Rate next to the person and press Enter or click away to save.

When someone is added to a project, their rate there starts at this number (you can still change it in the Add team member dialog). Leave it empty to use the organization's Default bill rate (Settings → General), shown greyed out in the empty field; with neither set, people start at 0. Changing it never changes their rate on projects they're already on: use Edit rate on the project for that. Changes trigger the Billing or payment details change alert.

Cost rates

Each member row shows a Cost field: what an hour of that person's time costs you (salary or contractor rate), per hour. Type a number and press Enter or click away to save. Leave it empty if you don't track it.

Default bill rates and cost rates are only shown to owners and admins. Reports use them, together with Overhead (%) from Settings → General, to work out profit per project. They never appear on invoices; what clients pay comes from each person's bill rate on the project.

Password resets

There are two ways to reset a forgotten password: the person asks for an email themselves, or an owner or admin creates a link and emails it or hands it over. Handing it over also works on a server without email.

Reset your own password

  1. Ask for a link

    On the login page, click Forgot password? under the password box, enter your email address, and click Email me a reset link.

  2. Open the email

    You see If an account exists for that email, we've sent a link to reset your password. whether or not there is one. Open the Reset your Consultainer password email and click Choose a new password. The link works once and expires in 1 hour.

  3. Choose a new password

    Enter it twice (at least 10 characters, with a letter and a number) and click Set new password, then Log in.

If the server can't send email, Forgot password? says so and tells you to ask an owner or admin for a link instead.

Who can do it: Owner, Admin (admins can't do it for owners).

  1. Open the menu

    Go to Settings → Members and open the ⋯ menu next to the person.

  2. Create the link

    Click Create password reset link.

  3. Send it to them

    If email is set up, the dialog offers Email it to them and Copy a link instead. Email it to them sends the Reset your Consultainer password email to their address, naming you and your organization, and the dialog shows Emailed a reset link to their address.

    Without email, or after Copy a link instead, the dialog shows the link with a Copy button: send it yourself, by chat or in person.

    Either way the link works once and expires in 24 hours.

If sending fails, the dialog says Couldn't send the email. Copy the link and send it to the person yourself. and shows the link to copy.

Check it worked: Settings → Audit log shows created a password reset link for the person, and later reset their password once they've used it. Both also raise the Access or security settings change alert.

What a reset changes

  • Only the newest link works. Asking for or creating a new link cancels any older unused one.
  • Everyone is signed out. The person's sessions, on every device, end straight away, and unused login links stop working. API keys keep working.
  • Two-factor authentication stays on. A reset never removes the authenticator app or passkeys, so the next password login still asks for a code. Someone who has lost their authenticator too uses a recovery code, or see Self-hosting troubleshooting.
  • SSO still applies. If Require SSO is on, people who have to use SSO get no reset email, and the ⋯ menu has no reset link for them. Reset their password in your identity provider. Owners keep password sign-in, so they can still reset theirs.
  • Limits. One account gets at most 3 reset emails an hour from Forgot password?, and one network address can ask 10 times an hour. Extra requests show the same message but send nothing. The per-address count is kept in memory, so restarting the app resets it; the per-account limit is stored in the database. Links an owner or admin creates don't count towards either.

Change your password and sign out other sessions

Anyone can do this for their own account, on Profile.

  1. Change your password

    In the Password card, enter your Current password, then the new one under New password and Confirm new password (at least 10 characters, with a letter and a number). Click Update password.

  2. Check the notice

    The page shows Password updated. Your other sessions were signed out. You stay signed in where you are.

To sign out everywhere else without changing your password, click Sign out other sessions in the Sessions card and confirm. The page shows Signed out of every other browser and device. You're still signed in here.

Your other sessions are also signed out when you Disable 2FA or remove a passkey. In each case:

  • Other browsers and devices land on the login page with You've been signed out. Log in again to continue. the next time they load a page.
  • API keys keep working. Revoke them under API keys & AI agents if you need to.

Auto-join by email domain

Who can do it: Owner, Admin. This only applies to Continue with Google sign-in, which the owner turns on under Settings → Integrations → Google sign-in (see Self-hosting). For other identity providers use SSO.

  1. Set the organization domain

    Go to Settings → Security. In the Domain card, enter your company's email domain (for example acme.com) under Organization domain. It must match the domain of your own email address, can't be a free email provider, and can't already belong to another organization on the server.

  2. Turn on auto-join

    Tick Auto-join teammates with a matching email domain and click Save changes.

Anyone who signs in with a Google account on that domain and has no account yet joins as a Member, and owners and admins are notified.

Single sign-on (SSO)

Consultainer supports single sign-on with any OpenID Connect (OIDC) provider: Google Workspace, Microsoft Entra ID, Okta, Authentik, Keycloak, Zitadel, Auth0 and others. SAML isn't supported; most providers that offer SAML also offer OIDC.

Who can do it: Owner, Admin. Each organization has one SSO connection.

How it works

  • Once a connection is enabled, the login page shows a Sign in with <Button label> button.
  • Sign-ins are matched to accounts by email address. Someone already in the organization (invited, or the owner) signs in to their existing account.
  • With Create accounts on first sign-in on, anyone your identity provider lets through (and whose email domain is allowed) gets an account the first time, with the role under New accounts join as. Owners and admins are notified. With it off, only people already in the organization can sign in with SSO.
  • With Require SSO on, password, magic-link, passkey and Google sign-in are blocked for everyone in the organization except the owner.
  • Consultainer asks for the scopes openid email profile, uses PKCE and a nonce, and sends the client secret in the token request body (client_secret_post).

Set up SSO

  1. Copy the redirect URI

    Open Settings → Security on the address people will sign in from (for example https://time.example.com, not localhost). In the Single sign-on (OIDC) card, click Copy next to Redirect URI. It looks like https://time.example.com/api/sso/callback.

  2. Create an OIDC app in your identity provider

    Follow the steps for your provider below. You come away with an issuer URL, a client ID and a client secret.

  3. Enter the details in Consultainer

    Back in the Single sign-on (OIDC) card, fill in Issuer URL, Client ID and Client secret. Optionally set:

    • Button label: the name on the login button, such as Okta.
    • Allowed email domains: for example acme.com, acme.co.uk. Leave it blank to accept any verified email the provider returns.
    • Create accounts on first sign-in and New accounts join as.
    • Trust email addresses from this provider: leave off unless sign-in fails with an unverified-email error (see Troubleshooting).
    • Require SSO: leave off until you've tested a sign-in.
  4. Connect

    Click Connect. Consultainer fetches <issuer>/.well-known/openid-configuration to find the provider's endpoints. If that fails, you'll see an error and nothing is saved.

  5. Test it

    In a private browser window, open the login page, click Sign in with …, and sign in as a test user.

  6. Require SSO (optional)

    Once a test sign-in works, click Edit, tick Require SSO, and click Save.

Check it worked: the card shows a summary with a green check next to the issuer, Enabled ticked, and the New users, Domains, Unverified emails and Enforced settings. Untick Enabled to hide the login button without deleting the connection.

Google Workspace

  1. Open Google Cloud console

    Go to console.cloud.google.com with a Workspace admin account and create or pick a project.

  2. Configure the consent screen

    Open APIs & Services → OAuth consent screen (shown as Google Auth Platform in newer consoles). Set the app name and support email, and choose the Internal audience so only users in your Workspace can sign in.

  3. Create the client

    Go to Clients (or APIs & Services → Credentials → Create credentials → OAuth client ID), choose application type Web application, and add the Consultainer redirect URI under Authorized redirect URIs. Click Create.

  4. Copy the values

    • Issuer URL: https://accounts.google.com
    • Client ID and Client secret: from the dialog Google shows after creating the client.

Google's issuer is the same for every Google account, including personal Gmail. Always fill Allowed email domains with your Workspace domain (for example acme.com), especially with Create accounts on first sign-in on.

Microsoft Entra ID

  1. Register an app

    In the Microsoft Entra admin center, go to Identity → Applications → App registrations → New registration. Give it a name, choose Accounts in this organizational directory only, and under Redirect URI pick Web and paste the Consultainer redirect URI. Click Register.

  2. Note the IDs

    On the app's Overview, copy the Application (client) ID and the Directory (tenant) ID.

  3. Create a client secret

    Go to Certificates & secrets → Client secrets → New client secret, pick an expiry, and click Add. Copy the secret's Value (not the Secret ID) straight away; it's only shown once.

  4. Add the email claim

    Go to Token configuration → Add optional claim, choose token type ID, tick email, and click Add. If asked, also tick the option to add the Microsoft Graph email permission. Users need an email address set on their Entra account.

  5. Copy the values

    • Issuer URL: https://login.microsoftonline.com/<Directory (tenant) ID>/v2.0
    • Client ID: the Application (client) ID.
    • Client secret: the secret's Value.

Entra client secrets expire (at most after 24 months). Put a reminder in your calendar to create a new one and paste it in with Edit before the old one expires, or SSO sign-in stops working.

Okta

  1. Create an app integration

    In the Okta Admin Console, go to Applications → Applications → Create App Integration. Choose OIDC - OpenID Connect and Web Application, then click Next.

  2. Configure it

    Name it, keep the Authorization Code grant type, and paste the Consultainer redirect URI into Sign-in redirect URIs. Under Assignments, choose who can use it (for example everyone, or a group). Click Save.

  3. Copy the values

    • Issuer URL: your Okta domain, for example https://your-org.okta.com. If you use a custom authorization server, use its issuer instead (for example https://your-org.okta.com/oauth2/default).
    • Client ID and Client secret: on the app's General tab under Client Credentials.

Okta only lets assigned users sign in, so assignments are where you control access.

Other providers

Create a confidential (server-side) OIDC client with the authorization code flow, the Consultainer redirect URI, and the scopes openid email profile. Use the provider's issuer URL: the address that serves /.well-known/openid-configuration. For Authentik that's the provider's OpenID Configuration Issuer.

The issuer URL must start with https://. Plain http:// is only accepted for a test provider on localhost, 127.0.0.1 or [::1].

SSO troubleshooting

What you seeWhat to do
Must start with https:// (http:// only for localhost). under Issuer URLUse the provider's https:// issuer URL.
Connect fails with Couldn't reach <issuer>/.well-known/openid-configuration. or Couldn't fetch OIDC discovery document (404).The issuer URL is wrong, or the server can't reach the provider. Open that URL in a browser; it should return JSON.
OIDC discovery document is missing required endpoints.The URL isn't an OIDC issuer. Use the provider's issuer, not its login page.
The provider shows a redirect URI mismatchRegister exactly the URI shown in the card. If it starts with http:// behind HTTPS, fix your proxy headers.
Login page: SSO sign-in failed. Try again or contact your admin.The token exchange or ID token check failed; the app log (docker compose logs consultainer-app) has the reason after [sso] Sign-in failed. Common causes: wrong or expired client secret; the provider didn't return an email (Entra: add the email optional claim); the provider requires a different client authentication method than sending the secret in the request body.
Your identity provider marked your email as unverified. …The provider sent email_verified: false. Tick Trust email addresses from this provider only if users can't change their own email in the provider. Authentik 2025.10 and later need this.
Your email domain isn't allowed to sign in with this SSO provider.Add the domain to Allowed email domains, or clear the list.
You don't have an account yet. Ask an admin to invite you.Create accounts on first sign-in is off and the person isn't in the organization. Invite them, or turn it on.
Your organization requires signing in with SSO.Require SSO is on. Use the SSO button. The owner can still sign in with their password.

Two-factor authentication and passkeys

Each person sets these up for their own account, on Profile. Owners can also require two-factor authentication for everyone in the organization.

Turn on two-factor authentication

  1. Start

    Go to Profile, find Two-factor authentication, and click Enable 2FA.

  2. Add it to your authenticator app

    Click Open in authenticator app, or type the Manual entry key into 1Password, Authy, Google Authenticator or similar.

  3. Confirm

    Enter the 6-digit code the app shows and click Verify and enable.

  4. Save your recovery codes

    Copy the recovery codes somewhere safe. Each works once in place of a code, and they're only shown this one time. Click Done.

From then on, signing in with your password, an emailed login link or Continue with Google asks for a code (see Which sign-ins ask for the code).

To turn it off, enter your password under Confirm password and click Disable 2FA. If your account has no password (you only sign in with Google, SSO or a passkey), enter a code from your authenticator app or a recovery code under Authentication code instead. Turning it off signs out your other sessions.

Which sign-ins ask for the code

Sign-inAsks for the authenticator code?
Email and passwordYes, on the login form.
Emailed login linkYes, after you open the link.
Continue with GoogleYes. After Google, you land on a page that asks for the code; you aren't signed in until you enter it.
PasskeyNo. A passkey sign-in needs your device's fingerprint, face or PIN, which is already a second factor.
Organization SSONo. Your identity provider handles the second factor.

Continue with Google with two-factor on

  1. Sign in with Google

    On the login page click Continue with Google and pick your account.

  2. Enter the code

    Consultainer shows Google confirmed your account. Enter the 6-digit code from your authenticator app to finish signing in. Enter the code (or a recovery code) and click Verify.

Nothing is signed in until the code is accepted, so the app, the REST API and the MCP server can't be reached from that step. The code page works once and for 10 minutes, and stops after 5 wrong codes. After that the login page shows That sign-in step expired or had too many wrong codes. Continue with Google again., and the code page itself says This sign-in step expired or had too many wrong codes. Go back to log in and continue with Google again. Wrong codes show Invalid code. Try again.

Require two-factor authentication

Who can do it: Owner.

  1. Turn it on for yourself first

    Set up two-factor authentication on your own Profile (see above). Otherwise saving fails with Set up two-factor authentication on your own Profile first, so turning this on can't lock you out.

  2. Turn it on for the organization

    Go to Settings → Security. In the Two-factor authentication card, tick Require two-factor authentication and click Save.

  3. Chase anyone who hasn't set it up

    The card shows how many people haven't set it up yet. On Settings → Members they have a red No 2FA badge.

What people without an authenticator app see:

  • They can still log in, but every page takes them to Set up two-factor authentication instead. The rest of the app, including its server actions and downloads, stays closed until they click Enable 2FA, confirm a code and save their recovery codes. Done then takes them to the dashboard.
  • If they belong to several organizations and any of them requires two-factor authentication, the requirement applies everywhere.
  • Only an authenticator app counts. Having a passkey doesn't, because password sign-in never asks for one, so someone with only a passkey is asked to add an authenticator app too.
  • People who signed in with the organization's SSO are exempt, because the identity provider handles their second factor. Turn on MFA in your identity provider.
  • API keys keep working. The REST API and MCP server never ask for a second factor. Revoke the key of anyone who shouldn't keep access.

Turning it off lifts the requirement straight away. Turning it on or off raises the Access or security settings change alert.

Passkeys

On Profile, add a passkey to sign in with your device's fingerprint, face or PIN instead of a password. Passkeys are tied to the domain you created them on; if the instance moves to a new domain, add them again. Removing a passkey (the bin icon next to it) also signs out your other sessions.

API keys

Anyone can create API keys for the REST API and the MCP server.

  1. Name the key

    Go to Profile → API keys & AI agents, enter a New key name (for example Claude Desktop), and click Create key.

  2. Copy it

    Click Copy API key. It starts with ch_live_ and is only shown once.

A key acts as you, in the organization you were in when you created it, with your role and project visibility. The list shows each key's first characters, when it was created and when it was last used. Click the bin icon to revoke one. Keys stop working when you're removed from the organization.

Security settings at a glance

WhereWhat
Settings → Security → DomainOrganization domain and Google auto-join.
Settings → Security → Two-factor authenticationRequire two-factor authentication for everyone (owners only).
Settings → Security → Single sign-on (OIDC)SSO connection, automatic accounts, allowed domains, Require SSO.
Settings → Security → Client link verificationRequire client contacts to verify their email with a code before client links open (owners and admins). See Email verification.
Settings → MembersRoles, contractor flag, default bill rates, cost rates, invites, password reset links, No 2FA badges.
Settings → Audit logEvery change to organization data, and every sign-in. See Alerts & audit log.
Settings → AlertsWhich access and security changes reach Slack or email.
ProfileYour password, two-factor authentication, passkeys, Sign out other sessions and API keys.
Login page → Forgot password?Email yourself a password reset link.