Design: the Flowstate control plane — an admin API, tenants as administered objects, ABAC over Temporal RBAC
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
The deliberate irony, named so it can be built on purpose: Flowstate runs on Temporal and is architected like Temporal — a control plane (submit, observe, govern, administer) over a data plane (workers executing steps), in parallel to and on top of Temporal's own pair. The power of the arrangement is that each layer does what it is good at: Temporal provides durability, history, and cluster RBAC; Flowstate provides the workload model, tenancy, ABAC policy, and identity — and a Flowstate user never needs to know Temporal is there, while one who does can reach through deliberately via the temporal plugin (#95) and do self-referential things (a workflow that inspects, terminates, or resets workflows) that no other arrangement offers.
What already exists, control-plane shaped
- Layer 5 is already named: ARCHITECTURE.md's layer table calls the Connect RPC service the control plane — submit, observe, schedule, govern. The workload half is real: Run/Get/Signal/List/Cancel/Terminate/Validate/Compile/GetCatalog, all authenticated, all tenant-scoped.
- Tenancy is real at the data path: namespace from the authenticated caller (never the file), memo-based ownership on every run, fairness keys per tenant, and — as of #103 — per-tenant routing onto mapped Temporal namespaces via the client pool. Temporal RBAC applies below that mapping (a Flowstate namespace's runs live in a Temporal namespace whose access Temporal controls); Flowstate ABAC applies above it.
- The identity machinery is enterprise-grade already: inbound OIDC with discovery, JWKS caching, algorithm confusion defenses, claim rules; outbound minting with key rotation (
Issuer.Rotate), retirement windows, and JWKS publishing. What it lacks is administration —Rotatehas no non-test caller, so key rotation today means restarting with a new--identity-key. - Policy surfaces exist and are file-fed (#104): trust, egress, secret access — deployment-wide, startup-loaded.
What an admin API adds, in dependency order
- Tenants as administered objects. Today a tenant emerges from a token claim mapping. An enterprise deployment needs tenant CRUD: create a namespace with its Temporal namespace mapping, its policy attachments (#104's scope ladder), its issuer bindings, its fairness weight; list them; retire one. This is Temporal's operator-namespace API paralleled one layer up — and it is what makes "local single-tenant → shared multi-tenant cloud service" one continuum rather than two products: the local deployment simply has one implicit tenant and no admin API configured.
- Key lifecycle RPCs. Mint, rotate, retire signing keys through the API with the actor recorded — the machinery exists (
Rotate, retirement windows, JWKS serving), only the reachable surface is missing. Same for trusted-issuer management: adding an issuer to the trust policy without restarting the server. - Policy attachment RPCs — #104's get/set/list per scope, with digests in run records for after-the-fact audit.
- All of it authenticated by the same OIDC machinery and authorized by CEL ABAC over the operator's verified claims — largely attribute-based, which is the right model for the multi-tenant cloud case (role explosion is what kills RBAC-only systems at tenant scale), while degrading naturally to "the one operator with the one admin audience" locally. One trust model, one condition language, no parallel admin-credential system.
- Proto-first, of course: the admin service is a schema service beside
WorkflowService(anAdminServiceorOperatorService), so the CLI (flow tenant,flow policy,flow keys), the MCP surface, and any UI are projections of the same messages — the discipline #99 and the fourth-round CLI doctrine already prescribe.
The self-referential loop, stated as a feature
With the temporal plugin (#95), a Flowstate workflow can administer the substrate it runs on; with the admin API, a Flowstate workflow could administer Flowstate — tenant provisioning as a durable, approval-gated workflow (wait_for_signal: before creating the namespace, compensation on failure) is exactly the dogfood that proves the platform: the control plane's own operations become policy-governed, audited, durable workloads. That is the "self-controlling and describing" property — and it must remain optional capability, never a bootstrap dependency: the control plane must come up with no workflows running (invariant 8).
Constraints that keep it honest
- Invariant 8 rules everything:
temporal server start-dev+flow server --insecure-no-authmust keep working with zero admin configuration. The admin API is how a shared deployment is governed, not a prerequisite for a laptop. - The scoping ladder (#104) is the authorization model for admin operations too: a tenant-admin administers their namespace; a deployment-admin administers tenants. Both are CEL over claims, not a role table.
- Fail closed at every rung: an admin RPC with no matching allow is denied; a policy swap that fails compilation is refused while the old policy holds (#104's reload seam).
- Users who never open this door lose nothing: the whole admin surface is additive beside the workload surface, exactly as Temporal's operator API sits beside its workflow API.
Related: #104 (policy management — this issue is the service that hosts it), #94 (outbound identity — the minting this administers), #95 (temporal plugin — the reach-through), #100 (sandboxing — what tenant policy attaches), #106 (modules — tenant provisioning workflows are natural module exports), #98 (the lab where multi-tenant operation gets proven observable).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ARCHITECTURE.md's layer table and the existing Connect RPC workload service, then read #104, #94, and #95 to understand policy, identity, and Temporal boundaries. A completed design should define the proto-first admin service, tenant and key lifecycle operations, authorization model, and the no-admin-configuration startup constraint; the issue names no implementation files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- authentication, authorization, backend-api-design, distributed-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100