Multi-team access control for Redpanda Agentic Data Plane

Multi-team access control for Redpanda Agentic Data Plane

How to use tags and Cedar policies to give each team a self-service boundary

November 9, 2026
Last modified on

A lot of the focus on Redpanda Agentic Data Plane is on governing the agents themselves, with data policies and guardrails. But what about governing the platform itself, so your whole enterprise can use it as the central place to run agents? This post shows how multiple teams can share one deployment, with a flexible boundary around each team that covers every type of resource on the platform.

Those boundaries have to keep teams moving, not slow them down, because the north star is self-service: a team should be able to build and release its own agents without filing a ticket to the platform team. Self-service means something different at every enterprise, so the access model needs to flex to fit. Skip that flexibility, and users find other ways to run their agents, undermining the security and governance the platform is supposed to bring.

That goal translates into three requirements:

  • Granular: draw a boundary around each team’s resources, and tell an agent in development apart from the same agent in production.
  • Flexible: release an agent, or add a new one, without rewriting the access rules.
  • Scalable: keep working as the number of teams and agents grows.

The approach is simple: policies can read any tag you put on a resource, so you decide which facts about a resource control access to it. This post shows one way to do that, a team tag for who owns each resource, a stage tag for whether an agent is released, a persona tag for what each team needs to do, and a small set of policies that read those tags. We’ll walk through how the authorization model meets the three requirements above, then cover the decisions you need to make before writing a policy.

To make this concrete, we’ll use an example with three teams. The platform team runs the deployment and owns a shared large language model (LLM) provider. The accounting team builds an invoice-triage agent that reaches its enterprise resource planning (ERP) system through a Model Context Protocol (MCP) server named erp. The support team builds a refund-helper agent on its own ticketing MCP server. We’ll show the finished model, and how it changes when a team needs its own provider or access to another team’s server.

How Redpanda Agentic Data Plane decides who can do what

Redpanda Agentic Data Plane is built on an attribute-based access control (ABAC) model. You tag each resource with a few attributes, and you write policies in the Cedar policy language that read those tags when a request comes in. A policy that says "the accounting team may invoke agents tagged team=accounting" covers every agent with that tag, including the ones that don't exist yet.

A Cedar policy is a permit or forbid statement with three required parts and an optional fourth:

  • Principal: who is making the request. A user, a group from your identity provider (IdP), or an agent.
  • Action: what they're trying to do, such as Agent.invoke or McpServer.create.
  • Resource: what they're trying to do it to. An agent, an MCP server, an LLM provider, and so on.
  • Conditions: a when clause for the rule and an unless clause for exemptions.

Two evaluation rules apply everywhere:

  • A request is denied unless some permit matches it.
  • A matching forbid overrides every permit.

Here's what a policy looks like. This is the policy that gives the accounting team control of its own agents:

// accounting-agents
permit (
  principal in Group::"accounting",
  action in [Action::"Agent.create", Action::"Agent.get", Action::"Agent.list",
             Action::"Agent.invoke", Action::"Agent.update"],
  resource is Agent
) when {
  resource.hasTag("team") &&
  resource.getTag("team") == "accounting"
};

‍

Translating the policy into words:

  • Principal: anyone in the IdP group accounting.
  • Action: create, get, list, invoke, and update agents.
  • Resource: pinned to the Agent type.
  • Condition: the agent is tagged team=accounting. The hasTag check comes first because reading a tag the resource doesn't have is an evaluation error in Cedar, not false.

On a create or update, the condition is checked against the resource as it will exist after the call. An accounting user who tries to create an agent tagged team=support, or with no team tag at all, is denied. The policy enforces the tagging rule without anyone checking. One case needs an extra policy, covered with the forbids later in the post.

The resources you're governing

Every request in Redpanda Agentic Data Plane is authorized against access policies like the one above. The resources those policies govern:

ResourceWhat it is
AgentAn agent Redpanda Agentic Data Plane runs for you (managed), or one you run yourself and register with Redpanda Agentic Data Plane (self-managed)
MCP serverA connection to a data source the agent calls
LLM providerA model endpoint and its credential
SecretAn API key or token referenced by providers and servers
GuardrailA content or safety check attached to an LLM provider
BudgetA spending limit on a team, provider, or agent
Access policyThe access rules themselves

All of these carry tags, and tags are what the policies read. The example model in this post uses agents, MCP servers, LLM providers, and access policies. Secrets, guardrails, and budgets take tags the same way, so the approach extends to them when you need it. The decisions below are about which rows each team needs, and which actions on each.

Design considerations: what does each team need to do its job?

The access model starts with a question about people rather than about Cedar. For each team that will use the platform, you need to decide what they need to be able to do, map that to the resource types above, and then express it with tags. 

These are the questions you'll need to think about as you build out your access model. Since the access model is flexible, there's no single right answer.

Who are the principals, and where do membership decisions live?

Redpanda Agentic Data Plane reads group membership from your IdP at request time, which makes the IdP the one place team membership is managed. When someone joins accounting, they’re added to the group and their access follows automatically.

This means that your team tag values should be your IdP group names, spelled exactly as the IdP emits them. A policy compares strings, so Accounting and accounting are two different teams.

A resource carries one team tag. A person can be in several groups, and gets the permits of all of them. Someone in both accounting and support can build and release for either team, which is usually what you want for a shared engineer but it’s worth knowing before you put someone in a second group

In our example, the team tag has three possible values: platform, accounting, and support; one for each IdP group.

Which tags does the model need?

The team tag draws the boundaries between teams. Any other fact about a resource that a policy should react to can be a tag too. Our model uses two more.

shared=true marks a resource that every team may use. The platform team puts it on the LLM provider, and one policy permits get, list, and invoke on any provider carrying it, for everyone. When the platform team adds a second shared provider, it tags it and the same policy covers it.

stage carries the release lifecycle. Every agent is either dev or prod. In dev, only the person who created the agent can invoke it. That takes one forbid with an exemption for the creator, which Redpanda Agentic Data Plane exposes to policies as created_by. The restriction applies to the creator's own teammates too, so a dev agent stays private to its builder until it's released. In prod, everyone can invoke it.

Releasing an agent means changing the tag value from dev to prod. Anyone on the owning team can do that without asking the platform team to change a policy. If you want a review step before release, a forbid on changing the stage tag can reserve that change for a reviewer group. The team tag works the other way. Teams can’t change it, because a forbid reserves that change for the platform team. The forbids section below explains why.

Map each team to a persona

Start from personas, not teams. A persona is a kind of user, defined by what it needs to do. Identify the personas your platform has, describe what each needs using Redpanda Agentic Data Plane’s action reference as the vocabulary, then map each team to one. Our example model has three:

  • Operator: every action on every resource. It's the only persona that can create, update, or delete policies, because whoever can change a policy can change every other policy.
  • Builder: create, get, list, update, and invoke its own agents; create, get, list, update, initialize, and list tools on its own MCP servers; call tools on its own servers; and get, list, and invoke shared LLM providers.
  • Consumer: get, list, and invoke agents other teams have released.

The platform team maps to Operator, and accounting and support both map to Builder. Consumer covers everyone, including people in no team group, so it needs no team of its own. A team that only uses agents other teams built needs no team policies at all.

Each Builder team gets one policy per resource type it uses: one for its agents, one for its MCP servers, and one for the tools on those servers. Tools get their own policy because they’re a sub-resource. An MCP server is the resource a team creates and connects to, and the tools it exposes sit underneath it. A policy on the server covers creating it, connecting to it, and listing its tools, but calling a tool is an action on the tool itself.

All three policies read the team tag, so a team with three agents and five MCP servers gets the same three policies as a team with one of each. Giving a team access to another resource type, such as secrets or budgets, adds one policy for that type.

The diagram below shows the resulting model. Each team’s resources sit inside its own boundary, and the shared provider and the access policies sit with the platform team. The only lines crossing a boundary are the calls the policies allow.

Each team’s resources sit inside its own boundary. Consumers can invoke invoice-triage, which is in prod, but not refund-helper, which is still in dev.

Does every team look the same?

No, and the model shouldn't force it. Teams that start on the same persona can drift apart, and when they do, their policy sets drift with them.

A team that handles regulated data, such as accounting, might want its own LLM provider under its own contract instead of the shared one. At that point accounting becomes a different kind of builder. Support is still a builder on the shared provider. Accounting is now a builder with a private provider, tagged team=accounting, that only it can use. The two personas need different policy sets: accounting's adds a policy for its own provider, and support's stays as it was.

Accounting moves to its own LLM provider and support stays on the shared one, so the two teams now need different policy sets.

What if a team's agent needs data from another team's system? That's a request to the platform team, because access across team boundaries is the platform team's call. They would write one policy that permits the support group to call tools on the accounting team's ERP server.

One extra policy lets support's refund-helper call tools on accounting's erp server.

What does everyone else need?

Once an agent is in prod, any user should be able to find it and run it. That means get, list, and invoke on agents tagged stage=prod, for every principal.

// all-prod-invoke
permit (
  principal,
  action in [Action::"Agent.get", Action::"Agent.list", Action::"Agent.invoke"],
  resource is Agent
) when {
  resource.hasTag("stage") &&
  resource.getTag("stage") == "prod"
};

‍

Update isn’t in the list, so everyone can use a released agent but only its team can change it.

What must nobody be able to do?

Three forbids hold the model together:

  • Dev agents stay with their creator: all-dev-creator-only denies invoking any agent tagged stage=dev, unless you created it.
  • Nobody can use an untagged agent: A forbid denies invoking any agent missing stage or team, so an agent someone forgot to tag is unusable instead of slipping past the dev and prod rules.
  • Nobody can move a resource to another team by changing its tag: Redpanda Agentic Data Plane’s built-in owner lifecycle policy lets whoever created a resource keep updating it regardless of its tags, so without a forbid a creator could move their own agent to another team. A forbid on changing the team tag closes that for everyone except the platform team:
// all-teams-cannot-change-team-tag
forbid (
  principal,
  action,
  resource
) when {
  resource has changed_tags && resource.changed_tags.contains("team")
} unless {
  principal in Group::"platform"
};

‍

changed_tags is the set of tag keys an update adds, removes, or changes. It exists only on the update path, so creates and reads are untouched. The exemption names the platform team instead of listing every builder team, so a new team is covered without editing this policy.

Access policy management doesn't need a forbid. A request is denied unless a permit matches it, and platform-full-access is the only policy that grants Policy.create, Policy.update, or Policy.delete.

Summarizing the policies for our access model example

You will need twelve access policies to produce the model in Diagram 1. Adding an agent or MCP server, or releasing an agent, doesn't change the set. A new team or persona adds policies.

Platform group‍

  • platform-full-access: every action on every resource.

Accounting group‍

  • accounting-agents: create, get, list, invoke, and update agents tagged team=accounting.
  • accounting-mcp: create, get, list, update, initialize, and list tools on MCP servers tagged team=accounting.
  • accounting-tool-calls: call tools on MCP servers tagged team=accounting.

Support group‍

  • support-agents: create, get, list, invoke, and update agents tagged team=support.
  • support-mcp: create, get, list, update, initialize, and list tools on MCP servers tagged team=support.
  • support-tool-calls: call tools on MCP servers tagged team=support.

Everyone‍

  • all-shared-llm-use: get, list, and invoke LLM providers tagged shared=true.
  • all-prod-invoke: get, list, and invoke agents tagged stage=prod.
  • all-dev-creator-only: forbid invoking agents tagged stage=dev, unless you created them.
  • all-untagged-deny: forbid invoking agents missing stage or team.
  • all-teams-cannot-change-team-tag: forbid everyone except the platform team from changing a team tag.

Anything this list or Redpanda Agentic Data Plane’s built-in owner lifecycle policy doesn’t grant is denied. The owner lifecycle policy lets people get, update, and delete what they created. Accounting and support have no permits on guardrails, budgets, secrets, or access policies, so they can’t create or change them, and none of those needs a forbid. Add a forbid only when you need to override something a permit would otherwise allow.

Design first, then write the policies

Governing a shared Redpanda Agentic Data Plane deployment is a design exercise before it's a policy exercise. Decide which personas your platform serves and what each needs to do. Choose the tags that express those decisions, with team values that match your IdP groups, plus any other tags, such as shared or stage, that a policy should react to. Then write the policies on top of the tags.

Done in that order, the model meets the three requirements from the start. It’s granular, because the team tag draws a boundary around each team’s resources and the stage tag separates a dev agent from a prod one. It's flexible, because adding or releasing an agent is a tag change rather than a policy change. It scales, because the policy count grows with teams and personas, not with agents. The platform team keeps the changes that deserve a second look, such as a new team or persona, or access across teams, and teams handle everything else themselves.

To set up a model like this for your own teams, try Redpanda Agentic Data Plane.

Keep learning

No items found.

Related articles

View all posts
Michael Golfi
,
,
&
Oct 27, 2026

How we built an AI assistant for an enterprise IT service desk

Automating IT service desk triage with a governed AI agent in Microsoft Teams

Read more
Text Link
Marcin Grzebieluch
,
,
&
Jul 29, 2026

10X more data, same 4 seconds: testing Redpanda SQL at scale

A benchmark on how a single analytical query behaves as the dataset and cluster grow

Read more
Text Link
Willem Kaufmann
,
,
&
Jun 30, 2026

How Redpanda Cloud Topics rethinks Kafka compaction

Fewer wasted CPU cycles and lower storage costs while keeping compaction correct

Read more
Text Link
PANDA MAIL

Stay in the loop

Subscribe to our VIP (very important panda) mailing list to pounce on the latest blogs, surprise announcements, and community events!
Opt out anytime.