Skip to content

Tenancy & isolation

A Workspace is hlix’s tenant boundary. Every piece of your data belongs to exactly one Workspace, and every request is confined to the Workspace it names. Isolation is enforced by the data layer itself, not only by the application code above it, so a bug in a query returns nothing rather than another Workspace’s data.

  • You are reviewing hlix before putting a client’s source code in it.
  • You run several client engagements in one account and need to know what separates them.
  • You invited an external customer to one project and want to know exactly what they can reach.
  • An API call returned 404 for a project you are sure exists, and you want to know why.
  • A hlix account and membership of at least one Workspace
  • For the checks on this page: an API key and your Workspace ID from Developer tools → API keys

A Workspace is the tenant: your agency, your company, the account that owns projects, secrets, agents and billing. It is the only tenant concept hlix has — there is no second grouping above or beside it.

Every record hlix stores for you carries the id of the Workspace it belongs to.

Isolation is applied in two independent places, and either one alone keeps your data separate:

  • In the data layer. Before any query runs, the request is bound to the Workspace it was authorized for. Access rules on every tenant table then make records of any other Workspace invisible to that request. These rules apply to hlix’s own application as well, and every new table must declare an isolation rule before it can ship.
  • In the application. Every query also filters on the Workspace explicitly, and every project-scoped route checks the caller’s access to that project before it does anything.

Every API call names its Workspace with the X-Organization-Id header. If you omit it, hlix falls back to the Workspace your session last made active.

Terminal window
curl -sS "$HLIX_BASE_URL/v1/api/projects" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID"

Expected result: a JSON envelope listing only the projects of that Workspace.

An API key does not carry a tenant. It authenticates the person who created it; membership is re-read from the live member record on every request, so a key can never reach a Workspace its owner has since left.

Two different refusals, and the difference is deliberate.

Naming a Workspace you do not belong to is a 403. The membership check runs before anything reads data:

{"error": "Not a member of this organization"}

Asking for a project you have no grant on is a 404, not a 403 — because a 403 would confirm the project exists. For a client collaborator this is explicit:

{"error": "Project not found"}

For an agency member, a project in another Workspace is simply not visible, so the request finds nothing and answers not-found.

An external customer invited to a project joins your Workspace with the client role, and a second, stricter boundary applies to them beneath the Workspace boundary.

A client sees only the projects explicitly shared with them. Their access is built from their project invitations and from nothing else, and it splits your Workspace’s data into two groups:

Group Behaviour for a client
Project data — the project, its cycles, tasks, messages, agent runs, deployments and packs Visible only for projects shared with them
Agency data — secrets, environments, model preferences, integrations, logs, events, pending requests and skills Not visible at all, and not writable

Belonging to a customer account does not grant project access. Deriving access from it would widen a client’s reach to every project for that customer, including ones nobody shared. The one exception is invoices: a client can read their own customer’s issued invoices, read-only, so they can see what they owe.

The same rule is checked again on every project-scoped API route: no grant is a 404, a grant without steering rights is 403 Read-only access to this project, and project administration is 403 Project administration is restricted to the agency for every client.

Agent conversation history and long-term memory follow the same boundary:

  • Conversation identifiers are derived by hlix from the authorized request, never accepted from a caller.
  • Before a stored conversation reaches a model, hlix confirms that it belongs to the Workspace the request was authorized for, and stops if it does not.
  • Long-term memory is filtered by Workspace on every lookup.

Scheduled maintenance, such as retention pruning and cleanup of finished sandboxes, works across all Workspaces by design. It runs only inside hlix and cannot be reached with any customer credential — no API key, session or role. See Reliability & maintenance.

If isolation does not behave as you expect

Section titled “If isolation does not behave as you expect”
  • {"error": "No active organization"} with 400. You sent no X-Organization-Id header and your session has no active Workspace. Send the header.
  • {"error": "Not a member of this organization"} with 403. The Workspace id is valid but you are not a member of it. Check the ID on the API keys page — an ID copied from a different account produces exactly this.
  • {"error": "Project not found"} with 404 on a project you can see in the dashboard. You are acting as a client collaborator and that project has not been shared with you, or you are using a key belonging to a different account. The 404 is deliberate: it does not confirm whether the project exists.
  • {"error": "Read-only access to this project"} with 403. You are a client collaborator on that project without steering rights. An agency admin grants them per project.
  • {"error": "Project administration is restricted to the agency"} with 403. Project configuration is closed to every client collaborator, with or without steering rights. This is not a setting.
  • A list endpoint returns an empty array where you expected results. The header named a Workspace you are a member of, but the records belong to another one. An empty result is the isolation working, not a failed query.
If you want to… Read
See what each role may actually do Roles & permissions
Read the record of who did what Audit log
Know where the data physically sits Data residency
Understand the sandbox side of isolation The Coding Workspace