# Isolation & access

Fleetlane separates customers at the database level, admits only invited users through its own sign-in screens backed by WorkOS, and applies every permission on the server. This page describes each layer, from the database outwards.

## Each customer has its own database

The checked-in staging configuration uses a dedicated database and runtime role for each tenant. Fleetlane also supports schema topology in explicitly configured environments. Confirm the deployed topology with your operator.

- Each customer database has its own database role, which the application uses to reach that customer's data.
- General connection rights are removed from each customer database. Only that customer's roles are granted access.

The database topology is designed to restrict each tenant runtime connection to its registered target. Operators must verify the deployed roles and grants; application source alone does not prove the live database configuration.

## Your address identifies your data

Each customer reaches Fleetlane on its own web address. The address of every incoming request is matched against a registry of known addresses to decide which customer's data the request concerns.

- Browser requests select their tenant through the registered host, without an `x-tenant-id` fallback. Inbound lifecycle callbacks have a separate authenticated path-tenant contract.
- A request to an address that is not registered is rejected, and no customer data is served.
- Customers that are inactive or not fully set up are not served.

```mermaid
flowchart LR
  B["Browser or assistant"] -->|customer web address| T{"Address registered,<br/>customer active?"}
  T -->|no| X["Rejected"]
  T -->|yes| A{"User invited<br/>to this customer?"}
  A -->|no| X
  A -->|yes| P["Permissions, scope<br/>and field rules"]
  P --> DB[("Customer database<br/>own role")]
  P --> FS[("Customer files<br/>signed links")]
```

## Lanes inside your workspace

Your workspace has a production lane for live work and can have test lanes for trying configuration changes. Each lane keeps its own vehicles, claims, dealers, partners and connected systems; records in a test lane are never shown in production, and the reverse. The lane a request runs in is decided on the server: a person needs the Work in lanes permission and a role in that lane, and an API key works only in the lane it was created in. A test lane is never paired with the production lifecycle engine. See [Lanes](https://docs.fleetlane.app/functionalities/lanes/).

## Own sign-in screens, invite-only

Fleetlane signs people in on its own screens at the workspace address, with
WorkOS handling the identity behind them: password, email code, verification,
recovery and, where an organisation has it configured, enterprise Microsoft
sign-in through an Entra connection. There is no social sign-in and no public
signup. See [sign-in and workspace access](https://docs.fleetlane.app/security/sign-in-and-access/) for
invitations, recovery and the shared identity model.

One identity can be reused between Fleetlane and its lifecycle engine within
the same provider environment. Each workspace still has its own organisation
membership, local account and permissions. Browser sessions remain bound to
their application and host.

Signing in does not grant access by itself. After authentication, Fleetlane looks the person up among the users invited to that customer. Someone who authenticates successfully but has not been invited is turned away before any data is loaded. Accounts can also be disabled, which blocks sign-in in the same way.

## Role-based permissions

What a user can do is defined by the roles assigned to them. Roles carry permissions such as viewing claims, editing claims, or managing configuration. Every request is checked against these permissions on the server.

For each claim and vehicle, the server works out that user's access and sends the result along with the data. The browser displays that decision. It never calculates access itself, and a decision sent back from the browser is never trusted.

## Dealers reach only their own dealership

Role assignments can be scoped to one or more dealerships. A head office user can hold a permission across the whole organisation. A dealer user holds it only for their own dealership.

This scope is applied inside the database query itself. Claims from other dealerships are not fetched and then hidden; they are never read. A user whose assignment covers no dealerships sees no claims under that permission.

## Hidden fields are removed on the server

Field rules can make individual fields, or whole sections, editable, required, locked or hidden, depending on role, status and claim type. See [Access & field control](https://docs.fleetlane.app/functionalities/access-field-control/) for how these are configured.

When a field is hidden for a user, its value is removed from the response on the server before anything is sent. It does not reach the browser, so it cannot be recovered with developer tools. Users also cannot filter or sort lists by a field that is hidden from them, which prevents a hidden value from being inferred through search.

## Credentials for your systems are encrypted

When Fleetlane connects to your other systems, the connection details and credentials for each system are stored encrypted with AES-256-GCM. Fleetlane will not start in production without its encryption key configured, so these credentials cannot be stored in plain text.

## API keys

Machine access uses API keys, which are designed so that a leaked database copy does not expose working keys.

| Property         | How it works                                                                              |
| ---------------- | ----------------------------------------------------------------------------------------- |
| Stored as a hash | Only a SHA-256 hash of the key is kept. The full key is shown once, when it is created.   |
| Masked           | Afterwards, only a short prefix is displayed to identify the key.                         |
| Scoped           | Each key carries explicit scopes, and requests outside those scopes are refused.          |
| Expiring         | A key can be given an expiry date, after which it stops working.                          |
| Revocable        | A key can be revoked at any time, with the reason and the person who revoked it recorded. |

Test keys and live keys carry different prefixes, so they cannot be confused.

Source review: 1 October 2026, based on tenant database composition, request
context, authorization, API-key and webhook code. Deployed grants and sign-in
configuration were not inspected.
