Compare commits

...

28 Commits

Author SHA1 Message Date
Jason O'Donnell 0723fd7348 Update to v2.2.0 (#214) 2021-05-06 13:51:05 -04:00
dependabot[bot] 0405c26bc9 chore(deps): bump jsonata from 1.8.3 to 1.8.4 (#171)
Bumps [jsonata](https://github.com/jsonata-js/jsonata) from 1.8.3 to 1.8.4.
- [Release notes](https://github.com/jsonata-js/jsonata/releases)
- [Changelog](https://github.com/jsonata-js/jsonata/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsonata-js/jsonata/compare/v1.8.3...v1.8.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-06 13:42:25 -04:00
dependabot[bot] 2eea93c25e chore(deps-dev): bump @actions/core from 1.2.6 to 1.2.7 (#206)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.6 to 1.2.7.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-06 13:42:11 -04:00
dependabot[bot] 4d9cf786d6 chore(deps-dev): bump @types/jest from 26.0.22 to 26.0.23 (#207)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.22 to 26.0.23.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-06 13:41:52 -04:00
dependabot[bot] 575042000a chore(deps): bump handlebars from 4.7.6 to 4.7.7 (#213)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.7.6 to 4.7.7.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.6...v4.7.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-06 13:41:29 -04:00
dependabot[bot] cc8ad16bec chore(deps): bump lodash from 4.17.20 to 4.17.21 (#212)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-06 13:41:20 -04:00
dependabot[bot] cd1614aee3 chore(deps): bump jsrsasign from 10.1.10 to 10.2.0 (#211)
Bumps [jsrsasign](https://github.com/kjur/jsrsasign) from 10.1.10 to 10.2.0.
- [Release notes](https://github.com/kjur/jsrsasign/releases)
- [Changelog](https://github.com/kjur/jsrsasign/blob/master/ChangeLog.txt)
- [Commits](https://github.com/kjur/jsrsasign/compare/10.1.10...10.2.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-06 13:38:52 -04:00
Jason O'Donnell f3a53220d9 changelog++ 2021-05-06 13:24:09 -04:00
Tom Proctor 3526e1be65 Mask each line of multi-line secrets (#208)
* Mask each line of multi-line secrets

* Don't include carriage return characters in masking

* Update CHANGELOG.md
2021-05-05 11:54:07 +01:00
Jason O'Donnell f60544fbda changelog++ 2021-05-04 09:02:26 -04:00
Raman Harnak 9e8f22534f Implement JWT auth (#188) 2021-05-04 08:49:35 -04:00
Maryam Ghanizadeh 8417c61f8a chore(deps): bump marked from 1.2.6 to 2.0.1 security reason (#202) 2021-04-22 16:32:18 -04:00
dependabot[bot] 0cca23248c chore(deps-dev): bump @types/jest from 26.0.19 to 26.0.22 (#201)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.19 to 26.0.22.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-22 15:46:23 -04:00
dependabot[bot] 8dad53ed10 chore(deps): bump got from 11.8.1 to 11.8.2 (#190)
Bumps [got](https://github.com/sindresorhus/got) from 11.8.1 to 11.8.2.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.1...v11.8.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-22 15:46:05 -04:00
Jason O'Donnell 937d792a86 Add GitHub authentication notice (#200)
* Add GitHub authentication notice

* Typo in perm name
2021-03-26 14:03:15 -04:00
Jason O'Donnell 5e5c06a3c8 Update to v2.1.2 (#180)
* Update to v2.1.2

* Update index.js
2021-01-21 14:45:22 -05:00
Jason O'Donnell ff547e1516 changelog++ 2021-01-11 11:50:03 -05:00
bilucodota 1d4917ec58 - Support complex keys, such as yaml/json files (#173) 2021-01-11 11:47:51 -05:00
Jason O'Donnell 2fb78ab91e Update to v2.1.1 (#168) 2020-12-15 11:55:39 -05:00
dependabot[bot] c261a0ad69 chore(deps): bump ini from 1.3.5 to 1.3.8 (#167)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-15 11:17:21 -05:00
Jon L 6ac603b23e bump readme to action v2.1.0 (#157) 2020-12-15 11:12:08 -05:00
dependabot[bot] 638924aeb4 chore(deps-dev): bump @types/jest from 26.0.14 to 26.0.19 (#164)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.14 to 26.0.19.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-15 11:09:42 -05:00
dependabot[bot] 668d59f96b chore(deps): bump got from 11.7.0 to 11.8.1 (#163)
Bumps [got](https://github.com/sindresorhus/got) from 11.7.0 to 11.8.1.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.7.0...v11.8.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-15 11:09:17 -05:00
dependabot[bot] 208b49ff6c chore(deps-dev): bump semantic-release from 17.1.2 to 17.3.0 (#158)
Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 17.1.2 to 17.3.0.
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v17.1.2...v17.3.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-15 11:08:50 -05:00
dependabot[bot] 53c0f5bcca chore(deps-dev): bump jest from 26.5.0 to 26.6.3 (#150)
Bumps [jest](https://github.com/facebook/jest) from 26.5.0 to 26.6.3.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v26.5.0...v26.6.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-15 11:04:07 -05:00
Jason O'Donnell b4cef0fa36 Revert "chore(deps-dev): bump jest-when from 2.7.2 to 3.0.1 (#147)" (#166)
This reverts commit 7bc0a10ff8.
2020-12-15 11:00:26 -05:00
dependabot[bot] 7bc0a10ff8 chore(deps-dev): bump jest-when from 2.7.2 to 3.0.1 (#147)
Bumps [jest-when](https://github.com/timkindberg/jest-when) from 2.7.2 to 3.0.1.
- [Release notes](https://github.com/timkindberg/jest-when/releases)
- [Commits](https://github.com/timkindberg/jest-when/compare/v2.7.2...v3.0.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-15 10:15:59 -05:00
Tom Proctor e5febde8e7 Update jira sync github action (#151) 2020-11-18 10:49:47 +00:00
13 changed files with 2572 additions and 1504 deletions
+8 -8
View File
@@ -5,7 +5,6 @@ on:
types: [opened, closed, reopened]
issue_comment: # Also triggers when commenting on a PR from the conversation view
types: [created]
workflow_dispatch:
name: Jira Sync
@@ -36,26 +35,27 @@ jobs:
JIRA_USER_EMAIL: ${{ secrets.JIRA_SYNC_USER_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_SYNC_API_TOKEN }}
- name: Set ticket type
if: github.event.action == 'opened' && !steps.vault-team-role.outputs.role
id: set-ticket-type
- name: Preprocess
if: github.event.action == 'opened' || github.event.action == 'created'
id: preprocess
run: |
if [[ "${{ github.event_name }}" == "pull_request_target" ]]; then
echo "::set-output name=type::PR"
else
echo "::set-output name=type::ISS"
fi
- name: Create ticket
if: github.event.action == 'opened' && !steps.vault-team-role.outputs.role
uses: tomhjp/gh-action-jira-create@v0.1.3
uses: tomhjp/gh-action-jira-create@v0.2.0
with:
project: VAULT
issuetype: "GH Issue"
summary: "${{ github.event.repository.name }} [${{ steps.set-ticket-type.outputs.type }} #${{ github.event.issue.number || github.event.pull_request.number }}]: ${{ github.event.issue.title || github.event.pull_request.title }}"
summary: "${{ github.event.repository.name }} [${{ steps.preprocess.outputs.type }} #${{ github.event.issue.number || github.event.pull_request.number }}]: ${{ github.event.issue.title || github.event.pull_request.title }}"
description: "${{ github.event.issue.body || github.event.pull_request.body }}\n\n_Created from GitHub Action for ${{ github.event.issue.html_url || github.event.pull_request.html_url }} from ${{ github.actor }}_"
# customfield_10089 is Issue Link custom field
# customfield_10091 is team custom field
extraFields: '{"fixVersions": [{"name": "TBD"}], "customfield_10091": ["ecosystem"], "customfield_10089": "${{ github.event.issue.html_url || github.event.pull_request.html_url }}"}'
extraFields: '{"fixVersions": [{"name": "TBD"}], "customfield_10091": ["ecosystem", "runtime"], "customfield_10089": "${{ github.event.issue.html_url || github.event.pull_request.html_url }}"}'
- name: Search
if: github.event.action != 'opened'
@@ -67,7 +67,7 @@ jobs:
- name: Sync comment
if: github.event.action == 'created' && steps.search.outputs.issue
uses: tomhjp/gh-action-jira-comment@v0.1.0
uses: tomhjp/gh-action-jira-comment@v0.2.0
with:
issue: ${{ steps.search.outputs.issue }}
comment: "${{ github.actor }} ${{ github.event.review.state || 'commented' }}:\n\n${{ github.event.comment.body || github.event.review.body }}\n\n${{ github.event.comment.html_url || github.event.review.html_url }}"
+23
View File
@@ -1,5 +1,28 @@
## Unreleased
## 2.2.0 (May 6th, 2021)
Security:
* multi-line secrets are now properly masked in logs [GH-208](https://github.com/hashicorp/vault-action/pull/208)
[CVE-2021-32074](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-32074)
Features:
* JWT auth method is now supported [GH-188](https://github.com/hashicorp/vault-action/pull/188)
## 2.1.2 (January 21st, 2021)
Bugs:
* fixed bug where newlines were being rendered for multi-line secrets [GH-173](https://github.com/hashicorp/vault-action/pull/173)
## 2.1.1 (December 15th, 2020)
Improvements:
* bump jest from 26.5.0 to 26.6.3 [GH-150](https://github.com/hashicorp/vault-action/pull/150)
* bump semantic-release from 17.1.2 to 17.3.0 [GH-158](https://github.com/hashicorp/vault-action/pull/158)
* bump got from 11.7.0 to 11.8.1 [GH-163](https://github.com/hashicorp/vault-action/pull/163)
* bump @types/jest from 26.0.14 to 26.0.19 [GH-164](https://github.com/hashicorp/vault-action/pull/164)
* bump ini from 1.3.5 to 1.3.8 [GH-167](https://github.com/hashicorp/vault-action/pull/167)
## 2.1.0 (October 6th, 2020)
Features:
+28 -6
View File
@@ -36,7 +36,7 @@ jobs:
steps:
# ...
- name: Import Secrets
uses: hashicorp/vault-action@v2.0.1
uses: hashicorp/vault-action@v2.1.2
with:
url: https://vault.mycompany.com:8200
token: ${{ secrets.VaultToken }}
@@ -71,14 +71,32 @@ with:
caCertificate: ${{ secrets.VAULTCA }}
```
- **github**: you must provide the github token as `githubToken`
**Notice: [Vault GitHub authentication](https://www.vaultproject.io/docs/auth/github)
requires `read:org` permissions for authentication. The auto-generated `GITHUB_TOKEN`
created for projects does not have these permissions and GitHub does not allow this
token's permissions to be modified. A new GitHub Token secret must be created with
`read:org` permissions to use this authentication method.**
```yaml
...
with:
url: https://vault.mycompany.com:8200
method: github
githubToken: ${{ secrets.GITHUB_TOKEN }}
githubToken: ${{ secrets.MY_GITHUB_TOKEN }}
caCertificate: ${{ secrets.VAULTCA }}
```
- **jwt**: you must provide a `role` & `jwtPrivateKey` parameters, additionally you can pass `jwtKeyPassword` & `jwtTtl` parameters
```yaml
...
with:
url: https://vault.mycompany.com:8200
method: jwt
role: github-action
jwtPrivateKey: ${{ secrets.JWT_PRIVATE_KEY }}
jwtKeyPassword: ${{ secrets.JWT_KEY_PASS }}
jwtTtl: 3600 # 1 hour, default value
```
If any other method is specified and you provide an `authPayload`, the action will attempt to `POST` to `auth/${method}/login` with the provided payload and parse out the client token.
@@ -161,9 +179,9 @@ with:
## Other Secret Engines
Vault Action currently supports retrieving secrets from any engine where secrets
are retrieved via `GET` requests. This means secret engines such as PKI are currently
not supported due to their requirement of sending parameters along with the request
Vault Action currently supports retrieving secrets from any engine where secrets
are retrieved via `GET` requests. This means secret engines such as PKI are currently
not supported due to their requirement of sending parameters along with the request
(such as `common_name`).
For example, to request a secret from the `cubbyhole` secret engine:
@@ -247,6 +265,10 @@ Here are all the inputs available through `with`:
| `roleId` | The Role Id for App Role authentication | | |
| `secretId` | The Secret Id for App Role authentication | | |
| `githubToken` | The Github Token to be used to authenticate with Vault | | |
| `role` | Vault role for specified auth method | | |
| `jwtPrivateKey` | Base64 encoded Private key to sign JWT | | |
| `jwtKeyPassword` | Password for key stored in jwtPrivateKey (if needed) | | |
| `jwtTtl` | Time in seconds, after which token expires | | 3600 |
| `authPayload` | The JSON payload to be sent to Vault when using a custom authentication method. | | |
| `extraHeaders` | A string of newline separated extra headers to include on every request. | | |
| `exportEnv` | Whether or not export secrets as environment variables. | `true` | |
@@ -254,7 +276,7 @@ Here are all the inputs available through `with`:
| `caCertificate` | Base64 encoded CA certificate the server certificate was signed with. | | |
| `clientCertificate` | Base64 encoded client certificate the action uses to authenticate with Vault when mTLS is enabled. | | |
| `clientKey` | Base64 encoded client key the action uses to authenticate with Vault when mTLS is enabled. | | |
| `tlsSkipVerify` | When set to true, disables verification of server certificates when testing the action. | `false` | |
| `tlsSkipVerify` | When set to true, disables verification of server certificates when testing the action. | `false` | |
## Masking - Hiding Secrets from Logs
+13
View File
@@ -53,6 +53,19 @@ inputs:
description: 'When set to true, disables verification of the Vault server certificate. Setting this to true in production is not recommended.'
required: false
default: "false"
role:
description: 'Vault role for specified auth method'
required: false
jwtPrivateKey:
description: 'Base64 encoded Private key to sign JWT'
required: false
jwtKeyPassword:
description: 'Password for key stored in jwtPrivateKey (if needed)'
required: false
jwtTtl:
description: 'Time in seconds, after which token expires'
required: false
default: 3600
runs:
using: 'node12'
main: 'dist/index.js'
+551 -122
View File
File diff suppressed because one or more lines are too long
+126
View File
@@ -0,0 +1,126 @@
jest.mock('@actions/core');
jest.mock('@actions/core/lib/command');
const core = require('@actions/core');
const {
privateRsaKeyBase64,
publicRsaKey
} = require('./rsa_keys');
const got = require('got');
const { when } = require('jest-when');
const { exportSecrets } = require('../../src/action');
const vaultUrl = `http://${process.env.VAULT_HOST || 'localhost'}:${process.env.VAULT_PORT || '8200'}`;
describe('jwt auth', () => {
beforeAll(async () => {
// Verify Connection
await got(`${vaultUrl}/v1/secret/config`, {
headers: {
'X-Vault-Token': 'testtoken',
},
});
try {
await got(`${vaultUrl}/v1/sys/auth/jwt`, {
method: 'POST',
headers: {
'X-Vault-Token': 'testtoken',
},
json: {
type: 'jwt'
}
});
} catch (error) {
const {response} = error;
if (response.statusCode === 400 && response.body.includes("path is already in use")) {
// Auth method might already be enabled from previous test runs
} else {
throw error;
}
}
await got(`${vaultUrl}/v1/sys/policy/reader`, {
method: 'PUT',
headers: {
'X-Vault-Token': 'testtoken',
},
json: {
policy: `
path "*" {
capabilities = ["read"]
}
`
}
});
await got(`${vaultUrl}/v1/auth/jwt/config`, {
method: 'POST',
headers: {
'X-Vault-Token': 'testtoken',
},
json: {
jwt_validation_pubkeys: publicRsaKey
}
});
await got(`${vaultUrl}/v1/auth/jwt/role/default`, {
method: 'POST',
headers: {
'X-Vault-Token': 'testtoken',
},
json: {
role_type: 'jwt',
bound_audiences: null,
bound_claims: {
iss: 'vault-action'
},
user_claim: 'iss',
policies: ['reader']
}
});
await got(`${vaultUrl}/v1/secret/data/test`, {
method: 'POST',
headers: {
'X-Vault-Token': 'testtoken',
},
json: {
data: {
secret: 'SUPERSECRET',
},
},
});
});
beforeEach(() => {
jest.resetAllMocks();
when(core.getInput)
.calledWith('url')
.mockReturnValueOnce(`${vaultUrl}`);
when(core.getInput)
.calledWith('method')
.mockReturnValueOnce('jwt');
when(core.getInput)
.calledWith('jwtPrivateKey')
.mockReturnValueOnce(privateRsaKeyBase64);
when(core.getInput)
.calledWith('role')
.mockReturnValueOnce('default');
when(core.getInput)
.calledWith('secrets')
.mockReturnValueOnce('secret/data/test secret');
});
it('successfully authenticates', async () => {
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
});
});
+77
View File
@@ -0,0 +1,77 @@
const privateRsaKey = `
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
`;
const privateRsaKeyBase64 = Buffer.from(privateRsaKey).toString('base64');
const publicRsaKey = `
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwavSHLLo7bUSuKX2EKu3
YStrNTGdmhku7sAFaeDyi9His1oot+wzajWp1rqHaGVk4b5o5z6D7Xhm0zYPhpTT
vEd3NyONc9sjVd7sf9rQaBY3QusPYAdF6j0ydTJGnTeG9N2zhHjdMLR+3F39F9Ry
6vddS9w3ibjVERucQtpqGhy5TIWhttk3gN3A7dk972+WCQeKUCC6wU6PvAEUPflT
hQc1hSHldpjVUHQlZkQXl/XHWBzZESwMgiQcAmVL3lkvxmgIYscqWzf8cTHogNrP
ml9Il89N+2XYcEfXgWLOyzGhQggigN9DRHDDE1UWT1foHnmeXAIZPCveKZc/Jp5S
ASIxaZ+r73mWjVt19GSvEsqtejDRmMC3jrYCdISrCVsHkbRQq7/yLCi5sJG9p2gD
91jCgaBy2tw22nWN/KoHm9p/mhzWmlWwVJrFTNiP0qccyoa5h1a6WBPt0oCKQk3I
AMV5HhVw4DhPx8gvh7qwOZk9vXXAFyA8bWhOVIFIJ8i8Gq25y7/bukyzqsEPkQ2m
KgbQnh3VOUCSugJFodPC/Jf7VQK1yRpUZH2v7r9cBjHVnUnePGac3Zns7/iRYBvK
5cIFUg+X48VXIMKIvs4EA8ee8VacVh8tyR6EuP42BU5fGQlvLC+ZKT165maQv/Vl
f52E9W2iFNt3sxB0KFtOkbkCAwEAAQ==
-----END PUBLIC KEY-----
`;
module.exports = {
privateRsaKeyBase64,
publicRsaKey
};
+1663 -1363
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -45,7 +45,8 @@
"homepage": "https://github.com/hashicorp/vault-action#readme",
"dependencies": {
"got": "^11.5.1",
"jsonata": "^1.8.2"
"jsonata": "^1.8.2",
"jsrsasign": "^10.1.10"
},
"peerDependencies": {
"@actions/core": ">=1 <2"
+7 -3
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 });
@@ -77,8 +77,12 @@ async function exportSecrets() {
const { value, request, cachedResponse } = result;
if (cachedResponse) {
core.debug(' using cached response');
}
command.issue('add-mask', value);
}
for (const line of value.replace(/\r/g, '').split('\n')) {
if (line.length > 0) {
command.issue('add-mask', line);
}
}
if (exportEnv) {
core.exportVariable(request.envVarName, `${value}`);
}
+37
View File
@@ -2,6 +2,7 @@ jest.mock('got');
jest.mock('@actions/core');
jest.mock('@actions/core/lib/command');
const command = require('@actions/core/lib/command');
const core = require('@actions/core');
const got = require('got');
const {
@@ -294,4 +295,40 @@ describe('exportSecrets', () => {
expect(core.exportVariable).toBeCalledWith('KEY', '1');
expect(core.setOutput).toBeCalledWith('key', '1');
});
it('single-line secret gets masked', async () => {
mockInput('test key');
mockVaultData({
key: 'secret'
});
mockExportToken("false")
await exportSecrets();
expect(command.issue).toBeCalledTimes(1);
expect(command.issue).toBeCalledWith('add-mask', 'secret');
expect(core.setOutput).toBeCalledWith('key', 'secret');
})
it('multi-line secret gets masked for each line', async () => {
const multiLineString = `a multi-line string
with blank lines
`
mockInput('test key');
mockVaultData({
key: multiLineString
});
mockExportToken("false")
await exportSecrets();
expect(command.issue).toBeCalledTimes(2); // 1 for each non-empty line.
expect(command.issue).toBeCalledWith('add-mask', 'a multi-line string');
expect(command.issue).toBeCalledWith('add-mask', 'with blank lines');
expect(core.setOutput).toBeCalledWith('key', multiLineString);
})
});
+36
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
+1 -1
View File
@@ -73,7 +73,7 @@ function selectData(data, selector) {
}
if (result.startsWith(`"`)) {
result = result.substring(1, result.length - 1);
result = JSON.parse(result);
}
return result;
}