Tenants
OpenFlows is designed to serve many teams from a single server. Each team is called a tenant, and tenants are kept strictly separate from one another.
If you only have one team, you still have "a tenant" - you just have one. Think of a tenant as "one project, one team, one repository."
What a tenant is
A tenant is made up of three things bound together:
- A distinct user account on the server, with the workspace fleet that belongs to it.
- A repository binding - the GitHub repository that team works on.
- An orchestrator workspace that runs that team's pipeline.
How isolation is enforced
Tenants are isolated in two independent ways at the same time:
- Identity and access. Each tenant is a separate user with its own access controls. A user allowed into one tenant's control plane cannot reach another tenant's workspaces.
- Coordination state. Every record in the coordination store is namespaced to its tenant. One tenant simply cannot read or collide with another tenant's records, even on shared infrastructure.
These two layers reinforce each other: even if access control were somehow misconfigured, the data itself is still partitioned.
What this means in practice
- Many teams, one server. Run several independent OpenFlows teams sharing the same control plane and coordination store.
- No cross-talk. One team's tickets, workers, and pull requests are invisible to another.
- Simple operations. Administrators manage tenants from the control panel - add a team, list teams, clean up a stuck team, or remove one entirely.
Managing a tenant
From the control panel, an operator can manage the tenants currently running:
| Action | What it does |
|---|---|
| Add | Create a tenant for a repository so its team can start working. |
| List | See the tenants currently running. |
| Clean | Reset a stuck tenant - clear stale or failed work back to the start so the team can take another pass. |
| Remove | Take down a tenant and its fleet entirely. |
Cleanup is an important operational tool. If a tenant's work is wedged and automated recovery has already given up, resetting it back to a clean state is the way to get the loop moving again.