Skip to content

Design: Should Agent Substrate have its own concept of “namespaces”? #21

Closed

Description

@thockin

xref #18

Problem statement

Agent Substrate has the concept of an "Actor" (aka "Session", aka "Agent"). We expect to have LOTS of Actors. We know that Actors can have relationships with each other, e.g. parents and children forming a sort of tree. We know that a given human, team, or system might own multiple trees of Actors, and probably we will want access control or policies on those groups.

If an entire substrate instance is running in a small set of Kubernetes namespaces, how do we delineate things like actor ownership, access control, policies, etc.?

By analogy to k8s

The earliest versions of Kubernetes didn't have namespaces! All of the resources existed in one big flat space, and the only way to sort through them was via labels. This was clunky for a lot of reasons, including the fact that it was basically unacceptable for all users to be able to see metadata about all other users (and WATCH makes it difficult to do simple filtering). So we added namespaces.

Once we had namespaces, we found many other ways to use them, and overall the UX of namespaces is pretty good.

In Agent Substrate today, things like actor names exist in a flat, global space (and we don't even have metadata or selectors yet).

Proposal

I think Substrate needs a namespace concept for similar reasons, and in fact we should take it further. We should not have non-namespaced concepts at all. We don't have to call them “ namespaces”, of course. They could be "subspaces" or "namestrates" or "users" or "realms" or "fiefs" or "forests" or "districts" or ... For clarity in this doc, I will say "subspace". These "subspaces" would NOT be mapped to Kubernetes namespaces; they would exist only in Agent substrate.

Actors would exist under subspaces. Any single substrate-namespace could hold actors from any number of ActorTemplates, regardless of the k8s namespace those came from. Access control would be governed first at the subspace layer. A single subspace could be a single user, or a team, whatever makes sense for the user. Most operations would be scoped to a subspace, just like Kubernetes. Perhaps we need nested subspaces (e.g. tenant->team->project->tree->session), but that would need to be explored and justified independently.

Unlike Kubernetes, things like Workers would ALSO exist in subspaces. These could either be "special" subspaces or just regular subspaces with policies governing access control.

Haven Xia (@HavenXia) Julian Gutierrez Oschmann (@juli4n)

Activity

  1. brandonrjacobs commented on May 20, 2026

    @brandonrjacobs
    Contributor

    I would agree here; we already see similar needs in our own implementation where we need per user isolation. I would also agree that not only should "per user" spaces be a thing but we should have flexibility to group users into shared spaces. We see the need for this flexibility to give certain teams or groups the same "namespace" or "realm" or whatever you want to call it.

  2. mtaufen commented on May 22, 2026

    @mtaufen
    Collaborator

    I agree we need some grouping mechanism. There are several options. Some notes I have on this:

    Overview of grouping mechanisms. Grouping aka "selection" of resources. Do we want relatively static groups, or more flexible groups? One dimension, or multiple query dimensions?

    We should also consider that whatever we choose, we'll probably (a) want security policy on it and (b) want it (or some subset of it) included in credential claims. Taahir Ahmed (@ahmedtd)

    Namespaces:

    • + clear object for the "container" / "query" for a group
    • + clear object to hang security policy on
    • - limit you to one dimension, less composable
    • - probably not hierarchical?

    Labels (somewhat like a triple-store):

    • + flexible organization
    • + selectors are convenient in policy
    • + could be handy for metrics/logs tracking?
    • ~ need to index them / affects DB choice
    • ~ are security sensitive, should require permission grants for any given label key, possibly validation for allowed label values

    Trees (filesystem-like, dirs and files):

    • + more flexible than flat list of namespaces, as it allows nesting
    • - more rigid than labels

    Direct references (graph/linked list):
    actor just directly references the other actors it's related to/willing to accept connections from

    • + local, tied to actor lifecycle, so less impact on latency (not waiting for concurrent policy sync)
    • + clear from just looking at an actor what its direct neighbors are
    • - less clear what the whole transitive closure is?
    • - are actors immutable? what if it needs to be updated?

    Templates:

    • grouping by "type"
    • probably the wrong thing… and could be queried off of actor template references anyway
  3. mtaufen commented on May 22, 2026

    @mtaufen
    Collaborator

    On user spaces/groups, I think this is a good idea. It's still a gap in K8s today. Does it make sense to use the same type of grouping mechanism for users as for substrate resources?

  4. mtaufen commented on May 22, 2026

    @mtaufen
    Collaborator

    Any single substrate-namespace could hold actors from any number of ActorTemplates, regardless of the k8s namespace those came from.

    If we allow this, we need a way to ACL which substrate namespaces can use templates from which K8s namespaces. Possibly an import/export style mechanism.

  5. mtaufen commented on May 22, 2026

    @mtaufen
    Collaborator

    Perhaps we need nested subspaces (e.g. tenant->team->project->tree->session), but that would need to be explored and justified independently.

    Mapping graphs onto trees is one of THE hardest problems :)

  6. thockin commented on May 31, 2026

    @thockin
    CollaboratorAuthor

    we should have flexibility to group users into shared spaces

    Brandon Jacobs (@brandonrjacobs) Can you expand on that?

    The simplest model would be kubernetes-like. Every actor is "in" a namespace, that decision is permanent for the lifespan of the actor, all namespaces are flat wrt each other.

    A more structured model might allow nesting of namespaces - is there any argument for that?

    A more composable model might be that every actor has metadata indicating which namespace(s?) it is in. In theory that could be changed but in practice it is unlikely to be worthwhile, given the impact on policies.

    I do think this is a topic we need to pin down soon, because it may have implications for API machinery, security models, network, etc.

  7. rakyll commented on Jun 2, 2026

    @rakyll
    Collaborator

    We need namespaces for some MST characteristics even if the isolation is soft.

    Consider the following use cases:

    • We want to able to use namespace for identity when accessing other MST downstream services
    • We want to deploy the same actor template per user with some different additional resources (e.g. a different ConfigMap)
    • We want to be able to create budgets/policies per tenant
    • We don't want the actors associated with a particular tenant to be able to access actors in the namespace of another tenant
    • We want to be able to delete everything associated with a tenant (safely)
  8. thockin commented on Jun 3, 2026

    @thockin
    CollaboratorAuthor

    Whether we implement spaces as selectors or not is orthogonal to the semantics we want. Let's start with semantics. I am biased, but starting with something "familiar" is OK (kubernetes).

    • Is it required that all Actors are in a namespace, or can there be some that are not in any namespace? I think it's uncontroversial to say they should all have a namespace.

    • Is an actor's user-assigned name unique within a namespace or globally (within the substrate)? I have a strong opinion that users should not be forced to pick names due to collisions outside their control, so I think "unique within namespace" is right

    • Can an actor change from one NS to another? I would need to hear a compelling use-case for why this is important, but the implications are severe.

    • Do we need recursive namespaces? From a design POV, it seems OK, but I don't know what the use-cases would be. Intersects with the previous point about changing NS.

    • Do we think it's correct to encourage people to think about namespaces as policy domains? E.g. "default-deny in the substrate but default-allow with my namespace"

  9. HavenXia commented on Jun 15, 2026

    @HavenXia
    Member

    A design proposal for ATE Namespaces is ready for review — a per-tenant boundary that every Actor lives in, giving the control plane one place to scope ownership, access, policy, and quota.

    Here's the porposal skeletion.

    Proposal

    Substrate needs a tenant boundary — every Actor lives inside a named container called a subspace, and access is checked there first.

    Why a subspace beats alternative grouping mechanism

    The boundary has to be its own object — a real record the actor is created into, not just a tag stuck on the actor. (Like a k8s Namespace: it runs nothing, but it exists in its own right, and you can attach permissions, policy to it.) Because it owns the actor, the same object is also where access is checked. That rules out the alternatives:

    Option Why it fails as the boundary
    Labels / tags Labels are written by whoever can create or edit the actor, with no per-key access control. Anyone who can write tenant=foo joins foo — that is not a boundary. Fine as secondary tags later, never the boundary itself.
    Direct references Wrong axis. A reference graph is who works with whom — one connected workflow — not who owns it. A user's 10 unrelated sessions are 10 separate graphs that nothing groups as "theirs". And the graph is dynamic: two separate graphs can get connected at runtime (e.g. one agent links to another), merging two boundaries into one — so it can't be a stable boundary.
    Templates A template is a type. Actors already share one template, which cannot separate them.It's common that a tenant runs actors from multiple templates.

    This mirrors k8s at the actor level: an actor has one mandatory subspace (the boundary, part of its resource identity) and may also carry optional labels.

    The subspace plays the namespace role; labels are secondary selection, scoped inside a subspace. One difference worth naming: a k8s Namespace is nearly empty and has quota, RBAC, and policy off it as separate objects, whereas our Subspace is a single object that carries those as typed fields.

    Decisions

    The decisions, one line each — rationale in The design below:

    # Decision Choice
    1 Resource Identity An actor's resource identity is the tuple (subspace.name, actor_id); subspace.name is baked into the canonical id and the DNS name.
    2 Shape Flat — subspaces are peers; hierarchy is an explicit non-goal.
    3 Object kind Substrate-native, not a CRD — the boundary is high-cardinality (one per tenant → millions), past a CRD/etcd store's practical ceiling.
    4 Default No default subspace — the subspace is explicit on every CreateActor.
    5 Metadata writes Gated by a fixed credential-tier classification (actor client / subspace admin / system).
    6 Authorization One cheap check — deny across, allow within — plus a subject allow-list; no k8s RBAC machinery.
    7 Snapshots Actor state under a subspace-prefixed path; tags stored subspace-scoped (…/tags/<tag>/) so they outlive the actor; restore-eligibility resolved by the subspace in the path.
    8 Workers Carry no subspace.
    9 Template entitlement A template-side grant (ReferenceGrant-style) controls which subspaces may use templates from which k8s namespaces.
    10 Per-tenant config Per-actor, caller-injected at CreateActor — not a subspace field in alpha

    Please join ate-dev@googlegroups.com group for doc access
    The full doc is available at https://docs.google.com/document/d/1zTfgZ8UrYfjLysxdWavmIHfAeCkMD1NkpH1SvOJTYEc/edit

    Key decisions are summarized up front based on existing discussions; a couple of open questions remain. Feedback welcome here or in the doc — thanks!

  10. thockin commented on Jun 16, 2026

    @thockin
    CollaboratorAuthor

    every Actor lives inside a named container called a subspace

    I think "subspace" is not going to be a good name. The doc comments proposed "atespace" which I don't hate at all.

    The boundary has to be its own object — a real record the actor is created into, not just a tag stuck on the actor.

    I think this is a strong argument - the "space" itself carries metadata and data.

    An actor's identity is the tuple ...

    Let's be careful with the word "identity" since it has such broad meaning. I've heard this called "resource identity" elsewhere and I kind of like that.

    Otherwise I like this proposal. Do you have an implementation plan? Obviously this affects a lot of components.

  11. EItanya commented on Jun 17, 2026

    @EItanya
    Collaborator

    I added this comment in one of the google doc designs here, but I think there's an important distinction to keep in mind here. There are really 2 APIs for substrate, the internal proto API, and the k8s API.

    For the former, I think we can come up with whatever tenant concept we want, and allow users to interact with it directly if they want. For the latter I really think we should rely on k8s concepts where possible so that we can fit neatly into user's existing workflows. If we want to bring concepts above and beyond Namespaces, then we can do that, but let's do it in a k8s native first way.

    I think one of the things that make k8s extension APIs successful is how they fit into existing API models, the Gateway API is a good example for me. It's not a perfect API by any means, but it fits existing concepts of how k8s APIs work which can ease adoption.

  12. HavenXia commented on Jun 17, 2026

    @HavenXia
    Member

    I think "subspace" is not going to be a good name. The doc comments proposed "atespace" which I don't hate at all.

    Let's be careful with the word "identity" since it has such broad meaning. I've heard this called "resource identity" elsewhere and I kind of like that.

    I've updated both and working on the implementation plan, while keeping learning and resolving comments on the doc

  13. thockin commented on Jun 17, 2026

    @thockin
    CollaboratorAuthor

    Eitan Yarmush (@EItanya) +1 - the fact that concepts sort of cross those planes of existence is (IMO) a problem we should tackle, too.

  14. HavenXia commented on Jul 6, 2026

    @HavenXia
    Member

    Closing: the alpha scope of this design is implemented (#280 + follow-ups) — <atespace, actor_id> identity on all actor RPCs, Atespace create/get/list/delete-when-empty, scoped Redis keys and DNS (..actors…), kubectl-ate -a/-A, golden actors in ate-golden. Confirmed done at today's milestone scoping.

    Remaining atespace work is Beta-scoped and tracked in follow-ups:

    Design doc stays the reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area/apiUser-facing API changesarea/api-machineryarea/securitySecurity related issue/prkind/featureAn enhancement / feature request or implementationprio/P0Highest priority / required for next milestone

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions