Implement JWT auth (#188)

This commit is contained in:
Raman Harnak 2021-05-04 15:49:35 +03:00 committed by GitHub
parent 8417c61f8a
commit 9e8f22534f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 275 additions and 2 deletions

View file

@ -5,7 +5,7 @@ const got = require('got').default;
const jsonata = require('jsonata');
const { auth: { retrieveToken }, secrets: { getSecrets } } = require('./index');
const AUTH_METHODS = ['approle', 'token', 'github'];
const AUTH_METHODS = ['approle', 'token', 'github', 'jwt'];
async function exportSecrets() {
const vaultUrl = core.getInput('url', { required: true });

View file

@ -1,5 +1,6 @@
// @ts-check
const core = require('@actions/core');
const rsasign = require('jsrsasign');
/***
* Authenticate with Vault and retrieve a Vault token that can be used for requests.
@ -17,6 +18,15 @@ async function retrieveToken(method, client) {
const githubToken = core.getInput('githubToken', { required: true });
return await getClientToken(client, method, { token: githubToken });
}
case 'jwt': {
const role = core.getInput('role', { required: true });
const privateKeyRaw = core.getInput('jwtPrivateKey', { required: true });
const privateKey = Buffer.from(privateKeyRaw, 'base64').toString();
const keyPassword = core.getInput('jwtKeyPassword', { required: false });
const tokenTtl = core.getInput('jwtTtl', { required: false }) || '3600'; // 1 hour
const jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl));
return await getClientToken(client, method, { jwt: jwt, role: role });
}
default: {
if (!method || method === 'token') {
return core.getInput('token', { required: true });
@ -32,6 +42,32 @@ async function retrieveToken(method, client) {
}
}
/***
* Generates signed Json Web Token with specified private key and ttl
* @param {string} privateKey
* @param {string} keyPassword
* @param {number} ttl
*/
function generateJwt(privateKey, keyPassword, ttl) {
const alg = 'RS256';
const header = { alg: alg, typ: 'JWT' };
const now = rsasign.KJUR.jws.IntDate.getNow();
const payload = {
iss: 'vault-action',
iat: now,
nbf: now,
exp: now + ttl,
event: process.env.GITHUB_EVENT_NAME,
workflow: process.env.GITHUB_WORKFLOW,
sha: process.env.GITHUB_SHA,
actor: process.env.GITHUB_ACTOR,
repository: process.env.GITHUB_REPOSITORY,
ref: process.env.GITHUB_REF
};
const decryptedKey = rsasign.KEYUTIL.getKey(privateKey, keyPassword);
return rsasign.KJUR.jws.JWS.sign(alg, JSON.stringify(header), JSON.stringify(payload), decryptedKey);
}
/***
* Call the appropriate login endpoint and parse out the token in the response.
* @param {import('got').Got} client