The Package.swift file at the root of a Swift Package Manager (SPM) package allows you specify the dependencies of the package.

If your dependency is a public package hosted somewhere like GitHub it’s easy to add that to your Package.swift. For example:

dependencies: [
  .package(url: "",
           from: "1.0.0")

But what if you want to depend on a private repository?

One option is to specify your GitHub credentials directly in the Package.swift file:

dependencies: [
  .package(url: "",
           from: "1.0.0")

Obviously this has a number of problems. It ties your Package.swift to a specific set of credentials, and exposes your GitHub password in plain text.

An alternative is to use a GitHub personal access token (OAuth2) with repo scope:

dependencies: [
  .package(url: "https://<token>",
           from: "1.0.0")

This is slightly better as the token’s scope is limited (in comparison to a full set of GitHub credentials), however the token is still effectively a password you are exposing in the package’s manifest. The token also has access to all of your private repositories, not just one.

A much better solution is to use a GitHub Deploy Key. This is an SSH key which gives access to a single GitHub repository, and can be stored outside the Package.swift file.

To use SSH, the dependency URL in your Package.swift needs to use SSH instead of HTTPS:

dependencies: [
  .package(url: "",
           from: "1.0.0")

Now, create a .ssh directory in the root of your SPM package and change into it:

$ mkdir .ssh
$ cd .ssh

Next, generate a new SSH key by running ssh-keygen with the following options:

$ ssh-keygen -b 4096 -t rsa -N "" -f key
Generating public/private rsa key pair.
Your identification has been saved in key.
Your public key has been saved in

This generates a 4096-bit RSA key with a blank passphrase and saves it to disk. You now have two files in your .ssh directory: key (the private key) and (the public key).

Still in the .ssh directory, create a file named config with this content:

    User git
    IdentityFile ./.ssh/key

Now, on GitHub, navigate to the Settings of your private repository, click on “Deploy Keys” in the sidebar, then click “Add deploy key”. Give your key a name then paste in the contents of the public key file. Click “Add key”.

Adding a new Deploy Key on GitHub
Adding a new Deploy Key on GitHub

Now when you run swift build from the root of your package, SPM will use your SSH key to authenticate with GitHub and access the private repository.


If you are deploying your Swift application to a Cloud Foundry PaaS such as IBM Cloud, the buildpack will automatically detect your .ssh directory at deploy time and use the SSH key when building your application. Sweet!

Join the discussion on Slack Learn more at Star Kitura on GitHub

2 comments on"Authenticating with private GitHub repositories in Swift Package Manager using SSH keys"

  1. Hey Ian,

    Just a short add-on
    If you are trying to authenticate and fetch dependencies from within the Docker container, first you have to open a connection to your authentication agent with:

    eval $(ssh-agent)

    and then, add your key using:

    echo -e “StrictHostKeyChecking no” >> /etc/ssh/ssh_config && \
    ssh-add /.ssh/key

    Otherwise, the container will not be able to utilize keys.

    • Is it also possible to push StrictHostKeyChecking no somewhere else? I got a permission denied error. When using sudo su first, I still get the following error: error: failed to clone; Cloning into bare repository ‘/root/project/.build-ubuntu/repositories/FHIRCore.git-1275565554428245315’…
      Host key verification failed.
      fatal: Could not read from remote repository.

      It just works with ssh/https on MacOSX, but not while using a Docker Container…

Join The Discussion

Your email address will not be published. Required fields are marked *