Ubuntu – How to add an SSH key to Gitlab through a bash executable

bashcommand linegitgitlabssh

I am creating a bash executable, which creates an SSH key, and uploads it to a user's Gitlab account. I am aware of how to create the SSH key via the bash executable:

ssh-keygen -o -f ~/.ssh/id_rsa

and I also know how to retrieve from it, however I don't know how to upload it to a user's Gitlab account.

I have found multiple documentations for uploading a user's SSH to Github however not Gitlab (I assume mostly similar…?). So I would use this for Github

curl -u "USERNAME:PASSWORD" --data "{\"title\": \"TITLE\", \"key\": \"$(cat ~/.ssh/id_rsa.pub)\"}" https://api.github.com/user/keys

and I would make USERNAME, PASSWORD, and TITLE input fields for the user to customize.

I want to say that it would be as simple for Gitlab (I found POST /users/:id/keys on their API site, but don't know how to implement it as a curl command), but I don't know how closely related Gitlab and Github are.

Best Answer

The first problem you need to solve when using the Gitlab REST API is the authentification, nicely explained in the docs here. I use a personal access token in this post which creation is explained here, but for you with a script authenticating as a specific user an Impersonation token (see here for the creation) may be better suited.

To add an ssh key I need:

POST /user/keys

To send data (and subsequently use the POST method) curl provides the -d option, required fields are title and key. As the default header is Content-Type: application/x-www-form-urlencoded but the API expects json I have to specify that using the -H option:

$ curl -d '{"title":"test key","key":"'"$(cat ~/.ssh/id_rsa.pub)"'"}' -H 'Content-Type: application/json' https://gitlab.com/api/v4/user/keys?private_token=<my_access_token>
{"id":3889765,"title":"test key","key":"ssh-rsa <my_ssh_key>","created_at":"2019-08-01T21:26:40.952Z"}

Now to test the change I just list my ssh keys. The docs say I have to use GET /user/keys, as GET is curl’s default method I just do:

$ curl https://gitlab.com/api/v4/user/keys?private_token=<my_access_token>
[{"id":3889765,"title":"test key","key":"ssh-rsa <my_ssh_key>","created_at":"2019-08-01T21:26:40.952Z"}]

I did this just for testing, so I’m going to delete the key with DELETE /user/keys/:key_id – note that :key_id needs to be substituted by the id of the key to delete:

$ curl -X DELETE https://gitlab.com/api/v4/user/keys/3889765?private_token=<my_access_token>

Here’s a nice article about curl and the common REST methods.