5
0
Fork 0
mirror of https://github.com/hashicorp/vault-action.git synced 2025-11-14 18:13:45 +00:00

Merge pull request #1 from blz-ea/feature/core-github-oidc

fix: get token via `@actions/core`
This commit is contained in:
Alex Kulikovskikh 2021-10-02 11:21:51 -04:00 committed by GitHub
commit eaa7d6890c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 35811 additions and 15150 deletions

View file

@ -86,8 +86,28 @@ with:
githubToken: ${{ secrets.MY_GITHUB_TOKEN }}
caCertificate: ${{ secrets.VAULTCA }}
```
- **jwt**: you must provide a `role` parameter, additionally you can pass `jwtPrivateKey`, `jwtKeyPassword` & `jwtTtl` parameters.
Github provided JWT will be used if `jwtPrivateKey` was not specified
- **jwt**: (Github OIDC) you must provide a `role` parameter, additionally you can pass `jwtGithubAudience` parameter.
```yaml
...
with:
url: https://vault.mycompany.com:8200
method: jwt
role: github-action
```
**Notice:** For Github provided OIDC token to work workflow should have `id-token: write` & `contents: read` specified in the `permissions` section of a workflow
```yaml
...
permissions:
id-token: write
contents: read
...
```
- **jwt**: you must provide a `role` parameter, additionally you can pass `jwtPrivateKey`, `jwtKeyPassword`, & `jwtTtl` parameters.
```yaml
...
with:
@ -99,16 +119,6 @@ with:
jwtTtl: 3600 # 1 hour, default value
```
**Notice:** In order for Github provided JWT to work workflow should have `id-token: write` & `contents: read` specified in the `permissions` section of a workflow
```yaml
...
permissions:
id-token: write
contents: read
...
```
- **kubernetes**: you must provide the `role` paramaters. You can optionally override the `kubernetesTokenPath` paramater for custom mounted serviceAccounts. Consider [kubernetes auth](https://www.vaultproject.io/docs/auth/kubernetes) when using self-hosted runners on Kubernetes:
```yaml
...
@ -289,6 +299,7 @@ Here are all the inputs available through `with`:
| `githubToken` | The Github Token to be used to authenticate with Vault | | |
| `jwtPrivateKey` | Base64 encoded Private key to sign JWT | | |
| `jwtKeyPassword` | Password for key stored in jwtPrivateKey (if needed) | | |
| `jwtGithubAudience` | Audience (`aud`) for Github OIDC token | sigstore| |
| `jwtTtl` | Time in seconds, after which token expires | | 3600 |
| `kubernetesTokenPath` | The path to the service-account secret with the jwt token for kubernetes based authentication |`/var/run/secrets/kubernetes.io/serviceaccount/token` | |
| `authPayload` | The JSON payload to be sent to Vault when using a custom authentication method. | | |

View file

@ -69,6 +69,9 @@ inputs:
jwtKeyPassword:
description: 'Password for key stored in jwtPrivateKey (if needed)'
required: false
jwtGithubAudience:
description: ''
required: false
jwtTtl:
description: 'Time in seconds, after which token expires'
required: false

1410
dist/index.js vendored

File diff suppressed because it is too large Load diff

19666
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -52,7 +52,7 @@
"@actions/core": ">=1 <2"
},
"devDependencies": {
"@actions/core": "^1.2.3",
"@actions/core": "^1.6.0",
"@types/got": "^9.6.11",
"@types/jest": "^26.0.13",
"@zeit/ncc": "^0.22.3",

View file

@ -2,7 +2,6 @@
const core = require('@actions/core');
const rsasign = require('jsrsasign');
const fs = require('fs');
const got = require('got').default;
const defaultKubernetesTokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token'
/***
@ -26,17 +25,15 @@ async function retrieveToken(method, client) {
case 'jwt': {
/** @type {string} */
let jwt;
const actionsIDTokenRequestToken = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];
const actionsIDTokenRequestURL = process.env['ACTIONS_ID_TOKEN_REQUEST_URL'];
const role = core.getInput('role', { required: true });
const privateKeyRaw = core.getInput('jwtPrivateKey', { required: (!(actionsIDTokenRequestToken && actionsIDTokenRequestURL)) });
const privateKeyRaw = core.getInput('jwtPrivateKey', { required: false });
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 githubAudience = core.getInput('jwtGithubAudience', { required: false });
if (!privateKeyRaw && actionsIDTokenRequestToken && actionsIDTokenRequestURL) {
jwt = await getJwt(actionsIDTokenRequestToken, `${actionsIDTokenRequestURL}&audience=sigstore`);
if (!privateKey) {
jwt = await core.getIDToken(githubAudience || 'sigstore')
} else {
jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl));
}
@ -94,34 +91,6 @@ function generateJwt(privateKey, keyPassword, ttl) {
return rsasign.KJUR.jws.JWS.sign(alg, JSON.stringify(header), JSON.stringify(payload), decryptedKey);
}
/***
* Call the appropriate endpoint and retrieves job's JWT
* @param {string} actionsIDTokenRequestToken
* @param {string} actionsIDTokenRequestURL
*/
async function getJwt(actionsIDTokenRequestToken, actionsIDTokenRequestURL) {
/** @type {'json'} */
const responseType = 'json';
const options = {
headers: {
Authorization: `Bearer ${actionsIDTokenRequestToken}`,
},
responseType,
};
const client = got.extend(options)
core.debug(`Retrieving Vault JWT from ${actionsIDTokenRequestURL} endpoint`);
/** @type {import('got').Response<GithubActionsIdTokenResponse>} */
const response = await client.get(actionsIDTokenRequestURL, options);
if (response && response.body && response.body.value) {
core.debug('✔ Github Actions ID Token successfully retrieved');
return response.body.value;
} else {
throw Error(`Unable to retrieve token from ${actionsIDTokenRequestURL}'s endpoint.`);
}
}
/***
* Call the appropriate login endpoint and parse out the token in the response.
* @param {import('got').Got} client
@ -167,12 +136,6 @@ async function getClientToken(client, method, path, payload) {
* }} auth
*/
/***
* @typedef {Object} GithubActionsIdTokenResponse
* @property {string} value
* @property {string} count
*/
module.exports = {
retrieveToken,
};