I want to set a repository secret via the GitHub REST API. I use the example from the docs:
const sodium = require('tweetsodium');
const key = "base64-encoded-public-key";
const value = "plain-text-secret";
// Convert the message and key to Uint8Array's (Buffer implements that interface)
const messageBytes = Buffer.from(value);
const keyBytes = Buffer.from(key, 'base64');
// Encrypt using LibSodium.
const encryptedBytes = sodium.seal(messageBytes, keyBytes);
// Base64 the encrypted secret
const encrypted = Buffer.from(encryptedBytes).toString('base64');
console.log(encrypted);
I receive this error:
(node:6008) UnhandledPromiseRejectionWarning: Error: bad public key size
at checkBoxLengths (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2158:54)
at Function.nacl.box.before (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2231:3)
at Object.nacl.box (C:\Users\User\probot\node_modules\tweetnacl\nacl-fast.js:2225:20)
at Object.tweetSodium.seal (C:\Users\User\probot\node_modules\tweetsodium\dist\index.umd.js:53:33)
at createSecret (C:\Users\User\probot\src\service\secret.js:55:33)
at Object.<anonymous> (C:\Users\User\probot\src\service\secret.js:73:1)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
(node:6008) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6008) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Problem: How do I correctly encrypt and decrypt the secret so i can use it in my API?
Solution: @Topaco mentioned that you need to use a base64 encoded key such as 2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU=
. This solves the error descibed above.
EDIT
I will use different secrets in different repositories. Should I generate a new base64 encoded key for each repo?
The example code was not quite clear what the key
actually is and where you get it. You need the "repository public key" that you get from the /repos/{owner}/{repo}/codespaces/secrets/public-key
endpoint.
Use the repository public key together with the value from your new secret:
const key = "base64-encoded-public-key"; // this is the repository public key you need to fetch from GitHub
const value = "plain-text-secret"; // the secret value
Then you can create or update your key:
const res = await octokit.actions.createOrUpdateRepoSecret({
owner: "GITHUBUSER",
repo: "GITHUB_REPO",
secret_name: "KEY_NAME",
encrypted_value: encrypted,
});