vvauth 0.1.5 → 0.2.1

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.
Files changed (2) hide show
  1. package/index.js +115 -27
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -22,57 +22,59 @@ const replaceEnv = require('nyks/string/replaceEnv');
22
22
  const debug = require('debug');
23
23
 
24
24
  const logger = {
25
- debug : debug('dspp:secrets:debug'),
26
- info : debug('dspp:secrets:info'),
27
- error : debug('dspp:secrets:error'),
25
+ debug : debug('vvauth:debug'),
26
+ info : debug('vvauth:info'),
27
+ error : debug('vvauth:error'),
28
28
  };
29
29
 
30
30
 
31
- const VAUTH_RC = process.env.VAUTHRC || ".vauthrc";
31
+ const VAUTH_RC = [process.env.VAUTHRC, path.join(process.cwd(), ".vauthrc"), path.join(os.homedir(), ".vauthrc")];
32
32
  const FUNCTION_NAME = "vauth";
33
33
  const FUNCTION_DECL = "function vauth() { source <(/usr/bin/env vvauth --ir://raw --source --ir://run=$1 \"${@:2}\"); }";
34
34
 
35
35
  class vvauth {
36
36
  constructor(rc = null) {
37
+
37
38
  this.rc = {};
38
39
  if(rc) {
39
40
  this.rc = rc;
40
41
  } else {
41
- if(fs.existsSync(VAUTH_RC)) {
42
- let body = fs.readFileSync(VAUTH_RC, 'utf8');
42
+ let vauth_rc = VAUTH_RC.filter(path => path && fs.existsSync(path))[0];
43
+ if(vauth_rc) {
44
+ let body = fs.readFileSync(vauth_rc, 'utf8');
43
45
  this.rc = walk(parse(body), v => replaceEnv(v, { env : process.env}));
44
46
  }
45
47
  }
46
48
 
47
- let {vault_addr} = this.rc;
48
- if(!vault_addr)
49
+ this.vault_addr = this.rc.vault_addr;
50
+
51
+ if(!this.vault_addr)
49
52
  throw `Invalid vault remote`;
50
- console.error("vauth bound to '%s'", vault_addr);
53
+
54
+ this.VAULT_TOKEN = process.env.VAULT_TOKEN;
55
+ console.error("vauth bound to '%s'", this.vault_addr);
51
56
  }
52
57
 
53
- async _get_token() {
54
- let {vault_addr, ssh_auth, jwt_auth} = this.rc;
58
+ async connect() {
59
+ let {VAULT_TOKEN, rc : {ssh_auth, jwt_auth}} = this;
55
60
 
56
- let token = this.rc.VAULT_TOKEN;
57
- if(!token && ssh_auth && process.env.SSH_AUTH_SOCK)
58
- token = await this._login_vault_ssh({...ssh_auth, vault_addr});
61
+ if(!VAULT_TOKEN && ssh_auth && process.env.SSH_AUTH_SOCK)
62
+ VAULT_TOKEN = await this._login_vault_ssh({...ssh_auth});
59
63
 
60
- if(!token && jwt_auth && jwt_auth.jwt) {
64
+ if(!VAULT_TOKEN && jwt_auth && jwt_auth.jwt) {
61
65
  let {path, jwt, role} = jwt_auth, payload = {jwt, role};
62
- token = await this._login_vault(vault_addr, path, payload);
66
+ VAULT_TOKEN = await this._login_vault(path, payload);
63
67
  }
64
- return token;
68
+ this.VAULT_TOKEN = VAULT_TOKEN;
65
69
  }
66
70
 
67
71
  async login(source = false) {
68
-
69
- let VAULT_TOKEN = await this._get_token();
72
+ await this.connect();
70
73
  if(source) {
71
- let env = {VAULT_TOKEN};
74
+ let env = {VAULT_TOKEN : this.VAULT_TOKEN};
72
75
  this._publish_env(env);
73
76
  process.exit();
74
77
  }
75
- return VAULT_TOKEN;
76
78
  }
77
79
 
78
80
  _publish_env(env) {
@@ -84,7 +86,70 @@ class vvauth {
84
86
  process.stdout.write(cmds.join("\n") + "\n");
85
87
  }
86
88
 
87
- async _login_vault_ssh({vault_addr, path = 'ssh', role}) {
89
+
90
+ async set(k, v) {
91
+ let {entity_id, identity : {metadata}} = await this._get_profile();
92
+ if(!metadata)
93
+ metadata = {};
94
+ let key_name = `env_${k.toUpperCase()}`;
95
+ metadata[key_name] = v;
96
+ await this._update_identity(this.VAULT_TOKEN, entity_id, {metadata});
97
+ }
98
+
99
+ async unset(k) {
100
+ await this.set(k, undefined);
101
+ }
102
+
103
+ async show() {
104
+ let {profile} = await this._get_profile();
105
+ return profile;
106
+ }
107
+
108
+ async _get_profile() {
109
+ await this.connect();
110
+ let {entity_id} = await this._lookup_token(this.VAULT_TOKEN);
111
+ let identity = await this._lookup_identity(this.VAULT_TOKEN, entity_id);
112
+ let profile = {};
113
+ for(let alias of identity.aliases) {
114
+ for(let [k, v] of Object.entries(alias.custom_metadata || {})) {
115
+ if(k.startsWith('env_'))
116
+ profile[k.substr(4)] = v;
117
+ }
118
+ }
119
+ for(let [k, v] of Object.entries(identity.metadata || {})) {
120
+ if(k.startsWith('env_'))
121
+ profile[k.substr(4)] = v;
122
+ }
123
+ return {entity_id, identity, profile};
124
+ }
125
+
126
+ async env(source = false) {
127
+ let {profile} = await this._get_profile();
128
+
129
+ let env = {VAULT_TOKEN : this.VAULT_TOKEN}, {env : {git, map}} = this.rc;
130
+ if(git) {
131
+ map = {...map,
132
+ "GIT_COMMITTER_NAME" : "VAUTH_USER_NAME",
133
+ "GIT_COMMITTER_EMAIL" : "VAUTH_USER_MAIL",
134
+ "GIT_AUTHOR_EMAIL" : "VAUTH_USER_MAIL",
135
+ "GIT_AUTHOR_NAME" : "VAUTH_USER_NAME",
136
+ "GIT_USER_LOGIN" : "VAUTH_USER_LOGIN",
137
+ };
138
+ }
139
+
140
+ for(let [k, v] of Object.entries(map || {})) {
141
+ if(profile[v])
142
+ env[k] = profile[v];
143
+ }
144
+
145
+ if(source) {
146
+ this._publish_env(env);
147
+ process.exit();
148
+ }
149
+ }
150
+
151
+ async _login_vault_ssh({path = 'ssh', role}) {
152
+ logger.info("Trying to auth as '%s'", role);
88
153
  let sock;
89
154
  await new Promise(resolve => (sock = net.connect(process.env.SSH_AUTH_SOCK, resolve)));
90
155
  let agent = new SSHAgent(sock);
@@ -95,7 +160,7 @@ class vvauth {
95
160
  if(token)
96
161
  return;
97
162
 
98
- let remote_url = `${trim(vault_addr, '/')}/v1/auth/${path}/nonce`;
163
+ let remote_url = `${trim(this.vault_addr, '/')}/v1/auth/${path}/nonce`;
99
164
  let query = {...url.parse(remote_url), json : true};
100
165
  let res = await request(query);
101
166
  let {data : {nonce}} = JSON.parse(String(await drain(res)));
@@ -105,7 +170,7 @@ class vvauth {
105
170
 
106
171
  const payload = {public_key, role, nonce : Buffer.from(nonce).toString('base64'), signature};
107
172
  try {
108
- token = await this._login_vault(vault_addr, path, payload);
173
+ token = await this._login_vault(path, payload);
109
174
  } catch(err) {
110
175
  logger.debug("ssh : invalid challenge for public key", comment);
111
176
  }
@@ -137,8 +202,32 @@ class vvauth {
137
202
  console.error(`Installation ok, please \nsource ${bashrc_path}`);
138
203
  }
139
204
 
140
- async _login_vault(vault_addr, path, payload) {
141
- let remote_url = `${trim(vault_addr, '/')}/v1/auth/${path}/login`;
205
+ async _lookup_token(token) {
206
+ let remote_url = `${trim(this.vault_addr, '/')}/v1/auth/token/lookup-self`;
207
+ let query = {...url.parse(remote_url), headers : {'x-vault-token' : token}, expect : 200};
208
+ let res = await request(query);
209
+ let response = JSON.parse(await drain(res)).data;
210
+ return response;
211
+ }
212
+
213
+ async _lookup_identity(token, id) {
214
+ let remote_url = `${trim(this.vault_addr, '/')}/v1/identity/entity/id/${id}`;
215
+ let query = {...url.parse(remote_url), headers : {'x-vault-token' : token}, expect : 200};
216
+ let res = await request(query);
217
+ return JSON.parse(String(await drain(res))).data;
218
+ }
219
+
220
+ async _update_identity(token, id, payload) {
221
+ let remote_url = `${trim(this.vault_addr, '/')}/v1/identity/entity/id/${id}`;
222
+ let query = {...url.parse(remote_url), headers : {'x-vault-token' : token}, expect : 204, json : true};
223
+ await request(query, payload);
224
+ return payload;
225
+ }
226
+
227
+
228
+
229
+ async _login_vault(path, payload) {
230
+ let remote_url = `${trim(this.vault_addr, '/')}/v1/auth/${path}/login`;
142
231
  let query = {...url.parse(remote_url), json : true};
143
232
  let res = await request(query, payload);
144
233
  let response = String(await drain(res));
@@ -147,7 +236,6 @@ class vvauth {
147
236
  throw `Could not login to vault : ${response}`;
148
237
 
149
238
  response = JSON.parse(response);
150
- //console.log(response);
151
239
  let token = get(response, 'auth.client_token');
152
240
  return token;
153
241
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vvauth",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "Vault Auth helper",
5
5
  "main": "index.js",
6
6
  "bin": {