-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GitHub team allowlist command #1206
GitHub team allowlist command #1206
Conversation
Multienv and ghteams
…tlantis into github_team_whitelist_command
@lkysow let me know your thoughts, thanks |
I have followed Atlantis for quite some time now, and I recall a conversation, perhaps a PR request, on an Issue, where it was explained that at its core, Atlantis was simply the "executioner" and shouldn't really be evaluating who can do what. I believe it was the same idea when debating about restricting the UI. While I could potentially agree with this, I wanted to share an end user's perspective. One of the things that has made Atlantis great for us, has been that it is a pretty self-contained thing. It also isn't a requirement to go through the atlantis route as one can always execute terraform itself if wanted. As such, the vanilla product offers everything we need. Almost. And this almost is what draws the line between a great fit for us, and an exceptional one. The ability to restrict per github team is one of the missing features.We already restrict what type of conditions need to be in place before executing, so I don't think it's too far of a stretch to mentally assing a "allowed team" structure to the objects. Would it maybe fit better if this was on a per repo setting instead of a global server one? |
I do not see why we could not create a subsequent PR ( after this is merged) to accommodate this at the per repo level, that is a great idea and it will be easy enough since we already check per user-level access at the repo level so we know the repo that the command is being executed for. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. couple comments and questions.
Also, I code cov is dropping and I don't see any tests?
} | ||
|
||
// NewTeamAllowlistChecker constructs a new checker | ||
func NewTeamAllowlistChecker(whitelist string) (*TeamAllowlistChecker, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to allowlist
server/events/vcs/github_client.go
Outdated
} | ||
for _, t := range teams { | ||
membership, _, err := g.client.Teams.GetTeamMembershipBySlug(g.ctx, org, *t.Slug, user.Username) | ||
//membership, _, err := g.client.Teams.GetTeamMembershipBySlug(g.ctx, org, t.GetID(), user.Username) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably remove this comment
|
||
// checkUserPermissions checks if the user has permissions to execute the command | ||
func (e *EventsController) checkUserPermissions(repo models.Repo, user models.User, cmd *events.CommentCommand) (bool, error) { | ||
if cmd.Name == models.ApplyCommand || cmd.Name == models.PlanCommand { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this check? Seems a bit redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we add more command like unlock, it could be parsed by this block which it will not work but it could be removed I think since at that point we know is a valid command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think by the time we get here the command has been parsed and it is valid. Also this might introduce bugs if there is a new command and this place was not updated. I believe this feature should work with any valid Atlantis command, right?
I did not write any test since I did not know how, I was hoping to get a bit of guidance on how to proceed with that since I'm still learning the base code. |
There are a bunch of examples in the code base and golang in general has good docs on how to write tests/testing best practices |
yes, I have been looking at those hopefully soon I will start working on them. |
@@ -99,6 +100,7 @@ const ( | |||
DefaultBitbucketBaseURL = bitbucketcloud.BaseURL | |||
DefaultDataDir = "~/.atlantis" | |||
DefaultGHHostname = "github.com" | |||
DefaultGHTeamAllowlist = "*:*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather this to something specific (even if its all commands currently supported), and/or force intentional configuration. My rationale is that this makes it safe to implement more dangerous commands that are intentionally not exposed currently such as import
and rm
. I'd personally prefer a breaking change over backwards compatibility here as whats currently being proposed is users are by default admins. This flies in the face of the https://en.wikipedia.org/wiki/Principle_of_least_privilege. Make admins escalate their privs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job, I left couple comments.
@@ -167,6 +169,18 @@ var stringFlags = map[string]stringFlag{ | |||
description: "Hostname of your Github Enterprise installation. If using github.com, no need to set.", | |||
defaultValue: DefaultGHHostname, | |||
}, | |||
GHTeamAllowlistFlag: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered moving the flag to server config? It might be easier to manage that way. You will also get unmarshaling through server config. It should also remove the need for string parsing that you have to do https://github.com/runatlantis/atlantis/pull/1206/files#diff-6d78b261a5a26bea8298bc9de21e6460e101e2cbc14f0ad282e2415006d0b760R23.
@@ -435,6 +439,20 @@ func (e *EventsController) handleCommentEvent(w http.ResponseWriter, baseRepo mo | |||
return | |||
} | |||
|
|||
// Check if the user who commented has the permissions to execute the 'plan' or 'apply' commands | |||
if !e.TestingMode { | |||
ok, err := e.checkUserPermissions(baseRepo, user, parseResult.Command) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think moving this into CommandRunnner
might work better. If there is ever another way to run atlantis outside of GitHub PRs it will allow developers not to add another check.
|
||
// checkUserPermissions checks if the user has permissions to execute the command | ||
func (e *EventsController) checkUserPermissions(repo models.Repo, user models.User, cmd *events.CommentCommand) (bool, error) { | ||
if cmd.Name == models.ApplyCommand || cmd.Name == models.PlanCommand { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think by the time we get here the command has been parsed and it is valid. Also this might introduce bugs if there is a new command and this place was not updated. I believe this feature should work with any valid Atlantis command, right?
Tests have been added to cover new functions in team_allowlist_checker.go. |
@jamengual Is there an ETA for this to be released? This is a feature we're looking forward to |
This PR has been taken other by a ex-team mate and they opened a new PR to
cleanup history and such.
There is few changes requested that I hope they will have time to do them
soon.
…On Wed, Aug 4, 2021 at 9:43 AM Gaston Bezzi ***@***.***> wrote:
@jamengual <https://github.com/jamengual> Is there an ETA for this to be
released? This is a feature we're looking forward to
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1206 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAQ3ERCUCUNCTKB54C7GXGLT3FU37ANCNFSM4R7XJ6QA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
.
|
@gaston-te, if you want to build it yourself, #1694 is a more up-to-date revision of this. |
Hey I wanted to chime in specifically about I do disagree with the default of give people apply access. If we are building security features they should be secure by default. We should follow the principle of least privilege and would prefer it to be released as a major version bump and allow people to switch when they can get the required config in place for the migration. |
Merged in #1694 |
Add the ability to specify a allowlist of GitHub teams and Atlantis commands that those teams can execute.
The idea behind this is that an Atlantis operator can pass a parameter to the Atlantis server like so:
atlantis server --gh-team-allowlist "myteam:plan, secteam:apply"
and by doing so add more granular controls on which teams and command those teams can run.
this has been discussed before in this issue : #308 that have 35 👍
Over the years these types of features have been gained a lot of interest for security reasons.
From what I gather there is a big desire for these features to make it to Atlantis and I'm willing to make the necessary changes to make this happen.
I have been using this code for years and I have no issues at all, and other Atlantis users have used this code in their forks.
The current workarounds leave blank comments or require shell scripts or bash parsing solutions.
I have been authorized by CloudPosse to use their code for this PR.
Thanks.
Merged in #1694