Skip to content
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

Add a REST API option to sign package with repo's private key on package upload #6

Open
wez opened this issue Mar 10, 2023 · 4 comments

Comments

@wez
Copy link

wez commented Mar 10, 2023

Hi! I've been playing around with openrepo tonight and I'm not sure exactly how I'm supposed to use the signing key with an rpm repo.

I can create a new signing key in the UI and associate it with the repo.
I can upload a (unsigned) rpm using the openrepo CLI.
When I dnf install the rpm, dnf complains that the rpm is not signed.

My expectation was that openrepo upload would sign the rpm as part of the upload, or alternatively, provide a means for me to obtain the signing key so that I can sign the rpm as part of the build process.

I don't see how to do either of those things.

What is the flow that you recommend for this?
My ultimate goal is to publish rpms to the repo from a GH actions CI workflow (and also debs at a later date).

Thanks in advance!

@wez
Copy link
Author

wez commented Mar 10, 2023

I can put gpgcheck=0 into the .repo file to disable the check, but I'd love to have an integrated way to sign as part of uploading

@matthill
Copy link
Contributor

The current default behavior is that OpenRepo will sign the repository, not the individual RPM/Deb files. Here's a discussion about how to sign the package, and then separately how to sign the yum repo:

https://blog.packagecloud.io/how-to-gpg-sign-and-verify-rpm-packages-and-yum-repositories/

Signing the individual packages should, I believe, still be handled by the build process. For example, you may have a repo that contains packages from many different developers/sources. Removing existing signatures and re-applying a different signature for each package would be unexpected and most likely not desired.

However, perhaps there could be an upload option (non-default) that forcibly signs packages on upload for convenience.

If you'd like to use a common signing key for the package and the repo, the best method would be to create the signing key manually, integrate it into your package build process, and then run the command "./manage.py import_pgp_private_key [pem file]" to import it into OpenRepo so that same key could be used to sign the repo. FWIW, these keys don't have to be the same.

If you want to use the auto generated private key for your package signing (i.e., export it to a file), you could extract it from the OpenRepo database:

./manage.py dbshell 
SELECT * FROM repo_pgpsigningkey;

or use a gpg export command on the OpenRepo server to pull it from the keyring.

@wez
Copy link
Author

wez commented Mar 11, 2023

This is what I ended up with:

    - name: "Sign and Publish"
      if: ${{ github.ref == 'refs/heads/main' }}
      env:
        PUB: ${{ secrets.OPENREPO_GPG_PUBLIC }}
        PRIV: ${{ secrets.OPENREPO_GPG_PRIVATE }}
        TOKEN: ${{ secrets.OPENREPO_API_TOKEN }}
      shell: bash
      run: |
        t=$(mktemp)
        printenv PUB > $t
        gpg --batch --import $t
        printenv PRIV > $t
        gpg --batch --import $t
        rpmsign --define '_signature gpg' --define '_gpg_name $IDENTITY' --addsign *.rpm
        printenv TOKEN > $t
        for rpm in *.rpm ; do
          curl -X POST $OPENREPO_SERVER/api/$REPONAME/upload/ \
              -H "Authorization: Token $(< $t)" \
              -F "package_file=@$rpm" -i
        done
        rm -f $t

I would appreciate an option to sign as part of publish, because the publish would then be essentially a one-liner curl command with no additional dependencies required in the CI environment.

Also, FWIW, I couldn't find a way to successfully run ./manage.py dbshell when using the docker compose file, but I was able to extract it from the host filesystem data directory via gpg --homedir /path/to/data ...

@matthill
Copy link
Contributor

The dbshell command has to be run interactively (i.e., exec into the container first and run it). You'd also need to apt-get install postgres client. It's simply a wrapper to provide you a CLI database shell for the configured db in Django

For the option to sign the key as part of publish, I think to add the upload option may also require a security feature as well. Signing the package is supposed to be done by the package maintainer, and signing the repo is supposed to be done by the repo maintainer. In other words, they're performing different functions related to what is trusted. A repo maintainer may want to give users the option to upload, but would not want to sign the package and vouch for the package's integrity. But, when the package maintainer and the repo maintainer are one and the same (I think that is your case) it doesn't matter too much.

So I think this feature would also require some way of (by default) disallowing an uploader to use the repo's signing key on their packages unless they're explicitly given that permission.

@matthill matthill changed the title clarify signing key behavior? Add a REST API option to sign package with repo's private key on package upload Mar 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants