Compare commits

...

9 commits
v3.1.0 ... main

Author SHA1 Message Date
compliance-pr-automation-bot[bot]
2c5827061f
[Compliance] - PR Template Changes Required (#586)
Co-authored-by: compliance-pr-automation[bot] <1425255+compliance-pr-automation-bot[bot]@users.noreply.github.com>
2025-07-28 16:10:23 -07:00
John-Michael Faircloth
4c06c5ccf5
Prepare for v3.4.0 release (#584)
* Prepare for v3.4.0 release

* update dist
2025-06-13 11:30:03 -05:00
dependabot[bot]
d07b4dc505
chore(deps): bump jsrsasign from 11.0.0 to 11.1.0 (#521)
Bumps [jsrsasign](https://github.com/kjur/jsrsasign) from 11.0.0 to 11.1.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/11.0.0...11.1.0)

---
updated-dependencies:
- dependency-name: jsrsasign
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-13 10:30:05 -05:00
John-Michael Faircloth
8ab17d80fa
Prevent possible DoS via polynomial regex (#583) 2025-06-13 09:17:23 -05:00
John-Michael Faircloth
b022ecdb0c
fix: replace all dot chars during normalization (#580)
* fix: replace all dot chars during normalization

* changelog
2025-05-14 09:32:58 -05:00
Tom Chwojko-Frank
4d5899dd0e
Adding codeowners file (#578) 2025-04-14 16:20:35 -07:00
Rory
7709c60978
feat: added double asterisk wildcard selector to prevent uppercasing of keys before exporting envs (#545)
* feat: added double asterisk wildcard selector to prevent uppercasing of keys before exporting envs

* chore: update changelog

---------

Co-authored-by: John-Michael Faircloth <fairclothjm@users.noreply.github.com>
2025-03-03 15:31:00 -06:00
John-Michael Faircloth
4b1f32b395
Prepare for v3.2.0 release (#575)
* Prepare for v3.2.0 release

* changelog update
2025-03-03 14:18:41 -06:00
Andre Fuentes
5d06ce836f
Retry core.getIDToken for JWT Auth Method (#574)
* adding generic async retry function and retry core.getIDToken

* adding test and build
2025-03-03 12:02:57 -06:00
18 changed files with 240 additions and 61 deletions

View file

@ -18,3 +18,15 @@ Relates OR Closes #0000
prioritize this request prioritize this request
* Please do not leave "+1" comments, they generate extra noise for pull request * Please do not leave "+1" comments, they generate extra noise for pull request
followers and do not help prioritize the request followers and do not help prioritize the request
## PCI review checklist
<!-- heimdall_github_prtemplate:grc-pci_dss-2024-01-05 -->
- [ ] I have documented a clear reason for, and description of, the change I am making.
- [ ] If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
- [ ] If applicable, I've documented the impact of any changes to security controls.
Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

View file

@ -1,11 +1,14 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options: # Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates # https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates
version: 2 version: 2
updates: updates:
- package-ecosystem: "npm" # See documentation for possible values - package-ecosystem: "npm"
directory: "/" # Location of package manifests directory: "/" # Location of package manifests
open-pull-requests-limit: 0 # only require security updates and exclude version updates
schedule: schedule:
interval: "daily" interval: "weekly"
# For got, ignore all updates since it is now native ESM
# see https://github.com/hashicorp/vault-action/pull/457#issuecomment-1601445634
ignore:
- dependency-name: "got"

View file

@ -8,7 +8,7 @@ jobs:
actionlint: actionlint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: "Lint workflow files" - name: "Lint workflow files"
uses: docker://docker.mirror.hashicorp.services/rhysd/actionlint:latest uses: docker://docker.mirror.hashicorp.services/rhysd/actionlint:latest
with: with:

View file

@ -6,14 +6,14 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with: with:
node-version: "20.9.0" node-version: "20.9.0"
- name: Setup NPM Cache - name: Setup NPM Cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@ -33,17 +33,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run docker compose - name: Run docker compose
run: docker compose up -d vault run: docker compose up -d vault
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with: with:
node-version: "20.9.0" node-version: "20.9.0"
- name: Setup NPM Cache - name: Setup NPM Cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@ -67,19 +67,19 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run docker compose - name: Run docker compose
run: docker compose up -d vault-enterprise run: docker compose up -d vault-enterprise
env: env:
VAULT_LICENSE_CI: ${{ secrets.VAULT_LICENSE_CI }} VAULT_LICENSE_CI: ${{ secrets.VAULT_LICENSE_CI }}
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with: with:
node-version: "20.9.0" node-version: "20.9.0"
- name: Setup NPM Cache - name: Setup NPM Cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@ -103,17 +103,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run docker compose - name: Run docker compose
run: docker compose up -d vault run: docker compose up -d vault
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with: with:
node-version: "20.9.0" node-version: "20.9.0"
- name: Setup NPM Cache - name: Setup NPM Cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@ -199,17 +199,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run docker compose - name: Run docker compose
run: docker compose up -d vault-tls run: docker compose up -d vault-tls
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with: with:
node-version: "20.9.0" node-version: "20.9.0"
- name: Setup NPM Cache - name: Setup NPM Cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

View file

@ -18,9 +18,9 @@ jobs:
name: local-test name: local-test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with: with:
node-version: '20.9.0' node-version: '20.9.0'

View file

@ -1,3 +1,26 @@
## Unreleased
## 3.4.0 (June 13, 2025)
Bugs:
* replace all dot chars during normalization (https://github.com/hashicorp/vault-action/pull/580)
Improvements:
* Prevent possible DoS via polynomial regex (https://github.com/hashicorp/vault-action/pull/583)
## 3.3.0 (March 3, 2025)
Features:
* Wildcard secret imports can use `**` to retain case of exported env keys [GH-545](https://github.com/hashicorp/vault-action/pull/545)
## 3.2.0 (March 3, 2025)
Improvements:
* Add retry for jwt auth login to fix intermittent login failures [GH-574](https://github.com/hashicorp/vault-action/pull/574)
## 3.1.0 (January 9, 2025) ## 3.1.0 (January 9, 2025)
Improvements: Improvements:

1
CODEOWNERS Normal file
View file

@ -0,0 +1 @@
* @hashicorp/vault-ecosystem

View file

@ -403,6 +403,15 @@ with:
secret/data/ci/aws * | MYAPP_ ; secret/data/ci/aws * | MYAPP_ ;
``` ```
When using the `exportEnv` option all exported keys will be normalized to uppercase. For example, the key `SecretKey` would be exported as `MYAPP_SECRETKEY`.
You can disable uppercase normalization by specifying double asterisks `**` in the selector path:
```yaml
with:
secrets: |
secret/data/ci/aws ** | MYAPP_ ;
```
### KV secrets engine version 2 ### KV secrets engine version 2
When accessing secrets from the KV secrets engine version 2, Vault Action When accessing secrets from the KV secrets engine version 2, Vault Action

66
dist/index.js vendored

File diff suppressed because one or more lines are too long

View file

@ -39,6 +39,14 @@ describe('integration', () => {
body: `{"data":{"secret.foo":"SUPERSECRET"}}` body: `{"data":{"secret.foo":"SUPERSECRET"}}`
}); });
await got(`${vaultUrl}/v1/secret/data/test-with-multi-dot-chars`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
body: `{"data":{"secret.foo.bar":"SUPERSECRET"}}`
});
await got(`${vaultUrl}/v1/secret/data/nested/test`, { await got(`${vaultUrl}/v1/secret/data/nested/test`, {
method: 'POST', method: 'POST',
headers: { headers: {
@ -293,6 +301,16 @@ describe('integration', () => {
expect(core.exportVariable).toBeCalledWith('SECRET__FOO', 'SUPERSECRET'); expect(core.exportVariable).toBeCalledWith('SECRET__FOO', 'SUPERSECRET');
}); });
it('get secrets with multiple dot chars', async () => {
mockInput(`secret/data/test-with-multi-dot-chars * ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(1);
expect(core.exportVariable).toBeCalledWith('SECRET__FOO__BAR', 'SUPERSECRET');
});
it('get wildcard secrets', async () => { it('get wildcard secrets', async () => {
mockInput(`secret/data/test * ;`); mockInput(`secret/data/test * ;`);
@ -395,7 +413,7 @@ describe('integration', () => {
expect(core.exportVariable).toBeCalledWith('FOO', 'bar'); expect(core.exportVariable).toBeCalledWith('FOO', 'bar');
}); });
it('wildcard supports cubbyhole', async () => { it('wildcard supports cubbyhole with uppercase transform', async () => {
mockInput('/cubbyhole/test *'); mockInput('/cubbyhole/test *');
await exportSecrets(); await exportSecrets();
@ -406,6 +424,32 @@ describe('integration', () => {
expect(core.exportVariable).toBeCalledWith('ZIP', 'zap'); expect(core.exportVariable).toBeCalledWith('ZIP', 'zap');
}); });
it('wildcard supports cubbyhole with no change in case', async () => {
mockInput('/cubbyhole/test **');
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(2);
expect(core.exportVariable).toBeCalledWith('foo', 'bar');
expect(core.exportVariable).toBeCalledWith('zip', 'zap');
});
it('wildcard supports cubbyhole with mixed case change', async () => {
mockInput(`
/cubbyhole/test * ;
/cubbyhole/test **`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(4);
expect(core.exportVariable).toBeCalledWith('FOO', 'bar');
expect(core.exportVariable).toBeCalledWith('ZIP', 'zap');
expect(core.exportVariable).toBeCalledWith('foo', 'bar');
expect(core.exportVariable).toBeCalledWith('zip', 'zap');
});
it('caches responses', async () => { it('caches responses', async () => {
mockInput(` mockInput(`
/cubbyhole/test foo ; /cubbyhole/test foo ;

15
package-lock.json generated
View file

@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"got": "^11.8.6", "got": "^11.8.6",
"jsonata": "^2.0.3", "jsonata": "^2.0.3",
"jsrsasign": "^11.0.0" "jsrsasign": "^11.1.0"
}, },
"devDependencies": { "devDependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
@ -3375,9 +3375,10 @@
} }
}, },
"node_modules/jsrsasign": { "node_modules/jsrsasign": {
"version": "11.0.0", "version": "11.1.0",
"resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-11.0.0.tgz", "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-11.1.0.tgz",
"integrity": "sha512-BtRwVKS+5dsgPpAtzJcpo5OoWjSs1/zllSBG0+8o8/aV0Ki76m6iZwHnwnsqoTdhfFZDN1XIdcaZr5ZkP+H2gg==", "integrity": "sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg==",
"license": "MIT",
"funding": { "funding": {
"url": "https://github.com/kjur/jsrsasign#donations" "url": "https://github.com/kjur/jsrsasign#donations"
} }
@ -7225,9 +7226,9 @@
"integrity": "sha512-vfavX4/G/yrYxE+UrmT/oUJ3ph7KqUrb0R7b0LVRcntQwxw+Z5kA1pNUIQzX5hF04Oe1eKxyoIPsmXtc2LgJTQ==" "integrity": "sha512-vfavX4/G/yrYxE+UrmT/oUJ3ph7KqUrb0R7b0LVRcntQwxw+Z5kA1pNUIQzX5hF04Oe1eKxyoIPsmXtc2LgJTQ=="
}, },
"jsrsasign": { "jsrsasign": {
"version": "11.0.0", "version": "11.1.0",
"resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-11.0.0.tgz", "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-11.1.0.tgz",
"integrity": "sha512-BtRwVKS+5dsgPpAtzJcpo5OoWjSs1/zllSBG0+8o8/aV0Ki76m6iZwHnwnsqoTdhfFZDN1XIdcaZr5ZkP+H2gg==" "integrity": "sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg=="
}, },
"keyv": { "keyv": {
"version": "4.3.2", "version": "4.3.2",

View file

@ -36,7 +36,7 @@
"dependencies": { "dependencies": {
"got": "^11.8.6", "got": "^11.8.6",
"jsonata": "^2.0.3", "jsonata": "^2.0.3",
"jsrsasign": "^11.0.0" "jsrsasign": "^11.1.0"
}, },
"peerDependencies": { "peerDependencies": {
"@actions/core": ">=1 <2" "@actions/core": ">=1 <2"

View file

@ -4,7 +4,7 @@ const command = require('@actions/core/lib/command');
const got = require('got').default; const got = require('got').default;
const jsonata = require('jsonata'); const jsonata = require('jsonata');
const { normalizeOutputKey } = require('./utils'); const { normalizeOutputKey } = require('./utils');
const { WILDCARD } = require('./constants'); const { WILDCARD, WILDCARD_UPPERCASE } = require('./constants');
const { auth: { retrieveToken }, secrets: { getSecrets }, pki: { getCertificates } } = require('./index'); const { auth: { retrieveToken }, secrets: { getSecrets }, pki: { getCertificates } } = require('./index');
@ -221,7 +221,7 @@ function parseSecretsInput(secretsInput) {
const selectorAst = jsonata(selectorQuoted).ast(); const selectorAst = jsonata(selectorQuoted).ast();
const selector = selectorQuoted.replace(new RegExp('"', 'g'), ''); const selector = selectorQuoted.replace(new RegExp('"', 'g'), '');
if (selector !== WILDCARD && (selectorAst.type !== "path" || selectorAst.steps[0].stages) && selectorAst.type !== "string" && !outputVarName) { if (selector !== WILDCARD && selector !== WILDCARD_UPPERCASE && (selectorAst.type !== "path" || selectorAst.steps[0].stages) && selectorAst.type !== "string" && !outputVarName) {
throw Error(`You must provide a name for the output key when using json selectors. Input: "${secret}"`); throw Error(`You must provide a name for the output key when using json selectors. Input: "${secret}"`);
} }

View file

@ -5,6 +5,8 @@ const fs = require('fs');
const { default: got } = require('got'); const { default: got } = require('got');
const defaultKubernetesTokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token' const defaultKubernetesTokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token'
const retries = 5
const retries_delay = 3000
/*** /***
* Authenticate with Vault and retrieve a Vault token that can be used for requests. * Authenticate with Vault and retrieve a Vault token that can be used for requests.
* @param {string} method * @param {string} method
@ -35,7 +37,10 @@ async function retrieveToken(method, client) {
const githubAudience = core.getInput('jwtGithubAudience', { required: false }); const githubAudience = core.getInput('jwtGithubAudience', { required: false });
if (!privateKey) { if (!privateKey) {
jwt = await core.getIDToken(githubAudience) jwt = await retryAsyncFunction(retries, retries_delay, core.getIDToken, githubAudience)
.then((result) => {
return result;
});
} else { } else {
jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl)); jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl));
} }
@ -142,6 +147,30 @@ async function getClientToken(client, method, path, payload) {
} }
} }
/***
* Generic function for retrying an async function
* @param {number} retries
* @param {number} delay
* @param {Function} func
* @param {any[]} args
*/
async function retryAsyncFunction(retries, delay, func, ...args) {
let attempt = 0;
while (attempt < retries) {
try {
const result = await func(...args);
return result;
} catch (error) {
attempt++;
if (attempt < retries) {
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
}
/*** /***
* @typedef {Object} VaultLoginResponse * @typedef {Object} VaultLoginResponse
* @property {{ * @property {{

View file

@ -85,4 +85,23 @@ describe("test retrival for token", () => {
const url = got.post.mock.calls[0][0] const url = got.post.mock.calls[0][0]
expect(url).toContain('differentK8sPath') expect(url).toContain('differentK8sPath')
}) })
it("test retrieval with jwt", async () => {
const method = "jwt"
const jwtToken = "someTestToken"
const testRole = "testRole"
const privateKeyRaw = ""
mockApiResponse()
mockInput("role", testRole)
mockInput("jwtPrivateKey", privateKeyRaw)
core.getIDToken = jest.fn()
core.getIDToken.mockReturnValueOnce(jwtToken)
const token = await retrieveToken(method, got)
expect(token).toEqual(testToken)
const payload = got.post.mock.calls[0][1].json
expect(payload).toEqual({ jwt: jwtToken, role: testRole })
const url = got.post.mock.calls[0][0]
expect(url).toContain('jwt')
})
}) })

View file

@ -1,5 +1,7 @@
const WILDCARD = '*'; const WILDCARD_UPPERCASE = '*';
const WILDCARD = '**';
module.exports = { module.exports = {
WILDCARD WILDCARD,
WILDCARD_UPPERCASE,
}; };

View file

@ -1,5 +1,5 @@
const jsonata = require("jsonata"); const jsonata = require("jsonata");
const { WILDCARD } = require("./constants"); const { WILDCARD, WILDCARD_UPPERCASE} = require("./constants");
const { normalizeOutputKey } = require("./utils"); const { normalizeOutputKey } = require("./utils");
const core = require('@actions/core'); const core = require('@actions/core');
@ -26,6 +26,7 @@ const core = require('@actions/core');
async function getSecrets(secretRequests, client, ignoreNotFound) { async function getSecrets(secretRequests, client, ignoreNotFound) {
const responseCache = new Map(); const responseCache = new Map();
let results = []; let results = [];
let upperCaseEnv = false;
for (const secretRequest of secretRequests) { for (const secretRequest of secretRequests) {
let { path, selector } = secretRequest; let { path, selector } = secretRequest;
@ -59,7 +60,8 @@ async function getSecrets(secretRequests, client, ignoreNotFound) {
body = JSON.parse(body); body = JSON.parse(body);
if (selector == WILDCARD) { if (selector === WILDCARD || selector === WILDCARD_UPPERCASE) {
upperCaseEnv = selector === WILDCARD_UPPERCASE;
let keys = body.data; let keys = body.data;
if (body.data["data"] != undefined) { if (body.data["data"] != undefined) {
keys = keys.data; keys = keys.data;
@ -78,7 +80,7 @@ async function getSecrets(secretRequests, client, ignoreNotFound) {
} }
newRequest.outputVarName = normalizeOutputKey(newRequest.outputVarName); newRequest.outputVarName = normalizeOutputKey(newRequest.outputVarName);
newRequest.envVarName = normalizeOutputKey(newRequest.envVarName,true); newRequest.envVarName = normalizeOutputKey(newRequest.envVarName, upperCaseEnv);
// JSONata field references containing reserved tokens should // JSONata field references containing reserved tokens should
// be enclosed in backticks // be enclosed in backticks
@ -151,7 +153,7 @@ const selectAndAppendResults = async (
secretRequest, secretRequest,
results results
) => { ) => {
if (!selector.match(/.*[\.].*/)) { if (!selector.includes(".")) {
selector = '"' + selector + '"'; selector = '"' + selector + '"';
} }
selector = "data." + selector; selector = "data." + selector;

View file

@ -3,12 +3,12 @@
* @param {string} dataKey * @param {string} dataKey
* @param {boolean=} isEnvVar * @param {boolean=} isEnvVar
*/ */
function normalizeOutputKey(dataKey, isEnvVar = false) { function normalizeOutputKey(dataKey, upperCase = false) {
let outputKey = dataKey let outputKey = dataKey
.replace(".", "__") .replaceAll(".", "__")
.replace(new RegExp("-", "g"), "") .replace(new RegExp("-", "g"), "")
.replace(/[^\p{L}\p{N}_-]/gu, ""); .replace(/[^\p{L}\p{N}_-]/gu, "");
if (isEnvVar) { if (upperCase) {
outputKey = outputKey.toUpperCase(); outputKey = outputKey.toUpperCase();
} }
return outputKey; return outputKey;