Search code examples
githubgithub-apigithub-api-v3

GitHub commits not verified despite matching GPG Key ID


On the command line I generated a new key pair using the github-api-signature package's generateKeyPair function, providing a name and email of my GitHub account and a random passphrase.

I took the public part of the generated key pair and put it in my GitHub account on the keys page.

I took the private key and provided it to the snippet of code below.

The request to create the commit returns successfully as does the programmatic creation of the PR, but when I visit the commits page of the PR there is a box saying 'Unverified' with the message "The signature in this commit could not be verified. Someone may be trying to trick you."

enter image description here

I compared the GPG key ID it provides me on this page with those listed in my GitHub keys page and it matches, so why does it show my commit as unverified?

Example code:

const privateKey = '[GENERATED PRIVATE KEY]';
const passphrase = '[RANDOM PASSPHRASE FROM EARLIER]';

const author = {
  name: '[NAME THAT MATCHES GITHUB]',
  email: '[EMAIL THAT MATCHES GITHUB]',
  date: new Date().toISOString(),
};

const commitPayload: CommitPayload = {
  message: commitMessage,
  author,
  committer: { ...author },
  tree: tree.data.sha,
  parents: [branch.data.object.sha],
};

const signature = await githubApiSignature.createSignature(
  commitPayload,
  privateKey,
  passphrase,
);

const result = await got(
  `[GITHUB API URL]/repos/[USERNAME]/[REPO_NAME]/git/commits`,
  {
    protocol: 'https:',
    method: 'POST',
    body: {
      ...commitPayload,
      signature,
    },
    json: true
  },
);

Solution

  • This was caused by a trailing \n in the commit message which was trimmed by the library I was using to generate the signature but not by me before POSTing to GitHub.

    Further information on how I debugged this, should it help anyone else further down the line:

    Originally I tried using the openpgp library directly following the guide for creating and verifying detached signatures, and faced the same validity issue.

    Knowing that the signature was verified locally I knew that I must be sending something to the GitHub API incorrectly. The Git Commits API provides some useful feedback in the verification block of the response:

    verification: {
        verified: boolean
        reason: string
        signature: string
        payload: string
    }
    

    ...as well as a little further information in the documentation page on what each of the reasons mean.

    Further investigation of the payload (including simplifying all my values) led me to find that the message was at fault.