git2r not automatically locating ssh credentials on macOS

I keep running into issues with git2r finding and using my ssh keys. I don't think I'm the only one but I can't figure out how to get git2r to find my ssh keys on its own.

The odd part is that git2r::cred_ssh_key() works fine, but relying on other git2r functions like git2r::fetch() to discover the keys on their own isn't working.

I've checked permissions in the ~/.ssh folder (700) and keys (600 for keys, 644 for .pub). I do have additional keys in the folder but I want git2r to use id_rsa, which I think should be the default. I also installed git2r from source after installing libgit2.

Has anyone resolved a similar issue or see something that I'm missing?

repo <- git2r::repository("~/play/my-repo")
git2r::fetch(repo, "upstream")
#> Error in git2r::fetch(repo, "upstream"): Error in 'git2r_remote_fetch': error authenticating:
git2r::fetch(repo, "upstream", credentials = git2r::cred_ssh_key())

git2r::cred_ssh_key()
#> $publickey
#> [1] "/Users/userxyz/.ssh/id_rsa.pub"
#> 
#> $privatekey
#> [1] "/Users/userxyz/.ssh/id_rsa"
#> 
#> $passphrase
#> character(0)
#> 
#> attr(,"class")
#> [1] "cred_ssh_key"

git2r::ssh_path()
#> [1] "/Users/userxyz/.ssh/"

fs::file_info("~/.ssh")[, c('path', 'type', 'permissions')]
#>     path      type permissions
#> 1 ~/.ssh directory   rwx------
fs::file_info(fs::dir_ls("~/.ssh"))[, c('path', 'type', 'permissions')]
#>                              path type permissions
#> 1      /Users/userxyz/.ssh/config file   rw-------
#> 2     /Users/userxyz/.ssh/gmb_rsa file   rw-------
#> 3 /Users/userxyz/.ssh/gmb_rsa.pub file   rw-r--r--
#> 4      /Users/userxyz/.ssh/id_rsa file   rw-------
#> 5  /Users/userxyz/.ssh/id_rsa.pub file   rw-r--r--
#> 6 /Users/userxyz/.ssh/known_hosts file   rw-------

Created on 2019-09-04 by the reprex package (v0.3.0)

Session info
devtools::session_info()
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.6.1 (2019-07-05)
#>  os       macOS Mojave 10.14.6        
#>  system   x86_64, darwin15.6.0        
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  ctype    en_US.UTF-8                 
#>  tz       America/New_York            
#>  date     2019-09-04                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 3.6.0)
#>  backports     1.1.4   2019-04-10 [1] CRAN (R 3.6.0)
#>  callr         3.3.1   2019-07-18 [1] CRAN (R 3.6.0)
#>  cli           1.1.0   2019-03-19 [1] CRAN (R 3.6.0)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.6.0)
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 3.6.0)
#>  devtools      2.1.0   2019-07-06 [1] CRAN (R 3.6.0)
#>  digest        0.6.20  2019-07-04 [1] CRAN (R 3.6.0)
#>  evaluate      0.14    2019-05-28 [1] CRAN (R 3.6.0)
#>  fs            1.3.1   2019-05-06 [1] CRAN (R 3.6.0)
#>  git2r         0.26.1  2019-06-29 [1] CRAN (R 3.6.1)
#>  glue          1.3.1   2019-03-12 [1] CRAN (R 3.6.0)
#>  highr         0.8     2019-03-20 [1] CRAN (R 3.6.0)
#>  htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.6.0)
#>  knitr         1.24    2019-08-08 [1] CRAN (R 3.6.0)
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 3.6.0)
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.6.0)
#>  pkgbuild      1.0.4   2019-08-05 [1] CRAN (R 3.6.0)
#>  pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.6.0)
#>  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.6.0)
#>  processx      3.4.1   2019-07-18 [1] CRAN (R 3.6.0)
#>  ps            1.3.0   2018-12-21 [1] CRAN (R 3.6.0)
#>  R6            2.4.0   2019-02-14 [1] CRAN (R 3.6.0)
#>  Rcpp          1.0.2   2019-07-25 [1] CRAN (R 3.6.0)
#>  remotes       2.1.0   2019-06-24 [1] CRAN (R 3.6.0)
#>  rlang         0.4.0   2019-06-25 [1] CRAN (R 3.6.0)
#>  rmarkdown     1.15    2019-08-21 [1] CRAN (R 3.6.0)
#>  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.6.0)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.6.0)
#>  stringi       1.4.3   2019-03-12 [1] CRAN (R 3.6.0)
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 3.6.0)
#>  testthat      2.2.1   2019-07-25 [1] CRAN (R 3.6.0)
#>  usethis       1.5.1   2019-07-04 [1] CRAN (R 3.6.0)
#>  withr         2.1.2   2018-03-15 [1] CRAN (R 3.6.0)
#>  xfun          0.9     2019-08-21 [1] CRAN (R 3.6.0)
#>  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.6.0)
#> 
#> [1] /Users/userxyz/Library/R/3.6/library
#> [2] /Library/Frameworks/R.framework/Versions/3.6/Resources/library

The git2r package does not appear to attempt to automatically acquire credentials when calling fetch()

Looking through the source, it does not appear that the fetch function or subsequent call attempts to look up credentials. Whereas defaults are provided when calling cred_ssh_key().

Fetching call

The R function is:

fetch <- function(repo = ".", name = NULL, credentials = NULL,
                  verbose = TRUE, refspec = NULL) {
    invisible(.Call(git2r_remote_fetch, lookup_repository(repo),
                    name, credentials, "fetch", verbose, refspec))

Which calls a C function, git2r_remote_fetch, that has a call to check if the credentials are good.

    if (git2r_arg_check_credentials(credentials))
        git2r_error(__func__, NULL, "'credentials'", git2r_err_credentials_arg);

That in turn doesn't appear to care that the credentials are NULL. This supports http and https protocols where no credentials are required.

int git2r_arg_check_credentials(SEXP arg)
{
    /* It's ok if the credentials is R_NilValue */
    if (Rf_isNull(arg))
        return 0;

So it happily continues along and attempts to connect to the repository. The uri specifies SSH as the protocol, and it goes ahead and attempts to use that. Then it fails in libgit2's ssh_agent_auth function.


	if (rc != LIBSSH2_ERROR_NONE)
		ssh_error(session, "error authenticating");

cred_ssh_key provides defaults

As opposed to cred_ssh_key which is where defaults are provided that provide the functionality you're expecting.

cred_ssh_key <- function(publickey = ssh_path("id_rsa.pub"),
                         privatekey = ssh_path("id_rsa"),
                         passphrase = character(0)) { 

Thanks, I looked through the source too and had a similar read. I guess I'm confused by the help text for fetch() and others:

credentials The credentials for remote repository access. Default is NULL. To use and query an ssh-agent for the ssh key credentials, let this parameter be NULL (the default).

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.