1 | # Git authentication with SSH keys
|
2 |
|
3 | When using [environment variables](../usage/ci-configuration.md#authentication) to set up the Git authentication, the remote Git repository will automatically be accessed via [https](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_http_protocols), independently of the [`repositoryUrl`](../usage/configuration.md#repositoryurl) format configured in the **semantic-release** [Configuration](../usage/configuration.md#configuration) (the format will be automatically converted as needed).
|
4 |
|
5 | Alternatively the Git repository can be accessed via [SSH](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_the_ssh_protocol) by creating SSH keys, adding the public one to your Git hosted account and making the private one available on the CI environment.
|
6 |
|
7 | **Note:** SSH keys allow to push the [Git release tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) associated to the released version. Some plugins might also require an API token. See each plugin documentation for additional information.
|
8 |
|
9 | ## Generating the SSH keys
|
10 |
|
11 | In your local repository root:
|
12 |
|
13 | ```bash
|
14 | $ ssh-keygen -t rsa -b 4096 -C "<your_email>" -f git_deploy_key -N "<ssh_passphrase>"
|
15 | ```
|
16 |
|
17 | `your_email` must be the email associated with your Git hosted account. `ssh_passphrase` must be a long and hard to guess string. It will be used later.
|
18 |
|
19 | This will generate a public key in `git_deploy_key.pub` and a private key in `git_deploy_key`.
|
20 |
|
21 | ## Adding the SSH public key to the Git hosted account
|
22 |
|
23 | Step by step instructions are provided for the following Git hosted services:
|
24 | - [GitHub](#adding-the-ssh-public-key-to-github)
|
25 |
|
26 | ### Adding the SSH public key to GitHub
|
27 |
|
28 | Open the `git_deploy_key.pub` file (public key) and copy the entire content.
|
29 |
|
30 | In GitHub **Settings**, click on **SSH and GPG keys** in the sidebar, then on the **New SSH Key** button.
|
31 |
|
32 | Paste the entire content of `git_deploy_key.pub` file (public key) and click the **Add SSH Key** button.
|
33 |
|
34 | Delete the `git_deploy_key.pub` file:
|
35 |
|
36 | ```bash
|
37 | $ rm git_deploy_key.pub
|
38 | ```
|
39 |
|
40 | See [Adding a new SSH key to your GitHub account](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/) for more details.
|
41 |
|
42 | ## Adding the SSH private key to the CI environment
|
43 |
|
44 | In order to be available on the CI environment, the SSH private key must be encrypted, committed to the Git repository and decrypted by the CI service.
|
45 |
|
46 | Step by step instructions are provided for the following environments:
|
47 | - [Travis CI](#adding-the-ssh-private-key-to-travis-ci)
|
48 | - [Circle CI](#adding-the-ssh-private-key-to-circle-ci)
|
49 |
|
50 | ### Adding the SSH private key to Travis CI
|
51 |
|
52 | Install the [Travis CLI](https://github.com/travis-ci/travis.rb#installation):
|
53 |
|
54 | ```bash
|
55 | $ gem install travis
|
56 | ```
|
57 |
|
58 | [Login](https://github.com/travis-ci/travis.rb#login) to Travis with the CLI:
|
59 |
|
60 | ```bash
|
61 | $ travis login
|
62 | ```
|
63 |
|
64 | Add the [environment](https://github.com/travis-ci/travis.rb#env) variable `SSH_PASSPHRASE` to Travis with the value set during the [SSH keys generation](#generating-the-ssh-keys) step:
|
65 |
|
66 | ```bash
|
67 | $ travis env set SSH_PASSPHRASE <ssh_passphrase>
|
68 | ```
|
69 |
|
70 | [Encrypt](https://github.com/travis-ci/travis.rb#encrypt) the `git_deploy_key` (private key) using a symmetric encryption (AES-256), and store the secret in a secure environment variable in the Travis environment:
|
71 |
|
72 | ```bash
|
73 | $ travis encrypt-file git_deploy_key
|
74 | ```
|
75 |
|
76 | The `travis encrypt-file` will encrypt the private key into the `git_deploy_key.enc` file and output in the console the command to add to your `.travis.yml` file. It should look like `openssl aes-256-cbc -K $encrypted_KKKKKKKKKKKK_key -iv $encrypted_VVVVVVVVVVVV_iv -in git_deploy_key.enc -out git_deploy_key -d`.
|
77 |
|
78 | Copy this command to your `.travis.yml` file in the `before_install` step. Change the output path to write the unencrypted key in `/tmp`: `-out git_deploy_key` => `/tmp/git_deploy_key`. This will avoid to commit / modify / delete the unencrypted key by mistake on the CI. Then add the commands to decrypt the ssh private key and make it available to `git`:
|
79 |
|
80 | ```yaml
|
81 | before_install:
|
82 | # Decrypt the git_deploy_key.enc key into /tmp/git_deploy_key
|
83 | - openssl aes-256-cbc -K $encrypted_KKKKKKKKKKKK_key -iv $encrypted_VVVVVVVVVVVV_iv -in git_deploy_key.enc -out /tmp/git_deploy_key -d
|
84 | # Make sure only the current user can read the private key
|
85 | - chmod 600 /tmp/git_deploy_key
|
86 | # Create a script to return the passphrase environment variable to ssh-add
|
87 | - echo 'echo ${SSH_PASSPHRASE}' > /tmp/askpass && chmod +x /tmp/askpass
|
88 | # Start the authentication agent
|
89 | - eval "$(ssh-agent -s)"
|
90 | # Add the key to the authentication agent
|
91 | - DISPLAY=":0.0" SSH_ASKPASS="/tmp/askpass" setsid ssh-add /tmp/git_deploy_key </dev/null
|
92 | ```
|
93 |
|
94 | See [Encrypting Files](https://docs.travis-ci.com/user/encrypting-files) for more details.
|
95 |
|
96 | Delete the local private key as it won't be used anymore:
|
97 |
|
98 | ```bash
|
99 | $ rm git_deploy_key
|
100 | ```
|
101 |
|
102 | Commit the encrypted private key and the `.travis.yml` file to your repository:
|
103 |
|
104 | ```bash
|
105 | $ git add git_deploy_key.enc .travis.yml
|
106 | $ git commit -m "ci(travis): Add the encrypted private ssh key"
|
107 | $ git push
|
108 | ```
|
109 |
|
110 | ### Adding the SSH private key to Circle CI
|
111 |
|
112 | First we encrypt the `git_deploy_key` (private key) using a symmetric encryption (AES-256). Run the following `openssl` command and *make sure to note the output which we'll need later*:
|
113 |
|
114 | ```bash
|
115 | $ openssl aes-256-cbc -e -p -in git_deploy_key -out git_deploy_key.enc -K `openssl rand -hex 32` -iv `openssl rand -hex 16`
|
116 | salt=SSSSSSSSSSSSSSSS
|
117 | key=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
|
118 | iv =VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
|
119 | ```
|
120 |
|
121 | Add the following [environment variables](https://circleci.com/docs/2.0/env-vars/#adding-environment-variables-in-the-app) to Circle CI:
|
122 | - `SSL_PASSPHRASE` - the value set during the [SSH keys generation](#generating-the-ssh-keys) step.
|
123 | - `REPO_ENC_KEY` - the `key` (KKK) value from the `openssl` step above.
|
124 | - `REPO_ENC_IV` - the `iv` (VVV) value from the `openssl` step above.
|
125 |
|
126 | Then add to your `.circleci/config.yml` the commands to decrypt the ssh private key and make it available to `git`:
|
127 |
|
128 | ```yaml
|
129 | version: 2
|
130 | jobs:
|
131 | coverage_test_publish:
|
132 | # docker, working_dir, etc
|
133 | steps:
|
134 | - run:
|
135 | # Decrypt the git_deploy_key.enc key into /tmp/git_deploy_key
|
136 | - openssl aes-256-cbc -d -K $REPO_ENC_KEY -iv $REPO_ENC_IV -in git_deploy_key.enc -out /tmp/git_deploy_key
|
137 | # Make sure only the current user can read the private key
|
138 | - chmod 600 /tmp/git_deploy_key
|
139 | # Create a script to return the passphrase environment variable to ssh-add
|
140 | - echo 'echo ${SSL_PASSPHRASE}' > /tmp/askpass && chmod +x /tmp/askpass
|
141 | # Start the authentication agent
|
142 | - eval "$(ssh-agent -s)"
|
143 | # Add the key to the authentication agent
|
144 | - DISPLAY=":0.0" SSH_ASKPASS="/tmp/askpass" setsid ssh-add /tmp/git_deploy_key </dev/null
|
145 | # checkout, restore_cache, run: yarn install, save_cache, etc.
|
146 | # Run semantic-release after all the above is set.
|
147 | ```
|
148 |
|
149 | The unencrypted key is written to `/tmp` to avoid to commit / modify / delete the unencrypted key by mistake on the CI environment.
|
150 |
|
151 | Delete the local private key as it won't be used anymore:
|
152 |
|
153 | ```bash
|
154 | $ rm git_deploy_key
|
155 | ```
|
156 |
|
157 | Commit the encrypted private key and the `.circleci/config.yml` file to your repository:
|
158 |
|
159 | ```bash
|
160 | $ git add git_deploy_key.enc .circleci/config.yml
|
161 | $ git commit -m "ci(circle): Add the encrypted private ssh key"
|
162 | $ git push
|
163 | ```
|