blue-build / github-action

Reusable GitHub Action to build custom images
Apache License 2.0
14 stars 4 forks source link

feat: support for injecting values from repository secret. #53

Closed Kerwood closed 2 weeks ago

Kerwood commented 5 months ago

I have a need for injecting a value from a repository secret into a file, before the build, eg. in ./config/files/etc/somefile.

Since the blue-build action its self does a checkout of the repo, it's not possible to do something like below before the build action.

echo "${{ secrets.SECRET_NAME }}" > ./config/files/etc/somefile
gmpinder commented 4 months ago

I would like to point out that using secrets and injecting them into files that are then copied into the image, will expose the secret when it's pushed to a public registry. So great care will be needed for something like this

xynydev commented 4 months ago

Good point. This wouldn't be any more secure than just including the secret file in the GitHub repository directly.

@Kerwood What is your use case for this? I suggest you re-examine it. You might be better off with a secrets manager product, such as Bitwarden's, or just reading off of a .env file on your local machine in a script that runs whatever you need the secret for.

I was initially going to close this as not planned since I view that as an antipatter, but I guess we could still implement some way to do secrets access in the build for stuff like web requests. It'd be the users own fault if they get their keys leaked, lol.

Does CLI support passing envvars into the build process or should this issue be moved? @gmpinder

Kerwood commented 4 months ago

You both have good points and I do not disagree. My use case is that I want to add files to my image that I do not want to be searchable on Github. Hmm maybe its a bad use case.. I'm not sure.

xynydev commented 4 months ago

Presumably text files, I guess. Also immutable. Something containing an email address perhaps?

Anyways; if you don't need it on your image, maybe don't put it there. There are more private ways to sync things over.

If you're concerned about being on GitHub search, you could use a private repository, or even not use GitHub at all and build your images locally (no more free compute in the nebulous cloud without you even noticing, though...)

gmpinder commented 4 months ago

Does CLI support passing envvars into the build process or should this issue be moved? @gmpinder

Yeah, I was actually wanting to implement something like that. So, Docker and Podman and Buildah, they have ways to mount secrets into the build. I want to try to set up a system for bluebuild that will make it easy to transpose those secrets into the proper build system.

Kerwood commented 4 months ago

I am working on a POC at my company where I want to give our developers the opportunity to use a Linux Desktop instead of a horrible Windows machine not suited for developing on. Our security department have some requirements for the Linux distro and I can actually meet most of them using Silverblue and a custom BlueBuild image.

One of the requirements is a specific anti virus software (Not CrowdStroke) which I can easily install with BlueBuild, but requires a specific config file that onboards the anti virus software to our tenant, pulls our company configuration and enables the software. It is that onboarding file that I wish to be on the final image but not searchable in my repo (which is a private repo). I can make it a manually process of just adding the file after OS installation, but automating it would be preferred.

I am not sure what the best approach is.

gmpinder commented 4 months ago

I am working on a POC at my company where I want to give our developers the opportunity to use a Linux Desktop instead of a horrible Windows machine not suited for developing on. Our security department have some requirements for the Linux distro and I can actually meet most of them using Silverblue and a custom BlueBuild image.

One of the requirements is a specific anti virus software (Not CrowdStroke) which I can easily install with BlueBuild, but requires a specific config file that onboards the anti virus software to our tenant, pulls our company configuration and enables the software. It is that onboarding file that I wish to be on the final image but not searchable in my repo (which is a private repo). I can make it a manually process of just adding the file after OS installation, but automating it would be preferred.

I am not sure what the best approach is.

For something like this, you could probably write a small script to curl/wget the file for a part of the build. I think when this feature is done, that could also be a way to go about it. I just wanted to make sure you were aware of the implications of putting a secret in the image.

@xynydev since we do the checkout in the action, you think it would be a good idea to add a flag to disable the checkout so that more advanced users can decide how to call our action?

xynydev commented 4 months ago

@xynydev since we do the checkout in the action, you think it would be a good idea to add a flag to disable the checkout so that more advanced users can decide how to call our action?

The repo checkout? I don't know what the use case for not doing it is, but if there's a reason to allow disabling it I'm not opposed. Of course, an advanced user may opt for not using the action at all, but using the CLI directly, perhaps by copying what we have here in action.yml.

A for @Kerwood, the use case of passing environment variables to the build will likely be supported in the future. Your use case for not having the file be searchable in the repo makes sense if multiple people are working on it, but those people shouldn't have access to the contents of the config file. However, if the config file is shipped on the image, everyone with access to the final image will be pretty easily able to extract the config file.

I'm curious about what the configuration file's privilege or confidentiality level is, and how the onboarding is handled on the Windows side.

If you don't want it on the internet, and it is a one-time setup, it could be possible to handle it with a USB stick with a script on it or something. Or if you have some sort of company intranet, hosting the config on there and deploying a systemd service to fetch it and put it in place could be an option.

Kerwood commented 4 months ago

A for @Kerwood, the use case of passing environment variables to the build will likely be supported in the future. Your use case for not having the file be searchable in the repo makes sense if multiple people are working on it, but those people shouldn't have access to the contents of the config file. However, if the config file is shipped on the image, everyone with access to the final image will be pretty easily able to extract the config file.

Well, I just dont want sensitive files in the repo. If someone accidentally makes the repo public, forks it or something. Not so much that my colleagues are not allowed to see it. The file would be on the public image, but one would have to know the url to that image. It's not in Github Packages.

I'm curious about what the configuration file's privilege or confidentiality level is, and how the onboarding is handled on the Windows side.

You can't get access to anything. With the file you can enroll your antivirus software with our company policies, which will cost us a license and get our config pushed on to your laptop.

If you don't want it on the internet, and it is a one-time setup, it could be possible to handle it with a USB stick with a script on it or something. Or if you have some sort of company intranet, hosting the config on there and deploying a systemd service to fetch it and put it in place could be an option.

Yes, as i said, the process could be manuel moving the file to the laptop after installation. I am not sure though what happen to files created in /etc on Silverblue. These laptops are zero-trust and does not have access to any private network like an intranet.

As you mentioned, it clould also be a systemd service that gets the file from storage bucket some where. Is it possible to make files in /etc without them getting overwritten ?

gmpinder commented 4 months ago

Is it possible to make files in /etc without them getting overwritten ?

Yes, any file changes in /etc on boot will persist. The only time that they don't persist is when the file itself hasn't changed. In which case, ostree will overwrite the unchanged file with what is in /usr/etc.

dkolb commented 4 weeks ago

I don't know if we should open a new feature, but some of the use cases above coincide with this. Getting dynamic information into the call to blue build right now is all but impossible.

For my use case, I just want to include build info like branch and sha in the image-info script on some universal blue images. Getting those values into the build process is very difficult and they change per build.

If I write this info to a file to be included in the image, the action's checkout overwrites that. I can't manipulate the build options passed to blue bulid at all due to it setting BUILD_OPTS="" at the beginning of the script.

Being opinionated is fine, but it's taken me less than 24 hours to find this action too restrictive.

xynydev commented 3 weeks ago

@Kerwood the merged PR above is a fix for your issue. We'll finish this discussion and do a new release immediately if we decide to not pursue adding more features related to this.

I can't manipulate the build options passed to blue bulid at all due to it setting BUILD_OPTS="" at the beginning of the script.' @dkolb

This issue could be fixed too, it's not intentional on my part. The point of the GitHub Action is to do the necessary setup for using BlueBuild on GitHub, not for it to restrict what you can do. I'm a bit busy, but if you're up for another PR, you could try this:

xynydev commented 2 weeks ago

The official recommended way to inject values into the build (right now) (make sure you're on action version v1.7.0 or higher)

Use the skip_checkout option to skip checkout, do the repo checkout yourself, and add in the files with a custom action step.

steps:
      # clone repo
      - uses: actions/checkout@v4

      # add secret (choose the location you want, then reference that in your image build if needed)
      - run: echo "${{ secrets.SECRET_NAME }}" > ./config/files/tmp/SECRET_NAME

       # the rest of the build handled by the reusable github action
      - name: Build Custom Image
        uses: blue-build/github-action@v1.6
        with:
          recipe: ${{ matrix.recipe }}
          cosign_private_key: ${{ secrets.SIGNING_SECRET }}
          registry_token: ${{ github.token }}
          pr_event_number: ${{ github.event.number }}

          # enabled by default, disable if your image is small and you want faster builds      
          maximize_build_space: true

          # skip the repo checkout built into the action
          skip_checkout: true

Passing in build opts dynamically is now also possible. If for example a build opt is added for adding ENV statements to the generated Containerfile, this feature could be used to achieve similar things.

Closing the issue now, cheers!