@commercetools-frontend/vault-utils 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +27 -0
- package/dist/commercetools-frontend-vault-utils.cjs.d.ts +2 -0
- package/dist/commercetools-frontend-vault-utils.cjs.dev.js +71 -0
- package/dist/commercetools-frontend-vault-utils.cjs.js +7 -0
- package/dist/commercetools-frontend-vault-utils.cjs.prod.js +71 -0
- package/dist/commercetools-frontend-vault-utils.esm.js +61 -0
- package/dist/declarations/src/auth.d.ts +16 -0
- package/dist/declarations/src/credentials.d.ts +16 -0
- package/dist/declarations/src/index.d.ts +3 -0
- package/dist/declarations/src/secrets.d.ts +20 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) commercetools GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @commercetools-frontend/vault-utils
|
|
2
|
+
|
|
3
|
+
> This package provide utilities to integrate with Vault to retrieve secrets.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
$ npm install --save @commercetools-frontend/vault-utils
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### `getCredentialsForCI`
|
|
14
|
+
|
|
15
|
+
Retrieve credentials for a given secret path, given that the `CI` environment variable is set.
|
|
16
|
+
|
|
17
|
+
Credentials are returned as a JSON object.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
const credentialsFromVault = await getCredentialsForCI({
|
|
21
|
+
vaultAddr: '',
|
|
22
|
+
repositoryName: '',
|
|
23
|
+
secretPath: '',
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
When running within CircleCI, the method uses the `CIRCLE_OIDC_TOKEN` environment variable for authentication.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from "./declarations/src/index";
|
|
2
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWVyY2V0b29scy1mcm9udGVuZC12YXVsdC11dGlscy5janMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4vZGVjbGFyYXRpb25zL3NyYy9pbmRleC5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBIn0=
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
8
|
+
|
|
9
|
+
var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
|
|
10
|
+
|
|
11
|
+
async function getAccessToken(params) {
|
|
12
|
+
const vaultAddr = params.vaultAddr ?? process.env.VAULT_ADDR;
|
|
13
|
+
const jwt = params.jwt ?? process.env.CIRCLE_OIDC_TOKEN;
|
|
14
|
+
const vaultAuthUrl = [vaultAddr, 'v1', 'auth/oidc/circleci/login'].join('/');
|
|
15
|
+
const response = await fetch(vaultAuthUrl, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
body: _JSON$stringify__default["default"]({
|
|
18
|
+
role: params.role,
|
|
19
|
+
jwt
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
const result = await response.json();
|
|
23
|
+
if (response.ok) {
|
|
24
|
+
return result.auth.client_token;
|
|
25
|
+
}
|
|
26
|
+
const error = new Error(response.statusText);
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
error.body = result;
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function getSecret(params) {
|
|
33
|
+
const vaultAddr = params.vaultAddr ?? process.env.VAULT_ADDR;
|
|
34
|
+
const vaultKV2Url = [vaultAddr, 'v1', params.mount, 'data', params.secretPath].join('/');
|
|
35
|
+
const response = await fetch(vaultKV2Url, {
|
|
36
|
+
method: 'GET',
|
|
37
|
+
headers: {
|
|
38
|
+
'X-Vault-Token': params.token
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const result = await response.json();
|
|
42
|
+
if (response.ok) {
|
|
43
|
+
return result.data.data;
|
|
44
|
+
}
|
|
45
|
+
const error = new Error(response.statusText);
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
error.body = result;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function getCredentialsForCI(params) {
|
|
52
|
+
if (String(process.env.CI) === 'true') {
|
|
53
|
+
console.log(`ℹ️ 'CI' environment variable is defined. Reading secrets from Vault ${params.secretPath}.`);
|
|
54
|
+
const token = await getAccessToken({
|
|
55
|
+
role: `${params.repositoryName}_merchant-center`,
|
|
56
|
+
vaultAddr: params.vaultAddr
|
|
57
|
+
});
|
|
58
|
+
const secret = await getSecret({
|
|
59
|
+
token,
|
|
60
|
+
mount: `kv2/repositories/${params.repositoryName}`,
|
|
61
|
+
secretPath: params.secretPath,
|
|
62
|
+
vaultAddr: params.vaultAddr
|
|
63
|
+
});
|
|
64
|
+
return secret;
|
|
65
|
+
}
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exports.getAccessToken = getAccessToken;
|
|
70
|
+
exports.getCredentialsForCI = getCredentialsForCI;
|
|
71
|
+
exports.getSecret = getSecret;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
8
|
+
|
|
9
|
+
var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
|
|
10
|
+
|
|
11
|
+
async function getAccessToken(params) {
|
|
12
|
+
const vaultAddr = params.vaultAddr ?? process.env.VAULT_ADDR;
|
|
13
|
+
const jwt = params.jwt ?? process.env.CIRCLE_OIDC_TOKEN;
|
|
14
|
+
const vaultAuthUrl = [vaultAddr, 'v1', 'auth/oidc/circleci/login'].join('/');
|
|
15
|
+
const response = await fetch(vaultAuthUrl, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
body: _JSON$stringify__default["default"]({
|
|
18
|
+
role: params.role,
|
|
19
|
+
jwt
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
const result = await response.json();
|
|
23
|
+
if (response.ok) {
|
|
24
|
+
return result.auth.client_token;
|
|
25
|
+
}
|
|
26
|
+
const error = new Error(response.statusText);
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
error.body = result;
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function getSecret(params) {
|
|
33
|
+
const vaultAddr = params.vaultAddr ?? process.env.VAULT_ADDR;
|
|
34
|
+
const vaultKV2Url = [vaultAddr, 'v1', params.mount, 'data', params.secretPath].join('/');
|
|
35
|
+
const response = await fetch(vaultKV2Url, {
|
|
36
|
+
method: 'GET',
|
|
37
|
+
headers: {
|
|
38
|
+
'X-Vault-Token': params.token
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const result = await response.json();
|
|
42
|
+
if (response.ok) {
|
|
43
|
+
return result.data.data;
|
|
44
|
+
}
|
|
45
|
+
const error = new Error(response.statusText);
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
error.body = result;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function getCredentialsForCI(params) {
|
|
52
|
+
if (String(process.env.CI) === 'true') {
|
|
53
|
+
console.log(`ℹ️ 'CI' environment variable is defined. Reading secrets from Vault ${params.secretPath}.`);
|
|
54
|
+
const token = await getAccessToken({
|
|
55
|
+
role: `${params.repositoryName}_merchant-center`,
|
|
56
|
+
vaultAddr: params.vaultAddr
|
|
57
|
+
});
|
|
58
|
+
const secret = await getSecret({
|
|
59
|
+
token,
|
|
60
|
+
mount: `kv2/repositories/${params.repositoryName}`,
|
|
61
|
+
secretPath: params.secretPath,
|
|
62
|
+
vaultAddr: params.vaultAddr
|
|
63
|
+
});
|
|
64
|
+
return secret;
|
|
65
|
+
}
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exports.getAccessToken = getAccessToken;
|
|
70
|
+
exports.getCredentialsForCI = getCredentialsForCI;
|
|
71
|
+
exports.getSecret = getSecret;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringify';
|
|
2
|
+
|
|
3
|
+
async function getAccessToken(params) {
|
|
4
|
+
const vaultAddr = params.vaultAddr ?? process.env.VAULT_ADDR;
|
|
5
|
+
const jwt = params.jwt ?? process.env.CIRCLE_OIDC_TOKEN;
|
|
6
|
+
const vaultAuthUrl = [vaultAddr, 'v1', 'auth/oidc/circleci/login'].join('/');
|
|
7
|
+
const response = await fetch(vaultAuthUrl, {
|
|
8
|
+
method: 'POST',
|
|
9
|
+
body: _JSON$stringify({
|
|
10
|
+
role: params.role,
|
|
11
|
+
jwt
|
|
12
|
+
})
|
|
13
|
+
});
|
|
14
|
+
const result = await response.json();
|
|
15
|
+
if (response.ok) {
|
|
16
|
+
return result.auth.client_token;
|
|
17
|
+
}
|
|
18
|
+
const error = new Error(response.statusText);
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
error.body = result;
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function getSecret(params) {
|
|
25
|
+
const vaultAddr = params.vaultAddr ?? process.env.VAULT_ADDR;
|
|
26
|
+
const vaultKV2Url = [vaultAddr, 'v1', params.mount, 'data', params.secretPath].join('/');
|
|
27
|
+
const response = await fetch(vaultKV2Url, {
|
|
28
|
+
method: 'GET',
|
|
29
|
+
headers: {
|
|
30
|
+
'X-Vault-Token': params.token
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const result = await response.json();
|
|
34
|
+
if (response.ok) {
|
|
35
|
+
return result.data.data;
|
|
36
|
+
}
|
|
37
|
+
const error = new Error(response.statusText);
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
error.body = result;
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function getCredentialsForCI(params) {
|
|
44
|
+
if (String(process.env.CI) === 'true') {
|
|
45
|
+
console.log(`ℹ️ 'CI' environment variable is defined. Reading secrets from Vault ${params.secretPath}.`);
|
|
46
|
+
const token = await getAccessToken({
|
|
47
|
+
role: `${params.repositoryName}_merchant-center`,
|
|
48
|
+
vaultAddr: params.vaultAddr
|
|
49
|
+
});
|
|
50
|
+
const secret = await getSecret({
|
|
51
|
+
token,
|
|
52
|
+
mount: `kv2/repositories/${params.repositoryName}`,
|
|
53
|
+
secretPath: params.secretPath,
|
|
54
|
+
vaultAddr: params.vaultAddr
|
|
55
|
+
});
|
|
56
|
+
return secret;
|
|
57
|
+
}
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { getAccessToken, getCredentialsForCI, getSecret };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type TVaultGetAccessTokenParams = {
|
|
2
|
+
/**
|
|
3
|
+
* The role name of the JWT/OIDC auth backend. The format is `<circleci-project>_<circleci-context>`.
|
|
4
|
+
*/
|
|
5
|
+
role: string;
|
|
6
|
+
/**
|
|
7
|
+
* The URL of the Vault server, usually exported as environment variable `VAULT_ADDR`.
|
|
8
|
+
*/
|
|
9
|
+
vaultAddr?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The JWT to authenticate to Vault. If used from CircleCI the variable is exported as `CIRCLE_OIDC_TOKEN`.
|
|
12
|
+
*/
|
|
13
|
+
jwt?: string;
|
|
14
|
+
};
|
|
15
|
+
declare function getAccessToken(params: TVaultGetAccessTokenParams): Promise<string>;
|
|
16
|
+
export { getAccessToken };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type TVaultGetCredentialsParams = {
|
|
2
|
+
/**
|
|
3
|
+
* The name of the repository
|
|
4
|
+
*/
|
|
5
|
+
repositoryName: string;
|
|
6
|
+
/**
|
|
7
|
+
* The path to the secret to read.
|
|
8
|
+
*/
|
|
9
|
+
secretPath: string;
|
|
10
|
+
/**
|
|
11
|
+
* The URL of the Vault server, usually exported as environment variable `VAULT_ADDR`.
|
|
12
|
+
*/
|
|
13
|
+
vaultAddr?: string;
|
|
14
|
+
};
|
|
15
|
+
declare function getCredentialsForCI(params: TVaultGetCredentialsParams): Promise<Record<string, string>>;
|
|
16
|
+
export { getCredentialsForCI };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type TVaultGetSecretParams = {
|
|
2
|
+
/**
|
|
3
|
+
* The Vault token. Use the `getAccessToken` method to get one.
|
|
4
|
+
*/
|
|
5
|
+
token: string;
|
|
6
|
+
/**
|
|
7
|
+
* The path to the KV mount containing the secret to read.
|
|
8
|
+
*/
|
|
9
|
+
mount: string;
|
|
10
|
+
/**
|
|
11
|
+
* The path to the secret to read.
|
|
12
|
+
*/
|
|
13
|
+
secretPath: string;
|
|
14
|
+
/**
|
|
15
|
+
* The URL of the Vault server, usually exported as environment variable `VAULT_ADDR`.
|
|
16
|
+
*/
|
|
17
|
+
vaultAddr?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function getSecret(params: TVaultGetSecretParams): Promise<unknown>;
|
|
20
|
+
export { getSecret };
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@commercetools-frontend/vault-utils",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Utilities to integrate with Vault",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"typecheck": "tsc --noEmit"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/commercetools-frontend-vault-utils.cjs.js",
|
|
13
|
+
"module": "dist/commercetools-frontend-vault-utils.esm.js",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"package.json",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@babel/runtime": "^7.21.0",
|
|
22
|
+
"@babel/runtime-corejs3": "^7.21.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@tsconfig/node20": "20.1.2",
|
|
26
|
+
"@types/node": "20.11.25",
|
|
27
|
+
"typescript": "5.2.2"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18",
|
|
31
|
+
"npm": ">=5"
|
|
32
|
+
}
|
|
33
|
+
}
|