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

Provide signned tags #427

Closed
FFY00 opened this issue Mar 21, 2020 · 4 comments
Closed

Provide signned tags #427

FFY00 opened this issue Mar 21, 2020 · 4 comments

Comments

@FFY00
Copy link

FFY00 commented Mar 21, 2020

Hey, would it be possible for you to start signing the tags?

@jaraco
Copy link
Owner

jaraco commented Apr 9, 2020

Wow. In 12 words, you opened up a huge can of worms.

I'd love to provide signed tags, but the implications of this request are many. If I were to implement this request just on keyring, it would mean that the workflow for keyring starts to deviate from the other 140 projects I maintain, or conversely, I'd need to apply this request to those projects as well. And while that might be a good idea, I'd need to make sure that signed tags are available in all of the environments in which I cut releases, including multiple workstations and GitHub and GitLab (I do cut releases through the web on my phone). I'd also need to ensure that signed tags are supported by tools that create tags (such as with setuptools via bump2version).

It doesn't look like either GitHub nor GitLab support creating signed tags. Furthermore, it's not obvious to me what PKI (if any) I should use for creating a key pair for signing or if the tooling is robust enough to support storing the private key in multiple places.

I suspect there are other pitfalls in the workflow, such as required interactivity. All of the examples show typing a passphrase on each invocation, but I'd like commands to be non-interactive, and I suspect git and other tools don't support secure storage of the keys without requiring a password.

So I'm struggling with envisioning a workflow that's not complicated and adds constraints to the workflows.

I'd be interested (enthusiastic even) if there were a definitive guide on how to address these concerns, but as it appears now, there's just a bunch of loosely-coupled tools without a complete workflow.

@FFY00
Copy link
Author

FFY00 commented Apr 28, 2020

Agh, sorry for the delay! I got lost on a few other things.

Okay, there are a few things to unpack here.

  1. Git tags

First, we should have a little discussion about git tags. Git actually provides two types of tags, annotated tags and lightweight tags. Annotated tags store an object containing the author, date and description in the git database, where lightweight tags are just a pointer to a git object, they don't hold any information.

Other thing to take into account is that git describe ignores lightweight tags. If you want it to take them into account, you need to provide the --tags option.

For project releases, in my opinion, annotated tags should be used. Having access to the tag author and date at a later date is something I consider very desirable for releases. You also have the opportunity to attach a changelog and/or comments to the releases.\

Git also recommends the use of annotated tags:

It’s generally recommended that you create annotated tags so you can have all this information; but if you want a temporary tag or for some reason don’t want to keep the other information, lightweight tags are available too.

  1. Github/Gitlab tag/release support

So, Github and Gitlab support is very similar. They both provide an incomplete interface to the tags and a custom separate release system. The main difference between the two is that Github only allows you to create a tag by creating a release, while Gitlab lets you create only a tag.

The problem here is tag both websites will create lightweight tags instead of annotated tags. They expect you to rely on their release system to keep this metadata. This is obviously bad, if you ever want to migrate, or if the website goes down, you lose the metadata.

Taking this into account, if you choose to use lightweight tags, you may use the web interface to create new releases, if you choose to use annotated tags, you must use the command line to create releases as there is no support on the web interface yet.

Because lightweight tags are not git objects, they can't be signed. So, if you want to provide signed tags, you need to create releases via the terminal.

  1. Which PKI & release workflow

Okay, the PKI to use seems pretty straight forward to me, GPG. Git has great integration with GPG and it's really easy sign and verify git objects.

The only requirement for this is to have a valid GPG setup and a private key.

Creating signed tags is trivial, just pass -s:

git tag -s v1.0

And then to verify the signature we use the -v option:

git tag -v v1.0
  1. Mobile workflow

If you choose to go with lightweight tags this is trivial, just use the web interface provided by Github or Gitlab. If you want annotated tags (which allow you to sign them), you need a git client that spports them. For eg. on Android I think the easiest way to achieve this is just running git from the terminal, which should also allow you to have a valid GPG setup. Other option is to ssh to a remote server, but this is not as secure.

  1. Interactivity

You can have your gpg/keyring setup caching the passphrase on a timeout, this is what I do. The passphrase caching does not happen at the git level, git asks gpg to sign something and then gpg asks you to unlock the key.

Note: If you want you can get a hardware security key, such as a Yubikey or a Nitrokey, I believe they should make your gpg setup a bit more secure and even easier to use in some cases. This also has some benefits and drawbacks so it's not a clear decision :)

Well, I think I managed to explain the requirements for such setup and the differences between the various approaches. Let me know if you have any questions!

@jaraco
Copy link
Owner

jaraco commented Apr 30, 2020

Thanks for the considerate response.

You can have your gpg/keyring setup caching the passphrase on a timeout.

This behavior is insufficient for my goals. I'd really like to avoid adding an interactive step at any stage. I've already authenticated to my workstation - that should be sufficient to unlock/decrypt any credentials (and ideally without storing it in plaintext on the filesystem). I'm able to do that with my one-time-password generator, x509 certs, cryptocurrency wallet keys, and passwords for my most sensitive assets. It should be possible for something like a signing key. Requiring a passphrase that I have to enter is a no-go. If the tooling can grab the passphrase from the output of a command, I can work with that.

I'm considering adopting the proposed approach with the following tweak:

  • Only configure signing of tags on my primary workstation. At least initially, other devices and workflows will produce the same unsigned tags.

Part of my workflow has been to configure the following in my .gitconfig:

keyring master $ git config --get alias.atag
tag -a -m 

And I use git atag n.n.n; git push to create a release. But this approach is ugly. It requires that I run a non-standard command (atag) and that the alias is configured on every workstation I use (not too bad as I sync my .gitconfig).

I also have some projects that rely on bump2version, a fork of bumpversion but with one tweak to enable annotated tags.

Can you imagine a way in which I could run some command, and if I'm on my primary workstation where the GPG credentials are present, it will produce a signed tag, but if I run the same command on another workstation where the GPG credentials (or tooling) is not present, it will create an unsigned (still annotated) tag?

I could imagine writing this software and making sure that I install this software on whatever machine I'm developing on, but I'm not sure I want to invest that kind of effort just for my own workflow.

I look forward to your thoughts and recommendations.

@jaraco
Copy link
Owner

jaraco commented Dec 22, 2020

It sounds like the workflow I desire may not be possible yet. I'll implement signed tags when signing can be integrated into a lightweight maintenance workflow.

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