Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-53877

sshagent + git checkout on local agent: ssh key not found

      sshagent + git checkout doesn't seem to work: the `SSH_AUTH_SOCK` env var disappears from the git process environment, and thus the ssh-agent is not available to ssh started by git...

       

      Scenario:

      • create a ssh key credentials `ssh-key`
      • create a pipeline job with Jenkinsfile:
        node {
            stage('Preparation') {
                sshagent (['my-ssh-key']) {
                    sh 'printenv'
                    sh 'ssh-add -l'
                    git 'git@github.com:foo/bar.git'
                }
            }
        }
        
      • run created job

      Expected result:
      ssh started by git finds the correct ssh key via the ssh agent.

      Actual Result:

      • git fetch fails : no valid ssh key found
      • `ssh-add -l` works though, and shows the key added by `sshagent`

      Other tests:

      • `checkout` scm instead of `git` command: same behavior: it fails to find the key
      • direct `sh 'ssh -vvv git@github.com'` works

      More digging:

      • configure a git wrapper as `git` tool in global jenkins config to observe what happens:
        #!/bin/bash                                                                                                           
        printenv >& /tmp/$$.git-env
        ssh-add -l >& /tmp/$$.git-ssh-add-list
        export GIT_TRACE=1
        export GIT_SSH_COMMAND="ssh -vvv" 
        git "${@}"
        
      • run job again

      Result:

      • `ssh-add -l` fails: "Could not open a connection to your authentication agent."
      • `printenv` shows `SSH_AUTH_SOCK` env var is not here, which explains why the ssh agent is not usable/used

      So the remaining question is: why is the `SSH_AUTH_SOCK` env var removed when executing git commands ?

          [JENKINS-53877] sshagent + git checkout on local agent: ssh key not found

          Mark Waite added a comment -

          I don't understand what you're trying to accomplish.

          Can you explain further why you're not passing a Jenkins credential to the `git` Pipeline step rather than passing an empty string as the argument to ssh-agent and then adding the default private key?

          Doesn't the ssh-add technique that you're using require that you place the private key into the ~/.ssh directory of each user that runs an agent? Passing a Jenkins credential will avoid that agent-specific configuration and will simplify the build script.

          If you truly need fine-grained control of the git command, you might choose to place the git command inside an `sh` step that is wrapped by the ssh-agent command. If you've decided that you're not using Jenkins credentials to manage credentials, you can probably just as readily decide that you won't use the git plugin to manage checkout.

          Note that I have not attempted the steps you've described, so I don't know if there is a way to accomplish what you're describing. I won't duplicate the bug report until later. I wanted to ask the clarifying questions before I invest the time to duplicate what you've described.

          Mark Waite added a comment - I don't understand what you're trying to accomplish. Can you explain further why you're not passing a Jenkins credential to the `git` Pipeline step rather than passing an empty string as the argument to ssh-agent and then adding the default private key? Doesn't the ssh-add technique that you're using require that you place the private key into the ~/.ssh directory of each user that runs an agent? Passing a Jenkins credential will avoid that agent-specific configuration and will simplify the build script. If you truly need fine-grained control of the git command, you might choose to place the git command inside an `sh` step that is wrapped by the ssh-agent command. If you've decided that you're not using Jenkins credentials to manage credentials, you can probably just as readily decide that you won't use the git plugin to manage checkout. Note that I have not attempted the steps you've described, so I don't know if there is a way to accomplish what you're describing. I won't duplicate the bug report until later. I wanted to ask the clarifying questions before I invest the time to duplicate what you've described.

          I don't understand what you're trying to accomplish.

          Can you explain further why you're not passing a Jenkins credential to the `git` Pipeline step rather than passing an empty string as the argument to ssh-agent and then adding the default private key?

          I'm sorry, I made a typo in my example. I now fixed it: the credentialsId in`sshagent` should not be empty (that's what happens when you clean sensitive data from examples...): I want to make available a ssh key handled by jenkins.

          (Side note: What do you mean by "adding the default private key"? Is there a notion of "default private key" ? or does it just rely on other mechanisms for authentication (standard ssh, outside of jenkins) (that's what I believe).)

          My end-goal is more complex, and I reduced one possible solution to it to this issue. There may indeed be alternate solutions.
          (But I believe this simple issue is still valid and should ideally be fixed anyway).

          In this simple case, I am trying to accomplish the following:

          • use `sshagent` to setup an ssh key handled by jenkins credentials
          • use that previously setup ssh key in git commands with a git+ssh remote

          I could indeed just use `sh 'git'` but it would make less sense in my more complex/initial case/scenario.

          More complex case:

          • use `checkout` with recursive submodules checkout, where the submodules use a different credentials than the parent repository
            This is not that unusual when:
          • using `multi branch pipeline` with `github branch source`: the latter imposes HTTPS git clone (because it re-uses the only credentials it asks, which is only of type user/apikey-as-password, because it needs API access to implement branch/tags discovery and such)
          • submodule remotes URLs are git+ssh:// URLs (submodule URLs are hardcoded in the parent git repository, not configurable from the jenkins pipeline)

          In this case I have the parent repo cloned with HTTPS, using a specified user/password credentials, then when trying to checkout the submodules, I here need a ssh key.

          I tried to work around this limitation by using the `sshagent` to make available the need ssh key for submodules: it didn't work, and this lead me to the simple case I initially reported here.

          Maybe I should open a second issue for the more general case?

          Other workarounds could be:

          • be able to specify credentials for submodules on `checkout` (I have many submodules, so it would be great with a "default credential" for all submodules for this `checkout`, or something along these lines)
          • be able to give a second credentials to `github branch source` of type ssh key so that it uses the apikey for the api, and the ssh key for git clone (and its submodules)

          Note that I have not attempted the steps you've described, so I don't know if there is a way to accomplish what you're describing. I won't duplicate the bug report until later. I wanted to ask the clarifying questions before I invest the time to duplicate what you've described.

          I totally understand you needed more information, especially as my initial report contained an error, and was not very detailed. I hope it's more clear now. If you need any more information please let me know.

          Thomas Riccardi added a comment - I don't understand what you're trying to accomplish. Can you explain further why you're not passing a Jenkins credential to the `git` Pipeline step rather than passing an empty string as the argument to ssh-agent and then adding the default private key? I'm sorry, I made a typo in my example. I now fixed it: the credentialsId in`sshagent` should not be empty (that's what happens when you clean sensitive data from examples...): I want to make available a ssh key handled by jenkins. (Side note: What do you mean by "adding the default private key"? Is there a notion of "default private key" ? or does it just rely on other mechanisms for authentication (standard ssh, outside of jenkins) (that's what I believe).) My end-goal is more complex, and I reduced one possible solution to it to this issue. There may indeed be alternate solutions. (But I believe this simple issue is still valid and should ideally be fixed anyway). In this simple case, I am trying to accomplish the following: use `sshagent` to setup an ssh key handled by jenkins credentials use that previously setup ssh key in git commands with a git+ssh remote I could indeed just use `sh 'git'` but it would make less sense in my more complex/initial case/scenario. More complex case: use `checkout` with recursive submodules checkout, where the submodules use a different credentials than the parent repository This is not that unusual when: using `multi branch pipeline` with `github branch source`: the latter imposes HTTPS git clone (because it re-uses the only credentials it asks, which is only of type user/apikey-as-password, because it needs API access to implement branch/tags discovery and such) submodule remotes URLs are git+ssh:// URLs (submodule URLs are hardcoded in the parent git repository, not configurable from the jenkins pipeline) In this case I have the parent repo cloned with HTTPS, using a specified user/password credentials, then when trying to checkout the submodules, I here need a ssh key. I tried to work around this limitation by using the `sshagent` to make available the need ssh key for submodules: it didn't work, and this lead me to the simple case I initially reported here. Maybe I should open a second issue for the more general case? Other workarounds could be: be able to specify credentials for submodules on `checkout` (I have many submodules, so it would be great with a "default credential" for all submodules for this `checkout`, or something along these lines) be able to give a second credentials to `github branch source` of type ssh key so that it uses the apikey for the api, and the ssh key for git clone (and its submodules) Note that I have not attempted the steps you've described, so I don't know if there is a way to accomplish what you're describing. I won't duplicate the bug report until later. I wanted to ask the clarifying questions before I invest the time to duplicate what you've described. I totally understand you needed more information, especially as my initial report contained an error, and was not very detailed. I hope it's more clear now. If you need any more information please let me know.

          Jesse Glick added a comment -

          See JENKINS-30600. Plugins which control the launch environment are ignored by the Git plugin. Use sh 'git …' as needed, or pass SSH credentials to the step.

          Jesse Glick added a comment - See JENKINS-30600 . Plugins which control the launch environment are ignored by the Git plugin. Use sh 'git …' as needed, or pass SSH credentials to the step.

            Unassigned Unassigned
            thomas_deepomatic Thomas Riccardi
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: