FixControl/Documentation

Admin Guide

Users & identity

Tenants, roles, OIDC sign-on, SCIM 2.0 provisioning, and the platformAdmin flag.

Multi-tenancy

FixControl is multi-tenant. One tenant owns its own issues, agents, knowledge, memory, audit log, and inbox. A user belongs to exactly one tenant. Tenants cannot see each other's data. An admin in tenant A cannot fetch issues from tenant B by hand-crafting an API call — tenant isolation is enforced on every endpoint, with additional database-level guards in strict mode (see Security & audit).

The one exception is the separate platformAdmin flag. It is independent of the regular role and is never set by self-serve signup.

Creating a new tenant

Two paths:

  1. Self-serve signup at /signup. Creates a new tenant, seeds the canonical AI team, creates the first user as admin, signs them in. User lands on /app.
  2. Companies page (platformAdmin only) — create a tenant on behalf of a customer.

Signup disambiguates company names — two independent signups for "Acme" become "Acme" and "Acme (2)", never silently merged.

Roles

Hierarchical (admin > manager > operator):

RoleCan
AdminUser management, agents, codebases, settings, destructive admin actions (with two-person rule).
ManagerAssign issues, approve / reject / apply patches, mutate verification checklists, change retention.
OperatorCreate workspaces, work on assigned items. No approval rights.

Plus the platformAdmin flag. It grants cross-tenant read access (Companies view, audit aggregations) and is only granted by FixControl staff. Self-serve signup never sets it.

Project-scoped authorization

On top of the tenant roles above, access to project-bound data can be scoped per project. The model: a user acts inside a project only through an active project membership carrying a project role.

Project roles

Two system roles are seeded per tenant and cannot be edited:

  • Project Admin — full management of one project: members, roles, settings, and the project-scoped resources.
  • Project Member — read and participate: read project data, draft and request communications, execute workflows, use bound connectors.

You can also create custom roles, either tenant-wide (reusable across projects) or scoped to a single project. Permissions are picked from a fixed catalogue of capability strings (project, customer, communication, workflow, connector, audit, and policy permissions) — there are no free-form permissions.

Membership lifecycle

Every membership has a status (active, suspended, revoked) and an optional validity window (valid from / until) for temporary access. Anything that is not active and inside its window grants nothing — a revoked or expired membership bites immediately.

Deny by default, phased rollout

Enforcement sits behind the tenant-overridable flag PROJECT_AUTHORIZATION_ENABLED (off by default = compatibility mode: existing tenant-level access keeps working, and reliance on the legacy path is logged). With the flag on, project-bound data is deny by default: an operator without an active membership does not see the project — a guessed project id returns a plain 404.

Two things to know as an admin:

  • Tenant admins and managers keep their tenant-wide reach. One central bypass rule lets them through; every bypass on an action path is audited. Operators never bypass — their access runs exclusively through an active membership. A handful of sensitive actions (for example approving external customer communication) demand a real membership even from an admin.
  • Last-admin protection. A role change, suspension, or revoke that would leave a project with zero active members holding member-management rights is refused — a project can never be locked out of its own administration.

Managing members and roles

Member and role management lives on the project page (team access), not under tenant settings — and it is itself gated by project permissions: viewing requires project.members.read, changing requires project.members.manage (held by tenant admins/managers via the bypass, or by members with the Project Admin role). Managers cannot modify their own membership. Adding a member from another tenant is refused outright.

Sign-in methods

MethodSurfaceUsed by
Email + password/loginTenants without an enterprise IdP.
OIDC SSO/login → IdP redirectTenants with an enterprise IdP.

You can run both in parallel during a migration. Configure under Settings → Identity.

OIDC SSO

Configure your IdP in the admin tenant settings:

  1. Go to Settings → Identity → OIDC.
  2. Add a provider with issuer, clientId, clientSecret, redirectUri.
  3. Set allowed email domains (the allowlist).
  4. Choose JIT provisioning if you want new users to be created on first sign-in, with a default role.
  5. Map claims: email, name, optionally groups.

What's enforced at the callback:

  • Issuer match, audience match, nonce match, exp in the future, signed with the algorithm pinned by the JWK.
  • State + PKCE one-shot — replay attempts return 401.
  • Domain allowlist check on the email claim.

If the email matches an existing user, the OIDC sign-in is linked to that user. If JIT is on and the domain is allowed, a new user is provisioned with the configured default role. Otherwise the sign-in is refused.

Today, OIDC links by email. SAML-style external-id-only linking is not supported.

SCIM 2.0 provisioning

If your IdP can push users (Okta, Azure AD, Google Workspace, others), connect via SCIM:

  1. Go to Settings → Identity → SCIM tokens (or Admin → SCIM tokens for platform admins).
  2. Mint a tenant-scoped bearer token. Shown once.
  3. In your IdP, configure the SCIM connector with:

- Endpoint: https://<your-deployment>/api/scim/v2 - Auth: Authorization: Bearer scim_…

  1. Select which Users and Groups to push.

Implemented endpoints:

  • Users GET (paginated, userName eq filter), POST, GET/PATCH/DELETE per id.
  • Groups GET (paginated), POST, GET/PATCH/DELETE per id.
  • ServiceProviderConfig, Schemas, ResourceTypes discovery.

Group → role mapping is manual today. SCIM creates and updates users; you decide how groups map to FixControl roles in the UI. (Auto-mapping is on the roadmap.)

Deprovisioning

When your IdP pushes a user removal (DELETE /scim/v2/Users/{id} or active=false PATCH):

  • The user is soft-deleted.
  • All sessions are revoked.
  • The deprovision event is audited.

Manual deactivation works the same — under Settings → Users, click Deactivate. Users can be re-activated as long as the soft-delete record remains.

Inviting users (without SCIM)

Tenant admin → Settings → UsersCreate user. Name, email, initial password (min. 8 chars), role. The new user is auto-assigned to your tenant — no UI path can place someone in a different tenant.

The Last seen column shows the most recent successful sign-in from the audit log.

Settings — Users
Settings — Users

Admin list pages — DataTable

/settings/users, /settings/audit, the platform-admin Companies list, and the other admin tables all use the canonical operator DataTable. That means:

  • Server-side sort + filter + pagination — large directories paginate cleanly; the URL captures the slice so you can paste a link to "all admins added in the last 7 days" and the colleague sees the same result.
  • Keyboard mapj/k to step rows, / to focus search, Enter to drill into a user/audit entry, [ / ] from a detail page step prev/next under the same filter. See Keyboard & command palette.
  • Bulk selectx toggles, Shift+x ranges, Cmd/Ctrl+A selects the visible page. Bulk Deactivate and bulk Reset password show in the sticky bulk toolbar; destructive actions confirm with the impacted list inline.
  • Saved views — for example Active, Inactive, Admins, or Operators with no recent sign-in; a shared view means the next admin landing on the page picks up the same lens.
  • Audit context/settings/audit benefits most: filter by actor + verb + time range, hit Save view, share the URL.

The admin tables share their keyboard map and command-palette commands with the user-facing operator pages — the same keys do the same things across the whole product.

Companies view

/companies is a platform-admin overview. Per tenant: issue count, agent count, member count, plan, contact mailbox, brand color. Create, edit, delete, or switch tenants. Only platform admins see all tenants — regular admins see only their own.

Security note — deleting a tenant from this view drops agents and cascades to all issues, knowledge, and memory. Irreversible. The action is gated by the two-person rule.

FAQ

Can a user belong to two tenants at once? No. A user lives in a single tenant. Use a second account with a different email if needed.

What happens to issues when I delete a user? Issues remain; only the user record is removed. Assignments to that user become loose references.

How do I make someone a platformAdmin? Not via self-service — contact FixControl support. Intentionally not exposed in the UI.

What if my IdP pushes a SCIM PATCH that adds a user from another tenant to my group? Refused server-side. Cross-tenant group membership is blocked at the SCIM layer.

Can I have both OIDC SSO and password sign-in active? Yes, during a migration. Disable passwords once SSO is fully rolled out.

Anything unclear or wrong?Let us know →

FixControl is a trade name of FixControl B.V. i.o.