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

Have Gitpod-based commits GPG-signed #666

Open
sr229 opened this issue Jul 6, 2019 · 66 comments
Open

Have Gitpod-based commits GPG-signed #666

sr229 opened this issue Jul 6, 2019 · 66 comments
Labels
meta: never-stale This issue can never become stale team: webapp Issue belongs to the WebApp team type: feature request New feature or request

Comments

@sr229
Copy link

sr229 commented Jul 6, 2019

There are some projects that requires commits to be GPG-signed to verify the authenticity of a contributor. Gitpod should be able make commits GPG-signed as a preference or automatically like browser-editing.

@csweichel csweichel added the type: feature request New feature or request label Jul 13, 2019
@libbitc
Copy link

libbitc commented Sep 15, 2019

Hi,

If home directories were persistent (see #340) then gpg keys may be imported into a persistent home area./home/gitpod/.gnupg/ or /home/<github username>/.gnupg/

@jankeromnes
Copy link
Contributor

If home directories were persistent (see #340) then gpg keys may be imported into a persistent home area./home/gitpod/.gnupg/ or /home/<github username>/.gnupg/

Good suggestion, thanks!

But since persisting the home directory seems a bit complicated, I have found a potential work-around (that I'd like to use for SSH keys):

  1. Set SSH_PUBLIC_KEY and SSH_PRIVATE_KEY environment variables in https://gitpod.io/environment-variables/ (you may restrict this to repos you trust, e.g. yourname/*)
  2. Add something like this to your projects' .gitpod.yml:
tasks:
  - before: >
      mkdir -p ~/.ssh &&
      echo $SSH_PUBLIC_KEY > ~/.ssh/id_rsa.pub &&
      chmod 644 ~/.ssh/id_rsa.pub &&
      echo $SSH_PRIVATE_KEY > ~/.ssh/id_rsa &&
      chmod 600 ~/.ssh/id_rsa

This will re-setup your SSH keys automatically in every workspace for that project, and may be adapted for GPG keys too.

It's a bit cumbersome, because it requires a project configuration change, but may work. I wonder if SSH and GPG could also accept keys as environment variables, removing the need for creating special files in the home directory.

@libbitc
Copy link

libbitc commented Sep 24, 2019

Hi,

The following would work for GPG keys so something similar will also work for .ssh.

  1. Convert your source .gnugpg directory contents to base64 data:
    tar -czvf - ./.gnupg | base64 -w 0

  2. Place this data into a gitpod environment varaiable called GNUGPG

  3. Add following to project's .gitpod.yml:

tasks:
  - before: >
      [[ ! -z $GNUGPG  ]] &&
      cd ~ &&
      rm -rf .gnupg &&
      echo $GNUGPG | base64 -d | tar --no-same-owner -xzvf -

@jankeromnes
Copy link
Contributor

jankeromnes commented Sep 24, 2019

Thanks for the tip!

  1. Place this data into a gitpod environment varaiable called GNUGPG

You can even do this directly from a Gitpod Terminal, like so:

gp env GNUGPG=$(tar -czvf - ~/.gnupg | base64 -w 0)

@corneliusludmann
Copy link
Contributor

I don't like to store my private GPG (or SSH) keys in a (unencrypted) third-party database (aka “not my computer”), but I really would like to sign my commits. I think one should rather use a secure solution like Krypton for that (see also #782, thx @Vlaaaaaaad for the hint). With Krypton, the private key never leaves the security chip on your phone.

We could add Krypton to the Gitpod base image gitpod/workspace-full. I was curious how well Krypton works in Gitpod. Thus, I created a simple sample repository (with some notes in the README.md): https://github.com/corneliusludmann/gitpod-krypton-example You still need to pair (kr pair + scan QR code with your phone) and enable (kr codesign) Krypton in every workspace via the terminal. (It's totally fine for me, however, it shouldn't be to hard to build a plugin/widget for GUI support for this.)

Pros of adding Krypton to the Gitpod base image:

  • Having a secure (!) way to sign your commits.
  • Little effort to support signed commits in Gitpod.
  • Could encourage users to sign their commits.

Cons of adding Krypton to the Gitpod base image:

  • Additional dependency in the base image for a feature that may not be used by many people.
  • Feature is “hidden” behind the terminal. A proper documentation on the Gitpod website could help users to discover this useful feature. Or even a widget.

How do you feel about it? Any opinions?

(Probably there are even alternatives to Krypton?!?)

@Vlaaaaaaad
Copy link

I very much like the idea( it's what I use now due to me switching tons of devices for work) and it also adds secure SSH for people who need that buuuuut krypt.co has been acquired and is now a part of Akamai. No comment has been made regarding the future of krypt.co so I would be against adding it in the base image until the future of the project is known.

CC @kcking and @agrinman for a comment on this.

@libbitc
Copy link

libbitc commented Oct 3, 2019

I don't like to store my private GPG (or SSH) keys in a (unencrypted) third-party database (aka “not my computer”),

@corneliusludmann If the keys are password protected then they are encrypted .

@corneliusludmann
Copy link
Contributor

If the keys are password protected then they are encrypted .

You're right. That makes it much better. The only thing left is that you have to decrypt the keys in the (probably “untrusted”) workspace to sign your commits, don't you? It's still a (small) attack vector that services like Krypton solve.

@sr229
Copy link
Author

sr229 commented Oct 3, 2019

I would prefer much to have an option to have Gitpod generate a one-time GPG key for me just like GitHub were they provide a GPG key for each account when you perform a browser-based edit as well.

There's reasons why this would be feasible since not everyone likes to provide their own keys and would probably prefer to have a service generate it for them.

@sr229
Copy link
Author

sr229 commented Oct 3, 2019

while the solutions you have might be good, again, in my opinion, this increases complexity if we wanted Gitpod to be just a out of the box experience, meaning user should just code and test, and that's it. I think this should be a optional integration for services like Krypton since I don't feel like its worth the configuration for many just to have their commits authenticated. Having options is a nice little thing.

@JesterOrNot
Copy link
Contributor

I agree with @sr229 the idea of the service is "frictionless coding" I feel it would compromise the goal of the project to force this it should be recommended but not forced upon users.

@Kreyren
Copy link

Kreyren commented Jun 29, 2020

Any info on this? Gitpod being unable to sign the commits is quite annoying when i am trying to contribute to things that require CLA, etc.. alike tldr-pages/tldr#4136

So for me i have to clone local and remake the commit..

@Kreyren
Copy link

Kreyren commented Jun 29, 2020

Note that github has access token for this

image

So i would think that just adapting gitpod's logic to use this would be enough?

@sr229
Copy link
Author

sr229 commented Jun 29, 2020

Note that github has access token for this

image

So i would think that just adapting gitpod's logic to use this would be enough?

Yep! That's what I was going for, We already have the API for it.

@wusatosi
Copy link

Any updates?

1 similar comment
@crazyuploader
Copy link

Any updates?

@jankeromnes
Copy link
Contributor

Hi @wusatosi and @crazyuploader!

While I agree this would definitely be more convenient with a built-in feature in Gitpod, you can already set up GPG-signed commits in Gitpod yourself as explained in #666 (comment)

Please let me know if this doesn't work or if you're getting any errors.

@sr229
Copy link
Author

sr229 commented Dec 1, 2020

Just wanna let you know @jankeromnes GitHub Codespaces now sign commits so you guys might want to catch up now.

image

@crazyuploader
Copy link

Hi @wusatosi and @crazyuploader!

While I agree this would definitely be more convenient with a built-in feature in Gitpod, you can already set up GPG-signed commits in Gitpod yourself as explained in #666 (comment)

Please let me know if this doesn't work or if you're getting any errors.

Oh it worked, thanks!

@stale
Copy link

stale bot commented Mar 17, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the meta: stale This issue/PR is stale and will be closed soon label Mar 17, 2021
@corneliusludmann corneliusludmann added the meta: never-stale This issue can never become stale label Mar 17, 2021
@stale stale bot removed the meta: stale This issue/PR is stale and will be closed soon label Mar 17, 2021
@enriquecaballero
Copy link

FWIW, I just tried the instructions on #666 (comment) and they don't work in the latest Gitpod builds (with rebranding and VS Code) via the gitpod user. It requires sudo to sign anything. Does anyone know how to fix this?

@mrzarquon
Copy link
Contributor

mrzarquon commented Jul 6, 2022

With the latest updates making gitpod remote IDE connections use SSH, and the just added "bring your own ssh publickey" to gitpod.io, combined that means to enable gpg signing via agent forwarding you can use these steps:

  • add publickey to your profile
  • update your .ssh/config to forward gpg keys to *.ssh.ws.gitpod.io servers, this is my example:
Host *.ssh.ws*.gitpod.io
    ServerAliveInterval 15
    IdentityFile /Users/cbarker/.ssh/gitpod
    RemoteForward /home/gitpod/.gnupg/S.gpg-agent /Users/cbarker/.gnupg/S.gpg-agent.extra
    StreamLocalBindUnlink yes
  • Have a build task in your gitpod.yml to inject your public key, stop the gpg-agent (started because we initialized a public key), and configure git for your key:
tasks:
  - before: |
      gpg --keyserver keys.openpgp.org --recv-keys 5993621FD9D214E212E421C3AC3A6CB9E464DBDA
      gpgconf --kill gpg-agent
      git config --global user.signingkey 5993621FD9D214E212E421C3AC3A6CB9E464DBDA

Now when you launch your workspace via VS Code IDE or Jetbrains, it should automatically forward a socket for GPG over SSH to your workspace. If you're in the web IDE, starting an ssh session from your workstation would also suffice.

In my configuration, my yubikey (setup from drduh's guide) hosts my private key. A side effect of this is that any commit signing or gpg action requires either pin + physical touch, or physical touch, before it will proceed. That makes me feel relatively secure knowing that while the socket is on a remote machine, the yubikey means I have to approve any use / access to the socket (I always require touch to sign and you can set a timeout for the pin approval).

@RudraSen2
Copy link

RudraSen2 commented Sep 11, 2022

If VS Code Web Supports signing, why not GitPod? GitPod is also a wrapper of VS Code... Please search VS Code Source to get how they sign commits.

@woss
Copy link

woss commented Sep 14, 2022

@RudraSen2

If VS Code Web Supports signing, why not GitPod? GitPod is also a wrapper of VS Code... Please search VS Code Source to get how they sign commits.

The VScode relies on the git + gpg program that YOU install on YOUR computer. you have the private key and public key; VSCode is , only using it. Also, the way HOW it is using it is via the git itself, especially via the gpg.program key in the .gitconfig file. Which you can set to any gpg compliant program. What you think is simple is far from it.

You have to understand that Gitpod is not just a wrapper for VScode, it is also the infrastructure that runs in the cloud, and the ONLY state that is persistent is the /workspace directory ( unless specified diff in the config ), which also means that you don't have many options if you are going to use it purely in the browser as i do. many people use it via the ssh on the desktop, which i personally think it's pointless since you can use the vscode directly ( of course, minus all the deps setup, etc ... then again, .devcontainer is good enough)

Having said that, i am using the remote signer for 6 months already, which signs my commits, and I am using ONLY the web version. maybe you can look into that before you start telling them what to do ;)

@agibralter
Copy link

@mrzarquon's approach +1

1 issue though... StreamLocalBindUnlink should in theory force the remote socket to get created? For some reason it didn't seem to work unless I went into the box to unlink /home/gitpod/.gnupg/S.gpg-agent first... anyone else find this?

With the latest updates making gitpod remote IDE connections use SSH, and the just added "bring your own ssh publickey" to gitpod.io, combined that means to enable gpg signing via agent forwarding you can use these steps:

  • add publickey to your profile
  • update your .ssh/config to forward gpg keys to *.ssh.ws.gitpod.io servers, this is my example:
Host *.ssh.ws*.gitpod.io
    ServerAliveInterval 15
    IdentityFile /Users/cbarker/.ssh/gitpod
    RemoteForward /home/gitpod/.gnupg/S.gpg-agent /Users/cbarker/.gnupg/S.gpg-agent.extra
    StreamLocalBindUnlink yes
  • Have a build task in your gitpod.yml to inject your public key, stop the gpg-agent (started because we initialized a public key), and configure git for your key:
tasks:
  - before: |
      gpg --keyserver keys.openpgp.org --recv-keys 5993621FD9D214E212E421C3AC3A6CB9E464DBDA
      gpgconf --kill gpg-agent
      git config --global user.signingkey 5993621FD9D214E212E421C3AC3A6CB9E464DBDA

Now when you launch your workspace via VS Code IDE or Jetbrains, it should automatically forward a socket for GPG over SSH to your workspace. If you're in the web IDE, starting an ssh session from your workstation would also suffice.

In my configuration, my yubikey (setup from drduh's guide) hosts my private key. A side effect of this is that any commit signing or gpg action requires either pin + physical touch, or physical touch, before it will proceed. That makes me feel relatively secure knowing that while the socket is on a remote machine, the yubikey means I have to approve any use / access to the socket (I always require touch to sign and you can set a timeout for the pin approval).

@ChevronTango
Copy link

ChevronTango commented Feb 23, 2023

I'm planning on having a look at GitSign in my own time to see if there's anything smoother that can be done. In particular I'm keen to see how a Self hosted Fulcio and GitLab instances can be used with Gitpod.

The real unknown is whether I can bypass the browser auth of GitSign by using the token that Gitpod uses. I know I can get an access_token from http://localhost:22999/_supervisor/v1/token/git/my.host.name/ but I don't know if that's enough or if I need a full jwt or id_token, or even if Fulcio will accept one from Gitpod rather than from itself. I'll see what I can figure out.

One question I had for the dev's whilst I figure this out is: is there a way to get the full oidc id_token including the aud field?

@ChevronTango
Copy link

One question I had for the dev's whilst I figure this out is: is there a way to get the full oidc id_token including the aud field?

I made some progress on this front. Turns out you can do the following:

curl --user oauth2:$(curl 'http://127.0.0.1:22999/_supervisor/v1/token/git/gitlab.com/' -s | jq -r '.token') "https://gitlab.com/jwt/auth?service=container_registry"

This retrieves a valid jwt (at least for gitlab) however it has the wrong audience to be useful for sigstore or fulcio. I've raised https://gitlab.com/gitlab-org/gitlab/-/issues/393134 to ask for this feature.

Not sure if the same is possible for github however

@woss
Copy link

woss commented Feb 24, 2023

i've been following this discussion for a while, and i don't what's the big deal, i have been using signed commits since last year may, and where gitpod does not host my keys.

@mrsimonemms
Copy link
Contributor

@ChevronTango as @woss says, this is already possible (but undocumented). If you take a look at my Dotfiles, you'll see how you can do it - you need to configure the envvars GPG_PRIVATE_KEY_BASE64 and GPG_SIGNING_KEY. The only problem then is that, if you have a passphrase, you have to enter it each time (I could probably get around that, but my passphrase is easy to type so the effort ain't worth going to)

@woss
Copy link

woss commented Feb 24, 2023

expanding on the @mrsimonemms comment...
or you can use a remote-signer, which i built for the purpose of having the signed commits.

It consists of 2 components; a CLI and the server. All you need to do is download the CLI in the init script, set a few ENV vars that point to your server, run the express app with your keys on the server, and that's it.

the server you can run on the cheapest and slowest VM you can find :)

Also with this setup you can have repos from Github and Gitlab using the same key

@mrsimonemms
Copy link
Contributor

@woss nice work. Have you got any source code you can share?

And could you run the server in the background of a Gitpod workspace to avoid having the expense ($5 is one whole beer after all)?

@woss
Copy link

woss commented Feb 24, 2023

@mrsimonemms

And could you run the server in the background of a Gitpod workspace to avoid having the expense ($5 is one whole beer after all)?

sure, but what's the point? in this case, you have your PVT key in the gitpod env, which is the thing i wanted to avoid 🙂

Have you got any source code you can share?

Unfortunately, i closed the source the repo because i accidentally pushed the sensitive info ☹️

but i can send you the CLI and the docker server image so you can play around

$5 is one whole beer after all

dude, where do you live???? where i live you get TWO beers for that 😊

@mrsimonemms
Copy link
Contributor

sure, but what's the point? in this case, you have your PVT key in the gitpod env, which is the thing i wanted to avoid :)

Yeah, but where's the fun in that?

Unfortunately, i closed the source the repo because i accidentally pushed the sensitive info ☹️

Oooops, but we've all been there. If you can share something, I'd be very interested in looking at how you solved it.

dude, where do you live???? where i live you get TWO beers for that 😊

UK. A pint for me is usually about £4. In that there London, it can be double that.

@woss
Copy link

woss commented Feb 24, 2023

@mrsimonemms i composed the gist with hopefully clear guidelines so you can test it :)
https://gist.github.com/woss/8a2e9921729280ce0e07bed459ecd7ef

All feedback is welcomed ( beers too ) 😊

@ChevronTango
Copy link

@mrsimonemms So my key point here is not that I want Gitpod to sign my commits, as you are quite correct that that can be done right now, but instead I want all commits from Gitpod signed for all of my teams, and most of all, I don't want Gitpod to store those credentials. Any time you have a service storing credentials that's just asking for a breach to occur, and whilst I trust the Gitpod devs to some extent, I'd rather not have to. I am not an individual, but a part of a larger userbase and I want to solve the problem for all of them.

The approach I'm prusing is aimed at providing what you and @woss were talking about, a remote service that gitpod can call out to and use to sign the commits, but without the user having to store anything sensitive in either of those systems. I don't want each user to have one service each, I want it centralised and managed. Fulcio and Gitpod both use OIDC and if they could be made to work in tandem then that means I can have every single user in my org signing all of their commits, without any of them having to do anything special, nor us having to do extra risk mitigation for potential loss of GPG keys stored in one or other of those systems.

To go a step further, if this were to work, it could be used for all users in Gitpod, not just my teams, which would be a big win for security around Gitpod.

@woss
Copy link

woss commented Feb 24, 2023

@ChevronTango
let me see if i got you correctly. Do you want a centralized 3rd party server to store your pvt keys and you don't trust a centralized 3rd party system ( gitpod ) to store your keys in the workspace that is literally alive for the duration of the task implementation? This doesn't make much sense to me.

Also, owning the PGP key is a personal responsibility, not companies'.

@ChevronTango
Copy link

ChevronTango commented Feb 24, 2023

@woss That's not what Fulcio does. It creates ephemeral keys based on your OIDC token. In the same way that you don't use your password for everything, you use a cookie or ephemeral token, Fulcio provides the same ephemeral signing key approach. All you do is provide your OAuth JWT token and it returns to you a temp key that you can sign your commits with. That's what I want. It's not that I don't trust 3rd party services, but more that I don't trust storing things in 3rd party services. There shouldn't ever exist a database of everyone's GPG keys just waiting to be attacked, and that includes Gitpod itself.

@burningion
Copy link

Agreed on the simplicity of the approach @ChevronTango has brought up. An OpenID Connect token with Fulcio signing makes a ton of sense, and is something I'm advocating for internally.

In the meantime, we've released a blog post detailing how to use 1Password for biometric confirmation of signing with SSH keys: https://www.gitpod.io/blog/signing-git-commits-on-gitpod-with-1-password

The main caveat here is that it only works on desktop clients, and doesn't work in the browser, like an OpenID Connect based approach would.

@strausmann
Copy link

When you use GitLab Repositories, you can now use SSH Code Signing.
https://docs.gitlab.com/ee/user/project/repository/ssh_signed_commits/

@ChevronTango
Copy link

Agreed on the simplicity of the approach @ChevronTango has brought up. An OpenID Connect token with Fulcio signing makes a ton of sense, and is something I'm advocating for internally.

In the meantime, we've released a blog post detailing how to use 1Password for biometric confirmation of signing with SSH keys: https://www.gitpod.io/blog/signing-git-commits-on-gitpod-with-1-password

The main caveat here is that it only works on desktop clients, and doesn't work in the browser, like an OpenID Connect based approach would.

Just noticed #16482 which makes Gitpod itself an OIDC provider. If it can support a sigstore JWT token, and the user can retrieve that from the workspace supervisor, then we may be in with a chance of getting fulcio working and signing our commits. That's a much better approach than getting a different token from GitLab and Github etc.

@mrzarquon
Copy link
Contributor

@mrzarquon's approach +1

1 issue though... StreamLocalBindUnlink should in theory force the remote socket to get created? For some reason it didn't seem to work unless I went into the box to unlink /home/gitpod/.gnupg/S.gpg-agent first... anyone else find this?

@agibralter StreamLocalBindUnlink depends on both client and server honoring it, and it looks like our latest revisions might not at the moment. I updated my example here to use a little more robust script that I'm actually using to consistently get my yubikey based gpg key forwarded to my workspaces in VSCode, without having to start a second ssh session.

@paramsiddharth
Copy link

@mrsimonemms

And could you run the server in the background of a Gitpod workspace to avoid having the expense ($5 is one whole beer after all)?

sure, but what's the point? in this case, you have your PVT key in the gitpod env, which is the thing i wanted to avoid 🙂

Have you got any source code you can share?

Unfortunately, i closed the source the repo because i accidentally pushed the sensitive info ☹️

but i can send you the CLI and the docker server image so you can play around

$5 is one whole beer after all

dude, where do you live???? where i live you get TWO beers for that 😊

@woss It is probably irrelevant but where I live, you can survive for 3-4 days. :')

@ChevronTango
Copy link

ChevronTango commented May 6, 2023

So I got very close to making this work:

I set up Fulcio with the following Config

{
  "OIDCIssuers": {
    "https://api.gitpod.io/idp": {
      "IssuerURL": "https://api.gitpod.io/idp",
      "ClientID": "sigstore",
      "Type": "email"
    }
  }
}

and in my gitpod workspace I setup Gitsign with the following instructions.

brew tap sigstore/tap
brew install gitsign

git config --global commit.gpgsign true  # Sign all commits
git config --global tag.gpgsign true  # Sign all tags
git config --global gpg.x509.program gitsign  # Use Gitsign for signing
git config --global gpg.format x509  # Gitsign expects x509 args
git config --global gitsign.fulcio https://5555-my-workspace.ws-eu96b.gitpod.io/

export SIGSTORE_ID_TOKEN=$(gp idp token --audience sigstore)

unfortunately it looks like the JWT token doesn't include the right fields for fulcio to approve the certificate for signing:

ERROR server/error.go:45 returning with error {"requestID": "O7hSTLqo", "code": "InvalidArgument", "clientMessage": "There was an error processing the identity token", "error": "token missing email claim"}

looks like fulcio has a number of different OIDC types and I chose email but it looks like none of them are compatible with the existing JWT claims:

{
  "iss": "https://api.gitpod.io/idp",
  "aud": [
    "sigstore"
  ],
  "azp": "sigstore",
  "c_hash": "",
  "exp": 1683410309,
  "iat": 1683406709,
  "auth_time": 1683406709,
  "sub": "https://gitlab.com/ChevronTango/gpg-test/-/tree/main/",
  "name": "ChevronTango"
}

so for the Gitpod dev's, if those extra "email" and "email_verified" claims could be added in, I can use a private sigstore instance to sign all of my commits. If you wanted to go one step further you could ask fulcio to add Gitpod to their config for SaaS fulcio, and you could then add the above git config to your static layers. Then every commit in all gitpod workspaces would all be signed. We are very close to making this a very powerful feature and it's not much more work to achieve it.

@VladimirCreator
Copy link

+1
It would make GitHub integration even better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meta: never-stale This issue can never become stale team: webapp Issue belongs to the WebApp team type: feature request New feature or request
Projects
Status: No status
Development

No branches or pull requests