Giving Teams Access to Portainer Without Handing Out the Keys to Everything
Stop sharing the Portainer admin account. Here's how to use teams, environments, and least-privilege roles so each team sees and operates only the endpoints it owns — including CI tokens.
01 May 2026, 16:13 UTC

You install Portainer to make Docker and Kubernetes manageable, and within a week every engineer on the team is logging in as the same admin account. Now anyone can stop anyone else's stack, audit trails are meaningless because every action maps to one identity, and the intern has delete rights on the production payments endpoint. The fix is not complicated, but it does require thinking about Portainer's access model before you start clicking.
The useful takeaway: Portainer's access control is built around users, teams, and environments (endpoints). The practical pattern is deny-by-default: group your endpoints, put users into teams, grant each team access only to the endpoints it owns, and keep administrator rights with a small platform group. Then verify it with a non-admin account before you call it done.
How Portainer thinks about access
Portainer does not expose every connected Docker host or Kubernetes cluster to every logged-in user by default. Instead, visibility and control are granted per environment. A user (or a team the user belongs to) is given a role on a specific environment, and everything else is invisible to them in the UI.
The moving parts:
- Users — individual accounts, either local or sourced from an external identity provider.
- Teams — groups of users. Access is assigned to teams, not to individuals, so onboarding and offboarding is a team membership change rather than a permissions audit.
- Environments / endpoint groups — the Docker hosts, Swarm clusters, or Kubernetes clusters Portainer manages. Grouping related endpoints (for example, everything belonging to one product) makes assignment cleaner.
- Roles — what the team can do on that environment, ranging from read-only visibility up to full operator control of containers, stacks, and volumes.
Administrators sit above all of this and see everything. That role should be small — the people who run Portainer itself, not everyone who deploys containers.
A worked example: payments vs. platform
Say you have two Docker endpoints registered in Portainer: payments-prod and shared-tools. You want the payments team to deploy and operate their own stacks on payments-prod, see nothing else, and never touch shared infrastructure.
The setup, conceptually (menu names drift between releases, so treat this as the model rather than an exact click path):
- Create a team called
paymentsand add the relevant users to it. - Create a team called
platformfor the people who administer Portainer and shared infrastructure. - On the
payments-prodenvironment, assign thepaymentsteam an operator-level role so they can manage containers and stacks there. - On
shared-tools, assign nothing topayments. Assign theplatformteam instead. - Reserve the administrator role for one or two platform engineers.
Result: a payments engineer logging in sees exactly one environment. They can redeploy their stack, pull logs, and restart containers — but the shared tooling host simply does not exist from their point of view.
Don't forget the API and automation tokens
A common gap: the UI permissions look right, but a CI pipeline authenticates to the Portainer API with an admin user's credentials or an access token tied to a broadly-privileged account. That pipeline can now do anything, on any endpoint, regardless of the team boundaries you just built.
Treat automation as a first-class identity. Create a dedicated service user for each automation flow, put it in its own team, and scope that team to only the environment the pipeline actually deploys to. A deploy job for payments should hold a token that can only touch payments-prod. If the token leaks, the blast radius is one environment instead of your entire estate.
Trade-offs and limitations
A few honest caveats before you rely on this:
- Edition and version matter. The basic users/teams/environments model exists in Community Edition, but finer-grained RBAC, external identity integration (LDAP/OIDC), and richer policy controls are edition- and version-sensitive. Check your instance's edition and version in the Portainer UI before promising any specific capability, and verify against the documentation for that release.
- Hiding is not isolation. Portainer controls what users can do through Portainer. If someone has direct SSH access to the Docker host, or the Kubernetes API is reachable with separate credentials, Portainer's boundaries don't apply. Also check what credentials Portainer itself uses — an over-privileged agent or a mounted Docker socket with broad host access can undermine the team model from underneath.
- Team sprawl is real. If every project gets its own team and endpoint group, the access matrix becomes hard to reason about. Start coarse (per product or per environment tier) and split only when a real need appears.
Verify before you document
Access control that hasn't been tested is a rumor. Before writing this into your runbook:
- Create a throwaway non-admin user, put it in the restricted team, and log in. Confirm it sees only the assigned environment.
- Try an unauthorized action — for example, hitting the API with that user's token against another team's environment — and confirm it is denied.
- Review the admin list. If it has more than a couple of people, that's your next cleanup task.
The goal is not bureaucratic control — it's making sure that a mistake or a leaked credential stays small. Fifteen minutes of team and endpoint setup in Portainer buys you exactly that.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.