Creating a Github Deploy Key Using Web Services?

The Problem

I read in the Github docs that I can call a Github API Endpoint to create Deployment Keys for a project.

Everytime I run my playbook, it re-creates the ssh-key-pair and thus if I want to clone a git repo with SSH, I have to create the key manually.

I’m looking to automate the following procedure using the documentation above, but for some reason (maybe the wrong permissions on my github access token) I end up with a 401 when I try to call it from curl.

I have some ansible code that is supposed to do the same thing, but if I can’t get cURL to do it, then how will I be able to get Ansible to do it?

#ssh-keygen -t ed25519
#*Enter file in which to save the key: ./keys/id_ed25519_github_clone_ssh_test
#vi ~/.ssh/config

Host *
       AddressFamily inet
...
Host github.com
        Hostname github.com
        User git
        IdentityFile ~/.ssh/id_ed25519_github       
  1. cat ./keys/id_ed25519_github_clone_ssh_test.pub so you can copy the public key for your repo.
  2. Manually:’
    1.1. Login to github
    1. Go to the repository you want to clone.
    2. Click the Settings tab
      1. Security -> Deploy Keys
      2. Click the Add Deploy Key button
      3. Paste the public key here and submit the form.
  3. With Web Services (need to get this part working):
    1. ???

And after that I’m able to clone the repo via SSH in vagrant

git clone git@github.com:leeand00/somerepo

3. With Web Services?

With cURL (currently doesn’t work):

$ curl -L \
  -H "Accept: application/json" \
  -H "Authorization: token <GITHUB_ACCESS_TOKEN>" \
  -H "X-GitHub-Api-Version 2022-11-28" https://api.github.com/leeand00/somerepo/keys
{
   "message": "Bad credentials"
   "documentation_url": "https://docs.github.com/rest"
   "status": 401
}

With Ansible (this is what I plan to do):

...
- name: Add SSH public key to GitHub account
  tags: github
  uri:
     url: https://api.github.com/leeand00/somerepo/keys
     validate_certs: no
     method: POST
     return_content: true
     body:
        title: "{{ KEY_TITLE }}"
        key: "{{  key_content.stdout }}"
     body_format: json
     headers:
        Content-Type: "application/vnd.github+json"
        Authorization: "Bearer {{ GITHUB_ACCESS_TOKEN }}"
        X-GitHub-Api-Version: 2022-11-28
     register: huh
     failed_when: huh.find('key is already in use') == 0
...

Does anyone know if it is a problem with the permissions on my GITHUB_ACCESS_TOKEN has something to do with the problem, and what those settings might be?

Also, if I were to run vagrant destroy would there be something that could also delete the key then?

It seems like the issue you’re facing is related to the permissions on your GitHub access token. When you’re getting a 401 Bad Credentials error, it’s most likely because the access token does not have the necessary permissions to create a deploy key for your repository.

To resolve this, ensure your GitHub token has the repo and write:public_key permissions. These permissions are required to add deploy keys. You can check the permissions of your token and update them accordingly in your GitHub account settings.

Regarding your Ansible script, ensure that your token has the correct scope and you’re using the correct URL format. It may also help to double-check your GITHUB_ACCESS_TOKEN permissions.

As for your question about vagrant destroy—it won’t delete the deploy key automatically. You’ll need to explicitly remove it from your GitHub repository using the API or manually if needed.

Good luck, and feel free to share any further details if the issue persists!

Attempt at using the API to Create a Deployment Key for my Repository:

So I tried the following in my github account using the Create a deploy key documentation to select the permissions.

The docs read the following:

Fine-grained access tokens for “Create a deploy key”
This endpoint works with the following fine-grained token types:

  • ...
  • Fine-grained personal access tokens
  The fine-grained token must have the following permission set:
  • "Administration" repository permissions (write)

So I did the following in my github account to set this up:

  1. Clicked my profile picture
  2. Clicked Settings
  3. Clicked Developer Settings in the right sidebar
  4. Expanded Personal Access Tokens in the right sidebar
  5. Clicked Fine-grained tokens
  6. Clicked Generate New Token

Next, I was presented with the form to create a Fine-grained token where I used the following settings:

  • Token name: jobsearch_dotfiles - Create a Deploy Key
  • Repository Access - leeand00/jobsearch_dotfiles
  • Permissions
    • Repository Permissions
      • Administration → Access Read and Write

Next, I clicked the Generate token button.

A dialog box appeared which read

New personal Access Token

Your new personal access token jobsearch_dotfiles - Create a Deploy Key will be ready immediately It will expire Wednesday, April 23, 2025.

jobsearch_dotfiles - Create a Deploy Key grants you 2 permissions for 1 repository:

Administration - Read and write
Metadata - Read-only


I then copied the personal access token tried the API call:

curl -L   -X POST   -H "Accept: application/vnd.github+json"   -H "Authorization: Bearer github_pat_..."   -H "X-GitHub-Api-Version: 2022-11-28"   https://api.github.com/leeand00/jobsearch_dotfiles/keys    -d '{"title":"leeand00@leeand00","key":"ssh-ed25519../xb..A vagrant@vagrant","read_only":true}'
{
  "message": "Not Found",
  "documentation_url": "https://docs.github.com/rest",
  "status": "404"
}

Still doesn’t work; any ideas what I’m doing wrong?

After talking to some more people I found out that my endpoint URL was wrong and it was missing the /repos/ part of the URL.

I also ditched the fancy yaml for generating the call for the deployment key and opted for just using a shell: and curl inside it instead; it wasn’t too bad, but I needed to make sure that the variable that stored the content of the key had .stdout appended to the end of it since otherwise it would print the contents of the dict.