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
| Member | Admin | Owner | |
|---|---|---|---|
| Clients, contacts and links: add and edit | Yes | Yes | Yes |
| Projects: create and edit | Yes (projects they can see) | Yes | Yes |
| Delete clients and projects | Yes | Yes | |
| Add or remove a project's team members, set bill rates | Yes | Yes | |
| Create a confidential project, or mark one confidential | Yes | Yes | |
| See confidential projects | Only ones they're on | All | All |
| Tasks (add, edit, assign, delete) on projects they can see, comments, own time entries and timers | Yes | Yes | Yes |
| Edit or delete other people's task comments | Yes | Yes | |
| Log expenses | Yes (need approval above the org's threshold) | Yes (auto-approved) | Yes (auto-approved) |
| Approve or reject expenses | Yes | Yes | |
| See the whole team's time, log time for others, approve timesheets | Yes | Yes | |
| Add, edit, complete, reopen and delete milestones | Yes | Yes | |
| See invoices | All except ones with a line on a confidential project they're not on | All | All |
| Generate draft invoices, edit line items | Yes | Yes | Yes |
| Send invoices (Email to client, Mark as sent), Mark as paid, Void, delete a draft invoice, push to QuickBooks | Yes | Yes | |
| Client and project share links, retainers, billing cycles | Yes | Yes | |
| Reports, Settings → Alerts, Settings → Audit log | Yes | Yes | |
| Change settings under General, Payments, Security, Members | View only | Yes | Yes |
| Connect Stripe, Mercury, QuickBooks, Linear; set up filing | Yes | Yes | |
| Invite people, change roles, set default bill rates and cost rates, remove people (not owners; see The owner) | Yes | Yes | |
| 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 off | Yes | ||
| Keep password sign-in when SSO is required | Yes | ||
| Create their own API keys | Yes | Yes | Yes |
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.
Open Members
Go to Settings → Members and click Invite member.
Enter their email and role
Type their email address, pick Member or Admin under Role, and click Create invite.
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.
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.
- Go to Settings → Members.
- 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
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.
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.
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.
Create a reset link for someone
Who can do it: Owner, Admin (admins can't do it for owners).
Open the menu
Go to Settings → Members and open the ⋯ menu next to the person.
Create the link
Click Create password reset link.
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.
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.
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.
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.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
Copy the redirect URI
Open Settings → Security on the address people will sign in from (for example
https://time.example.com, notlocalhost). In the Single sign-on (OIDC) card, click Copy next to Redirect URI. It looks likehttps://time.example.com/api/sso/callback.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.
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.
- Button label: the name on the login button, such as
Connect
Click Connect. Consultainer fetches
<issuer>/.well-known/openid-configurationto find the provider's endpoints. If that fails, you'll see an error and nothing is saved.Test it
In a private browser window, open the login page, click Sign in with …, and sign in as a test user.
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
Open Google Cloud console
Go to console.cloud.google.com with a Workspace admin account and create or pick a project.
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.
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.
Copy the values
- Issuer URL:
https://accounts.google.com - Client ID and Client secret: from the dialog Google shows after creating the client.
- Issuer URL:
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
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.
Note the IDs
On the app's Overview, copy the Application (client) ID and the Directory (tenant) ID.
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.
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.
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.
- Issuer URL:
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
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.
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.
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 examplehttps://your-org.okta.com/oauth2/default). - Client ID and Client secret: on the app's General tab under Client Credentials.
- Issuer URL: your Okta domain, for example
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 see | What to do |
|---|---|
| Must start with https:// (http:// only for localhost). under Issuer URL | Use 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 mismatch | Register 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
Start
Go to Profile, find Two-factor authentication, and click Enable 2FA.
Add it to your authenticator app
Click Open in authenticator app, or type the Manual entry key into 1Password, Authy, Google Authenticator or similar.
Confirm
Enter the 6-digit code the app shows and click Verify and enable.
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-in | Asks for the authenticator code? |
|---|---|
| Email and password | Yes, on the login form. |
| Emailed login link | Yes, after you open the link. |
| Continue with Google | Yes. After Google, you land on a page that asks for the code; you aren't signed in until you enter it. |
| Passkey | No. A passkey sign-in needs your device's fingerprint, face or PIN, which is already a second factor. |
| Organization SSO | No. Your identity provider handles the second factor. |
Continue with Google with two-factor on
Sign in with Google
On the login page click Continue with Google and pick your account.
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.
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.
Turn it on for the organization
Go to Settings → Security. In the Two-factor authentication card, tick Require two-factor authentication and click Save.
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.
Name the key
Go to Profile → API keys & AI agents, enter a New key name (for example
Claude Desktop), and click Create key.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
| Where | What |
|---|---|
| Settings → Security → Domain | Organization domain and Google auto-join. |
| Settings → Security → Two-factor authentication | Require 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 verification | Require client contacts to verify their email with a code before client links open (owners and admins). See Email verification. |
| Settings → Members | Roles, contractor flag, default bill rates, cost rates, invites, password reset links, No 2FA badges. |
| Settings → Audit log | Every change to organization data, and every sign-in. See Alerts & audit log. |
| Settings → Alerts | Which access and security changes reach Slack or email. |
| Profile | Your password, two-factor authentication, passkeys, Sign out other sessions and API keys. |
| Login page → Forgot password? | Email yourself a password reset link. |