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
RFC improved gating capabilities, whitelists #1971
Comments
|
I'll get the ball rolling here to spark some ideas ... Idea 1, Yaml ConfigurationIt would be interesting if the approval process could be defined in the yaml and take advantage of our plugin capabilities. This could be in the same or separate yaml. Open to thoughts on either option. Example configuration in new validate:
maintainer:
image: plugins/maintainers
when:
event: pull_request
pipeline:
build:
image: golang
commands: [ go build, go test ]Pros to this approach:
Cons to this approach: We cannot trust the yaml supplied by the pull request. This means we would need to source the approvals configuration from the target branch. Sourcing the pipeline and approvals from separate versions of the same yaml file might cause confusion. Plugins will also have limited data available at runtime and will probably need to make external api requests. This could make the approval process setup a bit annoying. Technical Challenges to this approach: This would result in the build executing AND all matrix jobs if applicable, and then failing when the validation section fails. This feels very suboptimal. |
Idea 2, Maintainers file, Override behavior with PluginsThe second approach I've considered is using a maintainers file (similar to lgtm) to designate a set of individuals whose pull requests are automatically executed without required approval. This could also be described as a white-list. The maintainers file could look like this: If the username is not found in the maintainers file, the build is blocked pending manual intervention. A project member (with push or admin access) would have the ability to manually approve the pull request, allowing the build to continue, or decline. One problem with maintainers files is that people will ask for all sort of funky logic. They will want custom formats. They will want to source the maintainers file from separate repositories, they will ask for inheritance, etc. As I type this paragraph I cringe thinking about the level of flexibility people will expect of Drone. Override with PluginsThe builtin logic could be overriden with a plugin. The plugin would be in the form of a REST endpoint that gets invoked at runtime. The endpoint would return true / false indicating approval is required. How that plugin reaches that conclusion would be wholly up to the plugin, meaning there would be a lot of flexibility here to implement custom approval logic and workflows. Disabled by DefaultThis could be disabled by default, and enabled with a toggle in the repository settings. Disabled by default also could mean insecure by default. If you expose a secret to your pull request without some sort of approval workflow, a bad actor could author a malicious pull request and expose the secret. We could probably show a warning in the user interface. |
Idea 3, Check for Yaml changes, use plugins for everything elseThe third option is to keep the current implementation (from #1935) and block the build if the yaml changes. The pipeline could include additional steps for verification and whitelists. Example plugin verifies committer is member of whitelist pipeline:
+ check_membership:
+ image: plugins/membership
+ when:
+ event: pull_request
build:
image: golang
commands:
- go buildNow imagine a bad actor submits a pull request to change this behavior ... drone will detect the change to the yaml and block the pull request, pending manual review. pipeline:
- check_membership:
- image: plugins/membership
- when:
- event: pull_request
build:
image: golang
commands:
- go build |
|
I like the idea of pluggable checks within the drone.yml, but per default I would prefer the maintainers file. |
|
Ah, the maintainers file needs to be fetched from the target branch, otherwise somebody can put himself on the maintainers file. |
|
Some un-organized initial thoughts:
Purely plugin/image-based approach
Specifying build guardian plugin Keep this as simple as humanly possible for MVP:
Ideas for future expansion
Other things to consider
|
|
changeset merged to provide a custom backend for gating builds and approval. DRONE_GATEKEEPER_ENDPOINT="http://my.custom.gatekeeper"the backend must implement the following endpoints: POST /sender/{owner}/{name}/{username} // verify user is authorized sender. Request includes build details. Response is true / false
GET /sender/{owner}/{name} // get permanently authorized senders
GET /sender/{owner}/{name}/{username} // get permanently authorized sender by username
POST /sender/{owner}/{name} // create permanently authorized (or blocked) sender
PATCH /sender/{owner}/{name}/{hostname} // update permanently authorized (or blocked) sender
DELETE /sender/{owner}/{name}/{hostname} // delete permanently authorized (or blocked) senderthe backend is responsible for securing itself. The recommended approach is to use private networking or a basic auth. DRONE_GATEKEEPER_ENDPOINT="http://{username}:{password}@my.custom.gatekeeper"the full details will be documented prior to the official release. I don't expect the plugin interface to be flexible enough for all use cases, but hopefully people will write plugins and help us improve. |
Initial support for gating was implemented per #1935. The initial implementation blocks pull requests from non-project members attempting to change the yaml, pending approval. This effectively eliminates the need to sign the yaml file.
There was also discussion in issue thread #1935 to implement gating based on user membership and whitelists, as opposed to checking for yaml changes. This issue will discuss pros / cons / alternate implementations.
consideration 1
There will be teams that want gated deployments. For example, an employee wants to
drone deploy <repo> <number> <environment>. There will be teams that want this gated, and approved by a supervisor or team leader. Gating is not limited to pull request events.consideration 2
Maintaining a whitelist and approving every pull request, especially for larger open source projects like drone, could become a burden. The benefit to eliminating the signature was simplifying the workflow. We should keep usability and simplicity in mind here.
consideration 3, whitelists
The challenge with whitelists are that we would end up blocking most pull request issued to the drone/drone repository. We get a ton of casual commits. If we were to whitelist every casual committer, they would have the ability to expose my pull request secrets (gitter and slack only) and the trust factor simply may not be present yet. If we don't whitelist casual committers, I end up having to manually approve every pull request AND every subsequent synchronize event.
This is one benefit to the yaml comparison. While it doesn't protect against a zero-day docker exploit or someone trying to consume my server resources, it does prevent them from leaking secrets and only requires I get involved when the yaml changes, which is infrequent.
The text was updated successfully, but these errors were encountered: