diff --git a/README.md b/README.md index b3939f5..a5b26e1 100644 --- a/README.md +++ b/README.md @@ -236,7 +236,7 @@ with: You can configure trust between your own OIDC Provider and Vault with the JWT auth method. Provide a `role` & `jwtPrivateKey` parameters, -additionally you can pass `jwtKeyPassword` & `jwtTtl` parameters +additionally you can pass `jwtKeyPassword`, `jwtTtl`, & `jwtIat` parameters. ```yaml with: @@ -247,6 +247,7 @@ with: jwtPrivateKey: ${{ secrets.JWT_PRIVATE_KEY }} jwtKeyPassword: ${{ secrets.JWT_KEY_PASS }} jwtTtl: 3600 # 1 hour, default value + jwtIat: 60 # 1 min, default value. Negative int postdates ``` ### Kubernetes diff --git a/action.yml b/action.yml index 94c738a..556dd38 100644 --- a/action.yml +++ b/action.yml @@ -89,6 +89,10 @@ inputs: description: 'Time in seconds, after which token expires' required: false default: 3600 + jwtIat: + description: 'Number of seconds (int) to predate the token issued at (iat).' + required: false + default: 60 secretEncodingType: description: 'The encoding type of the secret to decode. If not specified, the secret will not be decoded. Supported values: base64, hex, utf8' required: false diff --git a/integrationTests/basic/jwt_auth.test.js b/integrationTests/basic/jwt_auth.test.js index e2744a1..35c9ef5 100644 --- a/integrationTests/basic/jwt_auth.test.js +++ b/integrationTests/basic/jwt_auth.test.js @@ -44,7 +44,7 @@ function mockGithubOIDCResponse(aud= "https://github.com/hashicorp/vault-action" ref_type: "branch", job_workflow_ref: "hashicorp/vault-action/.github/workflows/workflow.yml@refs/heads/main", iss: 'vault-action', - iat: now, + iat: now - 60, nbf: now, exp: now + 3600, }; diff --git a/src/auth.js b/src/auth.js index 1d0f9b1..5476ac6 100644 --- a/src/auth.js +++ b/src/auth.js @@ -34,6 +34,7 @@ async function retrieveToken(method, client) { 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 tokenIat = core.getInput('jwtIat', { required: false }) || '60'; const githubAudience = core.getInput('jwtGithubAudience', { required: false }); if (!privateKey) { @@ -42,7 +43,7 @@ async function retrieveToken(method, client) { return result; }); } else { - jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl)); + jwt = generateJwt(privateKey, keyPassword, Number(tokenTtl), Number(tokenIat)); } return await getClientToken(client, method, path, { jwt: jwt, role: role }); @@ -84,14 +85,15 @@ async function retrieveToken(method, client) { * @param {string} privateKey * @param {string} keyPassword * @param {number} ttl + * @param {number} iat */ -function generateJwt(privateKey, keyPassword, ttl) { +function generateJwt(privateKey, keyPassword, ttl, iat) { const alg = 'RS256'; const header = { alg: alg, typ: 'JWT' }; const now = rsasign.KJUR.jws.IntDate.getNow(); const payload = { iss: 'vault-action', - iat: now, + iat: now - iat, nbf: now, exp: now + ttl, event: process.env.GITHUB_EVENT_NAME,