Untrusted user forks and secrets

As part of our puppet build process, we use packer to launch an OpenStack VM to verify the manifests cleanly apply on a fresh VM. Packer requires credentials to OpenStack. We want to run this as a final step as part of all branch builds, including on untrusted forks. Both GitLab secrets and embedding the credential into the runner environment manually ultimately mean the forks can write code in their .gitlab-ci.yml to extract the secret.

In this case, I want a build step that doesn’t execute any code from the fork in the environment that has access to the secret. I.e., fork pushes code to master, master executes an uncustomizable step that launches packerctl with access to the credentials, that then triggers a packer build within the newly created OpenStack VM.

This isn’t the only place I’ve bumped into this. On some rsync style deploys, there are SSH keys I don’t really want developers to have access to. We also use the Open Build Service to publish packages, for which the build step is basically an authenticated upload.

What I’m realizing is that I’m effectively looking to delegate a build step to another build system. I could write an HTTP service that triggers a pull of the source code at the appropriate version, runs the fixed packer command to launch the VM, and streams all of the output back. The job would then make a call to that HTTP end-point. That would protect the credentials, but it’s kind of complicated.

Am I missing a better strategy? I’m wondering if this is worth while enough to invest into first classing some sort of build delegation into GitLab.

I actually found a way to accomplish this in the documentation:

You can create a docker image with a predefined set of commands that cannot be modified.