Managing Multi‑Team Access in Portainer with Role‑Based Access Control
Learn how to configure Portainer’s RBAC to give teams precise permissions over stacks, endpoints, and settings, and verify that the controls work at the API level.
12 Sept 2026, 10:26 UTC

The problem: too much access for every user
When multiple teams share a single Portainer instance, giving everyone the default Admin role can lead to accidental stack deletions, unwanted template changes, or exposure of sensitive endpoints. Teams often need a middle ground: the ability to view and deploy their own stacks while being barred from altering global settings or other teams’ workloads.
How Portainer RBAC works
Portainer’s role‑based access control (RBAC) lets administrators define roles that bundle specific permissions—such as "View stacks", "Create stacks", or "Manage endpoints". Roles are assigned to users or teams, and the resulting permission set is enforced at the API layer. Even if a user calls the Portainer API directly with a JWT token, the server checks the token’s roles before processing the request. Role inheritance allows a child team to inherit permissions from a parent team, and overlapping permissions are merged (the most permissive wins). All role definitions are stored in Portainer’s internal database (BoltDB by default, or an external PostgreSQL/MySQL instance), so they survive upgrades and can be backed up.
Worked example: creating a Stack‑Viewer role
- Log in as an administrator to Portainer (UI or API) and navigate to
Settings → Roles → Add Role. - Create a role named
StackViewer. Tick only the permissionView stacks(leave all other boxes unchecked). Save the role. - Create a team (e.g.,
frontend) underTeams → Add Team. In the team’s edit view, assign the newly createdStackViewerrole. - Add a test user (e.g.,
alice@example.com) to thefrontendteam viaUsers → Add Useror by editing an existing user. - Verification via the UI: Log out, then log in as the test user. The UI should show the stack list (if any stacks exist) but the
Add stackbutton and any endpoint‑management menus should be disabled or hidden. - Verification via the API:
- Obtain a JWT for the test user (replace placeholders):
The response contains acurl -s -X POST "/api/auth" \ -H "Content-Type: application/json" \ -d '{"username":"","password":""}'jwtfield. - Attempt to list stacks (allowed):
Expect acurl -s -o /dev/null -w "%{http_code}" "/api/endpoints//docker/json" \ -H "Authorization: Bearer "200(or200 OK) response indicating the call succeeded. - Attempt to create a stack (disallowed):
Expect acurl -s -o /dev/null -w "%{http_code}" -X POST "/api/stacks" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"name":"test-stack","template":{}}'403 Forbiddenresponse, confirming the API enforces the role.
- Obtain a JWT for the test user (replace placeholders):
Trade‑offs and limitations
- Host‑level access remains a blind spot: RBAC only gates calls that go through the Portainer server. A user with SSH or direct Docker daemon access on the host can still run
dockercommands, create containers, or modify images without Portainer’s knowledge. - Complex role matrices can obscure intent: When many teams inherit from multiple parents, overlapping permissions may unintentionally elevate privileges. Regular audits (e.g., exporting the role table via
GET /api/roles) help surface unexpected grants. - Backup and restore considerations: Because RBAC data lives in Portainer’s database, backing up the
portainer/datadirectory (or dumping the external DB) preserves role definitions. Restoring to a different version may require checking the changelog for schema changes.
Actionable closing
Start by mapping your teams’ actual responsibilities to a minimal set of permissions. Use the StackViewer example as a template: create a role, assign it to a team, then verify both UI visibility and API enforcement. Document each role’s purpose, schedule a quarterly review of the role‑assignment matrix, and harden the underlying hosts so that Portainer’s RBAC is the last line of defense, not the only one.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.