Documentation index for AI agents: see /llms.txt. Markdown versions of every page are available at <path>.md or via Accept: text/markdown.
Concepts

Tenant

Every runtime is scoped to exactly one tenant. define_tenant(...) creates the identity serialized into RuntimeSpec; the Rust runtime (flowai-runtime) uses it as the isolation key...

Every runtime is scoped to exactly one tenant. define_tenant(...) creates the identity serialized into RuntimeSpec; the Rust runtime (flowai-runtime) uses it as the isolation key for everything it stores and serves.

from flowai_harness import define_tenant

tenant = define_tenant("acme", "v1")

tenant.model_dump(by_alias=True, mode="json")
# {"resourceId": "acme", "version": "v1"}

Pick a stable resource_id from trusted auth or deployment configuration; do not derive it from a user prompt.

What tenancy isolates

resource_id namespaces everything the runtime persists or guards:

  • Runtime storage — the runtime's KV state (references, plans, pending-approval audit records, caches) is keyed by tenant, so two tenants sharing one store never read each other's entries.
  • References — reference ids are content hashes salted with the tenant, and every resolve checks the stored owner. A handle leaked across tenants resolves to "not found" rather than to another tenant's payload.
  • Plans — plans are stored and loaded per (tenant, plan_id). Cross-tenant loads also return "not found", so the existence of another tenant's plan is never disclosed.
  • Requests — every query is checked against the handle's tenant. There is no per-call tenant override; a mismatched request is rejected.
  • Data-environment scope — if data_environment declares a tenant_id, runtime construction rejects it unless it matches the runtime tenant.

Telemetry and trace events are recorded per runtime handle, and each handle is bound to a single tenant.

What tenancy does not isolate: the topology itself. Agents, prompts, tools, and provider configuration are properties of the RuntimeSpec you build — runtimes created from the same spec for different tenants run the same agents. Per-tenant behavior belongs in the spec you construct for that tenant, not in the identity.

version semantics

The second field, version, labels the revision of the tenant identity. It must be a non-empty string and is serialized with the spec, so it shows up wherever the runtime spec is dumped or inspected. It does not participate in storage keying: changing "v1" to "v2" does not repartition or invalidate stored references, plans, or approval records — the tenant still sees all state keyed by its resource_id. Use it to record which revision of your tenant configuration built a given runtime.

Tenant is not prompt content

Tenant identity is runtime routing metadata. It is not automatically rendered into system prompts. Put business vocabulary, domain facts, or operating assumptions in layered_prompt(domain_knowledge=...) instead:

domain_knowledge = {
    "entities": ["product", "segment", "channel"],
    "metrics": ["revenue", "margin"],
}

This separation keeps tenancy inspectable and security-relevant while keeping prompt content customer-defined and domain-specific.

See also