RBAC for AI: Governing the AI Control Plane Bifrost has introduced a role-based access control (RBAC) model for its AI gateway, distinguishing between configuration, policy, and authority changes to prevent unauthorized modifications to AI governance. The system offers 42 distinct permissions across 16 protected resources, with roles that union rather than intersect, potentially undermining least privilege. Bifrost integrates with identity providers like Okta and Entra, but warns that RBAC is only effective when provisioning is enabled and roles are carefully managed. Giving someone access to the AI control plane is not the same as deciding which parts of it they are allowed to control. The previous post https://dev.to/kenwalger/ai-access-control-for-enterprise-ai-turning-policy-into-runtime-enforcement-5bkk described virtual keys as the runtime representation of a governance decision. A workload arrives carrying policy rather than just identity, and a Marketing key capped at $2,000 a month returns 402 budget exceeded on the request that crosses the line, every time, without anyone remembering to check. That guarantee is worth exactly as much as the answer to one question: who can log into the control plane and change the cap to $20,000? Enforcement is only as trustworthy as the authority that controls the enforcement configuration. Once a gateway becomes a control plane rather than a proxy, its administrative surface is part of the security boundary, and "we already have RBAC" stops being a sufficient answer. Three kinds of change share a single interface, and they carry very different consequences. Changing a team's display name is configuration . Changing which models that team can reach is policy . Changing who is allowed to define that policy is authority . Most control planes present all three through the same dashboard, which is how organizations end up granting authority when they meant to grant configuration. Bifrost's RBAC model https://docs.getbifrost.ai/enterprise/rbac is built around avoiding exactly that: permissions are combinations of a resource and an operation, spread across sixteen protected resources including virtual keys, model providers, guardrails, MCP gateways and tool groups, audit logs, adaptive routing, and user provisioning. That produces forty-two distinct permissions, and the three system roles carve them up unevenly. Admin holds all forty-two. Developer holds twenty-seven. Viewer holds fourteen. The gap between Developer and Admin is not a matter of seniority. It is the set of permissions that change what other people are allowed to do. Traditional RBAC falls short because an identity provider knows group membership and nothing else. It does not know what a virtual key is, what a guardrail config does, or that revealing a redacted log is different from reading one. The objection behind the question is still reasonable. Most organizations already run Okta https://www.okta.com/ or Entra https://www.microsoft.com/en-us/security/business/microsoft-entra , groups are already mapped to responsibilities, and nobody wants a second identity silo. They do not need one. Authentication can stay where it is while the control plane decides what an authenticated person may administer, and Bifrost handles the seam by mapping IdP groups, app roles, and claims to roles https://docs.getbifrost.ai/enterprise/user-provisioning across Okta, Entra, Zitadel, Keycloak, and Google Workspace, with assignments synchronized on each session. Two behaviors are worth knowing before you rely on that. When provisioning is not enabled, the permissions API returns full permissions for every resource. That is a sensible default for a single-operator deployment and a dangerous one for an organization that believes RBAC is on because the feature exists. It has the same shape as the enforcement setting from the previous post: the capability ships, and the constraint doesn't apply until you turn it on. And when a user holds multiple roles, the highest applies. Roles union rather than intersect, which is standard and still the mechanism that quietly defeats least privilege. A person added to one more IdP group during a reorganization does not get the overlap of their roles. They get the ceiling. AI RBAC has to control more than create, read, update, and delete, because the operations that matter most in an AI control plane are not CRUD at all. Reveal is the permission to un-redact reversible redactions in logs. That is not administration. That is data access with an administrative label, and it belongs in a different conversation than whether someone can rename a provider. Inference operations grant the ability to invoke chat completions, embeddings, images, audio, or moderations. A control-plane role can hand out data-plane access, which means the boundary between the two planes is itself a permission. The rest earn their scrutiny through consequence rather than shape. Changing routing sounds like infrastructure until it redirects a workload to a model that never passed security review. Raising a budget sounds financial until you notice it decides whether a production workload keeps running. And configuring an MCP tool group is the most consequential of all, for a reason worth stating plainly: a model completion produces information, and a tool invocation can produce an action. A permission answers what someone may do. Scope answers which resources they may do it to. Without both, anyone with a permission can use it everywhere. Two engineering managers both legitimately need to create virtual keys, inspect usage, and manage budgets. One runs Search and the other runs Customer Support. A permission called VirtualKeys: Update lets either of them modify the other's credentials. The action is authorized. The scope is not. Permission without scope is overreach. This is why a permission matrix alone is incomplete, and why Bifrost added row-level scoping that operates alongside it. A role's data access can be set to own-data, team-data, or all-data, with each governed resource tracking the user who created it, so "may manage virtual keys" and "may manage these virtual keys" become separable statements. Build the roles from responsibilities rather than job titles. "Developer," "manager," and "director" describe people, not authority over infrastructure. Ask instead who owns provider configuration, who owns organizational spend, who can issue credentials, and who needs to inspect usage without ever modifying policy. Answering those produces roles the org chart would not have suggested. An auditor, expressed as resource and operation pairs, comes out looking like this: Auditor AuditLogs View, Download Logs View GuardrailsConfig View Users View Note what is absent. The auditor can read logs but cannot Reveal them. Redacted values stay redacted for the person whose job is reading the record, which is the entire thesis of this post compressed into one missing toggle. The obvious risk is role explosion. Organizations starting from a blank permission matrix tend to produce forty roles nobody can reason about. Start from the three system roles as templates, subtract rather than assemble, and review assignments on a schedule. Roles connect to runtime policy through access profiles https://docs.getbifrost.ai/enterprise/access-profiles : a reusable policy template attached to a role, which automatically issues every holder of that role a virtual key built from it. Until now this post has treated the two planes as separate. Roles govern who administers the system; virtual keys govern what workloads may do. Access profiles are the seam between them. A profile carries allowed providers and models, budgets, rate limits, and MCP tool access. Attach it to a role and mark it as that role's default, and every user who gains the role is provisioned automatically, each with independent budget counters. Nobody hands out raw credentials and nobody writes a key by hand. Which returns us to the question this post opened with. A key issued this way is marked profile-managed, and direct edits to it are blocked even for someone holding VirtualKeys: Update . Raising a cap from $2,000 to $20,000 is no longer a matter of editing the key. It means editing the template and propagating the change, which is a different permission with an audit trail attached. All three tiers appear in one mechanism: editing the key is configuration and is refused, editing the template is policy, and deciding who may edit templates is authority. One behavior deserves a standing review. Role changes only replace assignments that came from a role default; a profile assigned directly to a user survives their role changing. That is correct for a contractor with a deliberate exception and wrong for someone who moved teams in a reorganization eighteen months ago. Direct assignments are the ones that quietly outlive their reasons. The smallest group you can operate with, and never as a side effect of a general administrative role. Every authorization system eventually has to authorize changes to itself, and this is the permission that decides what all the others mean. In this model that is not a special case, and the design is better for it. Users and UserProvisioning are resources in the same list as Logs and AdaptiveRouter , so the permission to grant permissions is auditable exactly like any other and cannot be bundled into a role unnoticed. It still deserves a different tier of scrutiny. A user who can create roles, edit permissions, or assign themselves a stronger role sits above every control described so far, because they can change what those controls mean. Which is where authorization stops and evidence begins. RBAC determines whether a change was permitted. Audit logs tell you how the system arrived at its current configuration, who changed it, when, and under what authority. Those are different guarantees, and an incident needs both. It is not an accident that AuditLogs is a protected resource with its own permissions rather than a view bundled into the admin role. Laid out end to end, the chain runs from a decision made in a room to a request evaluated in production, crossing from the control plane to the data plane exactly once. Break that chain at the RBAC layer and everything below it keeps working exactly as designed, faithfully enforcing a policy that was changed by someone who should never have been able to change it. The data plane has no way to know the difference. The first post https://dev.to/kenwalger/ai-governance-for-enterprise-ai-why-governance-comes-before-the-gateway-2hm1 argued that governance has to exist before a gateway can enforce it, and the second showed those decisions becoming policy objects evaluated on every request. This one adds a layer underneath both, leaving three questions rather than one. Who are you? What may this workload do? Who is allowed to decide what that workload may do? One practical note before you plan an architecture around any of this: the governance in the previous post, virtual keys and budgets and routing, is in the open source Bifrost https://getmax.im/githubdevto , while the RBAC and access profiles discussed here are Enterprise capabilities. Because once AI infrastructure can route data, spend money, select models, and authorize tools that act on other systems, controlling who configures those capabilities is not dashboard administration. It is security architecture. This article was written in collaboration with the Bifrost team. The architectural perspective and conclusions expressed here are my own.