mirror of
https://github.com/hashicorp/vault-action.git
synced 2025-11-14 18:13:45 +00:00
implemented kubernetes auth
This commit is contained in:
parent
2ca76a4465
commit
8a7c9e8dd1
5 changed files with 113 additions and 1 deletions
12
README.md
12
README.md
|
|
@ -80,6 +80,16 @@ with:
|
|||
caCertificate: ${{ secrets.VAULTCA }}
|
||||
```
|
||||
|
||||
- **kubernetes**: you must provide the path to the token in the `tokenPath`variable as well as the roleName for kuberentes bases auth this is interesting if [kubernetes auth](https://www.vaultproject.io/docs/auth/kubernetes) in combination with self hosted runners is deployed:
|
||||
```yaml
|
||||
...
|
||||
with:
|
||||
url: https://vault.mycompany.com:8200
|
||||
method: kubernetes
|
||||
roleName: ${{ secrets.KUBE_ROLENAME }}
|
||||
tokenPath: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Key Syntax
|
||||
|
|
@ -247,6 +257,8 @@ 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 | | |
|
||||
| `roleName` | The rolename of the serviceaccount for the kubernetes authentification | | |
|
||||
| `tokenPath` | The path to the serviceacconut secret with the jwt-token for kubernetes based authentification | | |
|
||||
| `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` | |
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@ inputs:
|
|||
githubToken:
|
||||
description: 'The Github Token to be used to authenticate with Vault'
|
||||
required: false
|
||||
roleName:
|
||||
description: "The role name for the kubernetes authentification"
|
||||
required: false
|
||||
tokenPath:
|
||||
description: "The path to the kubernetes service account secret, the action reads the content of this file on the runner"
|
||||
required: false
|
||||
authPayload:
|
||||
description: 'The JSON payload to be sent to Vault when using a custom authentication method.'
|
||||
required: false
|
||||
|
|
|
|||
|
|
@ -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','kubernetes'];
|
||||
|
||||
async function exportSecrets() {
|
||||
const vaultUrl = core.getInput('url', { required: true });
|
||||
|
|
|
|||
12
src/auth.js
12
src/auth.js
|
|
@ -1,5 +1,6 @@
|
|||
// @ts-check
|
||||
const core = require('@actions/core');
|
||||
const fs = require('fs');
|
||||
|
||||
/***
|
||||
* Authenticate with Vault and retrieve a Vault token that can be used for requests.
|
||||
|
|
@ -17,6 +18,17 @@ async function retrieveToken(method, client) {
|
|||
const githubToken = core.getInput('githubToken', { required: true });
|
||||
return await getClientToken(client, method, { token: githubToken });
|
||||
}
|
||||
case 'kubernetes': {
|
||||
const tokenPath = core.getInput('tokenPath', { required: true })
|
||||
const data = fs.readFileSync(tokenPath, 'utf8')
|
||||
const roleName = core.getInput('roleName', { required: true })
|
||||
if (!(roleName && data) && data != "") {
|
||||
throw new Error("Role Name must be set and a kubernetes token must set")
|
||||
}
|
||||
const payload = { jwt: data, role: roleName }
|
||||
return await getClientToken(client, method, payload)
|
||||
}
|
||||
|
||||
default: {
|
||||
if (!method || method === 'token') {
|
||||
return core.getInput('token', { required: true });
|
||||
|
|
|
|||
82
src/auth.test.js
Normal file
82
src/auth.test.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
jest.mock('got');
|
||||
jest.mock('@actions/core');
|
||||
jest.mock('@actions/core/lib/command');
|
||||
jest.mock("fs")
|
||||
|
||||
const core = require('@actions/core');
|
||||
const got = require('got');
|
||||
const fs = require("fs")
|
||||
const { when } = require('jest-when');
|
||||
|
||||
|
||||
const {
|
||||
retrieveToken
|
||||
} = require('./auth');
|
||||
|
||||
|
||||
function mockInput(name, key) {
|
||||
when(core.getInput)
|
||||
.calledWith(name)
|
||||
.mockReturnValueOnce(key);
|
||||
}
|
||||
|
||||
function mockApiResponse() {
|
||||
const response = { body: { auth: { client_token: testToken, renewable: true, policies: [], accessor: "accessor" } } }
|
||||
got.post = jest.fn()
|
||||
got.post.mockReturnValue(response)
|
||||
}
|
||||
const testToken = "testoken";
|
||||
|
||||
describe("test retrival for token", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it("test retrival with approle", async () => {
|
||||
const method = 'approle'
|
||||
mockApiResponse()
|
||||
const testRoleId = "testRoleId"
|
||||
const testSecretId = "testSecretId"
|
||||
mockInput("roleId", testRoleId)
|
||||
mockInput("secretId", testSecretId)
|
||||
const token = await retrieveToken(method, got)
|
||||
expect(token).toEqual(testToken)
|
||||
const payload = got.post.mock.calls[0][1].json
|
||||
expect(payload).toEqual({ role_id: testRoleId, secret_id: testSecretId })
|
||||
const url = got.post.mock.calls[0][0]
|
||||
expect(url).toContain('approle')
|
||||
})
|
||||
|
||||
it("test retrival with github token", async () => {
|
||||
const method = 'github'
|
||||
mockApiResponse()
|
||||
const githubToken = "githubtoken"
|
||||
mockInput("githubToken", githubToken)
|
||||
const token = await retrieveToken(method, got)
|
||||
expect(token).toEqual(testToken)
|
||||
const payload = got.post.mock.calls[0][1].json
|
||||
expect(payload).toEqual({ token: githubToken })
|
||||
const url = got.post.mock.calls[0][0]
|
||||
expect(url).toContain('github')
|
||||
})
|
||||
|
||||
it("test retrival with kubernetes", async () => {
|
||||
const method = 'kubernetes'
|
||||
const jwtToken = "someJwtToken"
|
||||
const testRoleName = "testRoleName"
|
||||
const testTokenPath = "testTokenPath"
|
||||
mockApiResponse()
|
||||
mockInput("tokenPath", testTokenPath)
|
||||
mockInput("roleName", testRoleName)
|
||||
fs.readFileSync = jest.fn()
|
||||
fs.readFileSync.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: testRoleName })
|
||||
const url = got.post.mock.calls[0][0]
|
||||
expect(url).toContain('kubernetes')
|
||||
})
|
||||
|
||||
})
|
||||
Loading…
Reference in a new issue