Multi-tenant agent observability: one workspace per customer
You build agents and sell them: an agent product, an agency running agents per client, a platform with agent features. Each of your customers needs their telemetry isolated from every other customer’s, and you need to see cost and health per customer. With Rius, you do that by treating each customer as its own workspace: the security and observability boundary for multi-tenant deployments. This guide is the opinionated way to set that up.
TL;DR: Give every customer their own workspace. The workspace is the boundary Rius actually enforces, so isolation, per-customer cost, alerts, and customer-facing visibility all fall out of that one decision.
The mapping
| Your world | In Rius |
|---|---|
| You, the vendor | The organization |
| One of your customers | One workspace |
| The agents you run for that customer | Agents (services) inside the workspace |
| One conversation or task run | A session |
| Your customer’s end users | A user_id span attribute |
Workspace-based tenant isolation
For multi-tenant observability, treat each customer as a separate workspace: the workspace provides the isolation boundary for that customer’s traces, cost, alerts, and support access. This pattern is not a naming convention; it lines up with what the platform enforces:
- Every trace belongs to exactly one workspace, determined by the API key it was sent with. The server derives the workspace from the verified key, never from anything the request claims.
- A leaked key exposes one customer, never the fleet. Keys, MCP agent keys, alert settings, and shared views are all scoped per workspace.
- Per-customer cost needs no tagging discipline. Token and cost rollups are per workspace, so “what does customer X cost us” is the workspace’s own monitoring view, not a query you have to maintain.
There is no limit on the number of workspaces in an organization, so the pattern holds whether you have five customers or five hundred.
When a single workspace is enough
A single workspace can work when customer isolation is not required.
You can identify customers with a customer_id span attribute
(span.set_attribute("customer_id", ...)), but that gives you logical
rather than enforced isolation. Be aware of what else you give up:
attributes are stored and inspectable on traces, but they do not drive
analytics, so there are no per-customer cost or error rollups; and one API
key covers everyone. What each approach gets you:
customer_id attribute | Workspace per customer | |
|---|---|---|
| Identify the customer on a trace | Yes | Yes |
| Isolated API keys | No | Yes |
| Per-customer cost rollups | No | Yes |
| Per-customer alerts | No | Yes |
| Scoped support access | No | Yes |
| Customer-facing trace access | No | Yes |
Teams that start with the attribute and grow tend to migrate to workspaces later, with a mixed history that straddles the cutover. If customers are your business model, start with the workspace pattern.
Onboarding a customer
Repeat this runbook for each new customer. Today the steps are in the console; workspace and key provisioning through the API is planned, and this section will gain the scripted version when it ships.
-
Create the workspace. From the workspace switcher at the top of the sidebar, choose Create new workspace (organization admins only). Name it after the customer.
-
Create its API key in Settings → API keys inside the new workspace. The key is shown once; put it straight into your secret store, keyed by customer.
-
Deploy the customer’s agents with that key. With one deployment per customer, configuration is two environment variables:
export RIUS_API_KEY="gf_..." # this customer's workspace key export RIUS_SERVICE_NAME="support-agent" # the agent, same name across customersUse the same service name for the same agent across customers: the workspace already says whose it is, and keeping names stable lets you compare the same agent’s behavior between customers.
-
Verify the first trace. Run one task and check the workspace’s trace list, the same check as the quickstart.
-
Optional: connect support tooling. Create an MCP agent key in the workspace so a coding agent or support engineer can query exactly that customer’s traces and nothing else.
Routing traces to the right workspace
One key per workspace means your runtime must send each customer’s traces
with that customer’s key. The clean shape is one agent process (or
deployment) per customer: each process calls init() once, the key
arrives by environment variable, and auto-instrumentation works as
documented. If you already isolate customer runtimes for other reasons,
which most agent vendors do, you get trace routing for free.
Serving multiple customers from one shared process is the advanced case, and today it is Python-only:
- The high-level API (
observe, generations, sessions) binds to the process-global client, so it always exports to one workspace. - A scoped client
(
rius.init(api_key=key, set_global=False)) gives you a second export pipeline, but you trace against its raw OpenTelemetry tracer (client.get_tracer()) and auto-instrumentation does not apply to it. - The TypeScript SDK has no scoped-client equivalent: one process, one workspace.
Treat in-process multi-tenancy as the exception, not the architecture. If a shared runtime is unavoidable, run one process per customer behind your scheduler rather than multiplexing keys inside one process; you keep the full SDK surface and your isolation story stays simple.
Operating per customer
With customers as workspaces, the per-workspace surfaces become per-customer surfaces:
- Cost: each workspace’s monitoring view shows spend, cost by model, and token totals for that customer, the input to your own pricing.
- Alerts: alerting is configured per workspace, so detection runs and fires per customer, and acknowledging one customer’s alert never touches another’s.
- Support access: an MCP agent key per workspace scopes any tooling to one customer’s traces.
- Customer-facing visibility: shared views hand a customer a read-only, frozen window of their own traces, optionally failed-only, with an expiry, and without a Rius account. A weekly shared view is a lightweight “here is how your agent behaved” report.
Current limitations of workspace-based multi-tenancy
Stated plainly, so you can plan around it:
- No provisioning API. Workspaces and API keys are created in the console today. The API is planned; until then, onboarding a customer is the manual runbook above.
- No cross-workspace rollup in the console. You see one customer at a time; an organization-level usage view is planned as part of billing. Meanwhile, the MCP server can list your workspaces and fetch each one’s metrics, which is enough to script a weekly all-customers summary.
- No per-customer end-user analytics. A
user_idspan attribute is carried and inspectable per trace, but there are no per-user rollups.
Next steps
- Settings: workspaces, API keys, and shared views in detail.
- Installation and configuration:
init(), environment variables, and scoped clients. - Working with sessions: scoping one conversation or task run.
- MCP server: querying a workspace’s traces from an agent.