Granular API token scoping per project, environment, and server #9912
adalinesimonian
started this conversation in
Feature Requests
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Right now, API tokens are scoped to a team and have abilities like
readorwrite. Therefore, if you put a deploy token in a CI pipeline, it can deploy anything in the entire team.This is fine for small setups but becomes a problem when you have multiple projects or environments and want to hand out tokens that can only touch specific things, such as making sure the production environment can't be affected by, let's say, a CI workflow that triggers deployments in staging. This is the norm across many similar platforms precisely for this reason, to keep situations like a faulty or compromised staging deployment from impacting production.
Therefore, I'd like to propose adding a scope to API tokens that allows you to restrict them to specific projects, environments, or servers.
When creating a token, you'd optionally pick which projects, environments, or servers it has access to. If you don't pick anything, it works like it does today, i.e. it has access to the full team's resources. If you do pick something, the token can only see and act on resources within that scope.
The scoping would layer on top of existing abilities, so a token with
deployscoped to Project X can only deploy things in Project X, and so on. Scoping to a project would include all its environments and their resources. Scoping to a specific project's environment would only allow access to that environment's resources, and so on.From what I can tell from a cursory look at the codebase, this should be a relatively straightforward addition. I would guess that most of the work would be making sure it's properly enforced in all the relevant places and testing it thoroughly.
I see that the
personal_access_tokenstable already has ateam_id. Maybe we could add a nullablescopesJSON column and store the resource allowlist like that. This would be a non-breaking change since existing tokens would keep working just fine. I see a bunch ofownedByCurrentTeamAPI()methods on the different models that filter by team, so AFAIK it would be easy to give them an additional, optional filter for the scope, assuming that's the right place to put such a check.On the UI side we could add a new section where you can select the scope when creating a token, which would list the projects, environments, and servers in a tree structure with checkboxes. You could check the boxes for the resources you want to allow access to, and the UI would then save that as the token's scope.
Of course, this is all based on maybe like an hour of me looking at the codebase for the first time, so perhaps a maintainer would have more insight or might see some issues with this approach that I haven't thought of. :)
What I think would be out of scope for a first iteration of this feature would be things like scoping based on tags, scoping by resource type (that is, allowing a token to read applications but not databases, for example), or other more complex rules. I think just supporting project, environment, and server is probably going to address the vast majority of use cases for this. Nothing's stopping us from adding more security features for API keys later on, after all, if it seems like there's demand for them. I'm not much a fan of solutions in search of problems, myself.
For me personally, the lack of this feature meant I scrapped my plans to let GitHub Actions kick off deployments based on images built on Actions and pushed to GHCR, since I didn't want to give the deploy/write token access to everything, both staging and production, in the team. (I'd like to avoid just using a single tag to differentiate between versions deployed to different environments since that conflates "what's running where" with "what exists". I'd much rather have separate, immutable tags per build and let the deployment target decide which tag to pull, but that requires the token doing the deployment to be trusted to only touch the intended environment, which brings us back to this issue.)
Would there be interest in something like this?
Beta Was this translation helpful? Give feedback.
All reactions