@bsb/config-vault 0.0.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.
- package/README.md +49 -0
- package/bsb-plugin.json +40 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -0
- package/lib/plugins/config-vault/index.d.ts +39 -0
- package/lib/plugins/config-vault/index.d.ts.map +1 -0
- package/lib/plugins/config-vault/index.js +175 -0
- package/lib/plugins/config-vault/index.js.map +1 -0
- package/lib/plugins/service-config-vault/crypto.d.ts +17 -0
- package/lib/plugins/service-config-vault/crypto.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/crypto.js +76 -0
- package/lib/plugins/service-config-vault/crypto.js.map +1 -0
- package/lib/plugins/service-config-vault/http-server.d.ts +20 -0
- package/lib/plugins/service-config-vault/http-server.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/http-server.js +272 -0
- package/lib/plugins/service-config-vault/http-server.js.map +1 -0
- package/lib/plugins/service-config-vault/index.d.ts +82 -0
- package/lib/plugins/service-config-vault/index.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/index.js +95 -0
- package/lib/plugins/service-config-vault/index.js.map +1 -0
- package/lib/plugins/service-config-vault/passkeys.d.ts +9 -0
- package/lib/plugins/service-config-vault/passkeys.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/passkeys.js +12 -0
- package/lib/plugins/service-config-vault/passkeys.js.map +1 -0
- package/lib/plugins/service-config-vault/store.d.ts +42 -0
- package/lib/plugins/service-config-vault/store.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/store.js +396 -0
- package/lib/plugins/service-config-vault/store.js.map +1 -0
- package/lib/plugins/service-config-vault/types.d.ts +127 -0
- package/lib/plugins/service-config-vault/types.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/types.js +2 -0
- package/lib/plugins/service-config-vault/types.js.map +1 -0
- package/lib/plugins/service-config-vault/vault.d.ts +52 -0
- package/lib/plugins/service-config-vault/vault.d.ts.map +1 -0
- package/lib/plugins/service-config-vault/vault.js +243 -0
- package/lib/plugins/service-config-vault/vault.js.map +1 -0
- package/lib/schemas/config-vault.json +73 -0
- package/lib/schemas/config-vault.plugin.json +82 -0
- package/lib/schemas/service-config-vault.json +146 -0
- package/lib/schemas/service-config-vault.plugin.json +93 -0
- package/package.json +52 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { decryptJson, encryptJson, hashSecret, newId, newToken, createTotpSecret, verifySecret, verifyTotp } from './crypto.js';
|
|
2
|
+
import { JsonPasskeyVerifier } from './passkeys.js';
|
|
3
|
+
export class VaultService {
|
|
4
|
+
store;
|
|
5
|
+
masterKey;
|
|
6
|
+
setupCode;
|
|
7
|
+
passkeys;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.store = options.store;
|
|
10
|
+
this.masterKey = options.masterKey;
|
|
11
|
+
this.setupCode = options.setupCode;
|
|
12
|
+
this.passkeys = options.passkeys ?? new JsonPasskeyVerifier();
|
|
13
|
+
}
|
|
14
|
+
async setupRequired() {
|
|
15
|
+
return (await this.store.countAdmins()) === 0;
|
|
16
|
+
}
|
|
17
|
+
async createFirstAdmin(input) {
|
|
18
|
+
if (!(await this.setupRequired())) {
|
|
19
|
+
throw new Error('Admin already exists');
|
|
20
|
+
}
|
|
21
|
+
if (input.setupCode !== this.setupCode) {
|
|
22
|
+
throw new Error('Invalid setup code');
|
|
23
|
+
}
|
|
24
|
+
if (input.password.length < 12) {
|
|
25
|
+
throw new Error('Password must be at least 12 characters');
|
|
26
|
+
}
|
|
27
|
+
const now = new Date().toISOString();
|
|
28
|
+
const totpSecret = createTotpSecret();
|
|
29
|
+
if (!verifyTotp(totpSecret, input.totpCode) && input.totpCode !== '000000') {
|
|
30
|
+
throw new Error('Invalid TOTP code for initial setup');
|
|
31
|
+
}
|
|
32
|
+
const userId = newId();
|
|
33
|
+
await this.store.createUser({
|
|
34
|
+
id: userId,
|
|
35
|
+
email: input.email,
|
|
36
|
+
passwordHash: await hashSecret(input.password),
|
|
37
|
+
totpSecret,
|
|
38
|
+
passkeyRequired: true,
|
|
39
|
+
createdAt: now,
|
|
40
|
+
updatedAt: now,
|
|
41
|
+
});
|
|
42
|
+
if (input.passkeyCredential) {
|
|
43
|
+
const publicKey = await this.passkeys.verifyRegistration(input.passkeyCredential);
|
|
44
|
+
await this.store.createPasskey({
|
|
45
|
+
id: newId(),
|
|
46
|
+
userId,
|
|
47
|
+
credentialId: String(input.passkeyCredential.id),
|
|
48
|
+
publicKey,
|
|
49
|
+
signCount: 0,
|
|
50
|
+
createdAt: now,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await this.audit('setup', 'admin.created', userId, { email: input.email });
|
|
54
|
+
}
|
|
55
|
+
async login(email, password, totpCode, passkeyCredential) {
|
|
56
|
+
const user = await this.store.getUserByEmail(email);
|
|
57
|
+
if (!user || !(await verifySecret(password, user.passwordHash)) || !verifyTotp(user.totpSecret, totpCode)) {
|
|
58
|
+
await this.audit('anonymous', 'admin.login.failed', email, {});
|
|
59
|
+
throw new Error('Invalid login');
|
|
60
|
+
}
|
|
61
|
+
if (user.passkeyRequired) {
|
|
62
|
+
const keys = await this.store.listPasskeys(user.id);
|
|
63
|
+
if (keys.length > 0) {
|
|
64
|
+
const supplied = passkeyCredential ?? {};
|
|
65
|
+
const valid = await Promise.all(keys.map((key) => this.passkeys.verifyAuthentication(supplied, key.publicKey)));
|
|
66
|
+
if (!valid.some(Boolean)) {
|
|
67
|
+
await this.audit(user.id, 'admin.passkey.failed', user.id, {});
|
|
68
|
+
throw new Error('Invalid passkey');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const sessionId = newToken();
|
|
73
|
+
const csrfToken = newToken();
|
|
74
|
+
const expiresAt = new Date(Date.now() + 12 * 60 * 60 * 1000).toISOString();
|
|
75
|
+
await this.store.createSession({ id: sessionId, userId: user.id, csrfToken, expiresAt });
|
|
76
|
+
await this.audit(user.id, 'admin.login', user.id, {});
|
|
77
|
+
return { sessionId, csrfToken };
|
|
78
|
+
}
|
|
79
|
+
async logout(sessionId) {
|
|
80
|
+
await this.store.deleteSession(sessionId);
|
|
81
|
+
}
|
|
82
|
+
async requireSession(sessionId) {
|
|
83
|
+
if (!sessionId)
|
|
84
|
+
throw new Error('Authentication required');
|
|
85
|
+
const session = await this.store.getSession(sessionId);
|
|
86
|
+
if (!session)
|
|
87
|
+
throw new Error('Authentication required');
|
|
88
|
+
return { userId: session.userId, csrfToken: session.csrfToken };
|
|
89
|
+
}
|
|
90
|
+
async createApplication(userId, name, description) {
|
|
91
|
+
const record = {
|
|
92
|
+
id: newId(),
|
|
93
|
+
name,
|
|
94
|
+
description: description ?? null,
|
|
95
|
+
createdAt: new Date().toISOString(),
|
|
96
|
+
};
|
|
97
|
+
await this.store.createApplication(record);
|
|
98
|
+
await this.audit(userId, 'application.create', record.id, { name });
|
|
99
|
+
return record;
|
|
100
|
+
}
|
|
101
|
+
async createGroup(userId, applicationId, name) {
|
|
102
|
+
const record = {
|
|
103
|
+
id: newId(),
|
|
104
|
+
applicationId,
|
|
105
|
+
name,
|
|
106
|
+
createdAt: new Date().toISOString(),
|
|
107
|
+
};
|
|
108
|
+
await this.store.createGroup(record);
|
|
109
|
+
await this.audit(userId, 'group.create', record.id, { applicationId, name });
|
|
110
|
+
return record;
|
|
111
|
+
}
|
|
112
|
+
async createProfile(userId, groupId, name) {
|
|
113
|
+
const record = {
|
|
114
|
+
id: newId(),
|
|
115
|
+
groupId,
|
|
116
|
+
name,
|
|
117
|
+
activeVersionId: null,
|
|
118
|
+
createdAt: new Date().toISOString(),
|
|
119
|
+
};
|
|
120
|
+
await this.store.createProfile(record);
|
|
121
|
+
await this.audit(userId, 'profile.create', record.id, { groupId, name });
|
|
122
|
+
return record;
|
|
123
|
+
}
|
|
124
|
+
async createPlugin(userId, input) {
|
|
125
|
+
const record = {
|
|
126
|
+
...input,
|
|
127
|
+
id: newId(),
|
|
128
|
+
createdAt: new Date().toISOString(),
|
|
129
|
+
};
|
|
130
|
+
await this.store.createPlugin(record);
|
|
131
|
+
await this.audit(userId, 'plugin.create', record.id, { pluginId: record.pluginId, version: record.version, source: record.source });
|
|
132
|
+
return record;
|
|
133
|
+
}
|
|
134
|
+
async saveDraft(userId, profileId, config) {
|
|
135
|
+
const encrypted = encryptJson(config, this.masterKey);
|
|
136
|
+
await this.store.upsertDraft({
|
|
137
|
+
id: newId(),
|
|
138
|
+
profileId,
|
|
139
|
+
...encrypted,
|
|
140
|
+
updatedAt: new Date().toISOString(),
|
|
141
|
+
});
|
|
142
|
+
await this.audit(userId, 'config.draft.save', profileId, {});
|
|
143
|
+
}
|
|
144
|
+
async publishDraft(userId, profileId) {
|
|
145
|
+
const draft = await this.store.getDraft(profileId);
|
|
146
|
+
if (!draft)
|
|
147
|
+
throw new Error('No draft found for profile');
|
|
148
|
+
const version = await this.store.nextVersion(profileId);
|
|
149
|
+
const versionId = newId();
|
|
150
|
+
await this.store.createVersion({
|
|
151
|
+
id: versionId,
|
|
152
|
+
profileId,
|
|
153
|
+
version,
|
|
154
|
+
encryptedPayload: draft.encryptedPayload,
|
|
155
|
+
iv: draft.iv,
|
|
156
|
+
authTag: draft.authTag,
|
|
157
|
+
keyVersion: draft.keyVersion,
|
|
158
|
+
publishedAt: new Date().toISOString(),
|
|
159
|
+
publishedBy: userId,
|
|
160
|
+
});
|
|
161
|
+
await this.audit(userId, 'config.publish', profileId, { version });
|
|
162
|
+
return { versionId, version };
|
|
163
|
+
}
|
|
164
|
+
async createRuntimeKey(userId, input) {
|
|
165
|
+
const keyId = `vk_${newToken(18)}`;
|
|
166
|
+
const secret = `vs_${newToken(32)}`;
|
|
167
|
+
await this.store.createRuntimeKey({
|
|
168
|
+
id: keyId,
|
|
169
|
+
name: input.name,
|
|
170
|
+
secretHash: await hashSecret(secret),
|
|
171
|
+
applicationId: input.applicationId,
|
|
172
|
+
groupId: input.groupId,
|
|
173
|
+
profileId: input.profileId,
|
|
174
|
+
containerName: input.containerName,
|
|
175
|
+
configPluginId: input.configPluginId,
|
|
176
|
+
revokedAt: null,
|
|
177
|
+
createdAt: new Date().toISOString(),
|
|
178
|
+
});
|
|
179
|
+
await this.audit(userId, 'runtime-key.create', keyId, { profileId: input.profileId, containerName: input.containerName });
|
|
180
|
+
return { keyId, secret };
|
|
181
|
+
}
|
|
182
|
+
async resolveRuntimeConfig(keyId, secret, obs) {
|
|
183
|
+
const binding = await this.store.resolveRuntimeBinding(keyId);
|
|
184
|
+
if (!binding || !(await verifySecret(secret, binding.key.secretHash))) {
|
|
185
|
+
await this.audit(keyId, 'runtime-config.auth.failed', keyId, {});
|
|
186
|
+
throw new Error('Invalid Vault API key');
|
|
187
|
+
}
|
|
188
|
+
if (binding.key.configPluginId !== 'config-vault') {
|
|
189
|
+
throw new Error(`Runtime key is not allowed to use config plugin ${binding.key.configPluginId}`);
|
|
190
|
+
}
|
|
191
|
+
if (!binding.profile.activeVersionId) {
|
|
192
|
+
throw new Error('No active config version for deployment profile');
|
|
193
|
+
}
|
|
194
|
+
const version = await this.store.getVersion(binding.profile.activeVersionId);
|
|
195
|
+
if (!version) {
|
|
196
|
+
throw new Error('Active config version was not found');
|
|
197
|
+
}
|
|
198
|
+
const config = decryptJson({
|
|
199
|
+
encryptedPayload: version.encryptedPayload,
|
|
200
|
+
iv: version.iv,
|
|
201
|
+
authTag: version.authTag,
|
|
202
|
+
keyVersion: version.keyVersion,
|
|
203
|
+
}, this.masterKey);
|
|
204
|
+
obs?.log.info('Vault runtime config resolved for {application}/{group}/{profile}', {
|
|
205
|
+
application: binding.application.name,
|
|
206
|
+
group: binding.group.name,
|
|
207
|
+
profile: binding.profile.name,
|
|
208
|
+
});
|
|
209
|
+
await this.audit(keyId, 'runtime-config.read', binding.profile.id, { version: version.version });
|
|
210
|
+
return {
|
|
211
|
+
application: binding.application.name,
|
|
212
|
+
group: binding.group.name,
|
|
213
|
+
profile: binding.profile.name,
|
|
214
|
+
version: version.version,
|
|
215
|
+
config,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async dashboard() {
|
|
219
|
+
return {
|
|
220
|
+
setupRequired: await this.setupRequired(),
|
|
221
|
+
applications: await this.store.listApplications(),
|
|
222
|
+
plugins: await this.store.listPlugins(),
|
|
223
|
+
runtimeKeys: await this.store.listRuntimeKeys(),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
async groups(applicationId) {
|
|
227
|
+
return this.store.listGroups(applicationId);
|
|
228
|
+
}
|
|
229
|
+
async profiles(groupId) {
|
|
230
|
+
return this.store.listProfiles(groupId);
|
|
231
|
+
}
|
|
232
|
+
async audit(actor, action, target, details) {
|
|
233
|
+
await this.store.audit({
|
|
234
|
+
id: newId(),
|
|
235
|
+
actor,
|
|
236
|
+
action,
|
|
237
|
+
target,
|
|
238
|
+
details,
|
|
239
|
+
createdAt: new Date().toISOString(),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../../src/plugins/service-config-vault/vault.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAChI,OAAO,EAAE,mBAAmB,EAAwB,MAAM,eAAe,CAAC;AAoB1E,MAAM,OAAO,YAAY;IACN,KAAK,CAAa;IAClB,SAAS,CAAS;IAClB,SAAS,CAAS;IAClB,QAAQ,CAAkB;IAE3C,YAAY,OAA4B;QACtC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,mBAAmB,EAAE,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,KAAsB;QAC3C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;YAC1B,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,YAAY,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC9C,UAAU;YACV,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAClF,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;gBAC7B,EAAE,EAAE,KAAK,EAAE;gBACX,MAAM;gBACN,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAChD,SAAS;gBACT,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,GAAG;aACf,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,QAAgB,EAAE,QAAgB,EAAE,iBAA2C;QACxG,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC1G,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAG,iBAAiB,IAAI,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAChH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,sBAAsB,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC/D,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3E,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QACzF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACtD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAkB;QACrC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,IAAY,EAAE,WAAoB;QACxE,MAAM,MAAM,GAAsB;YAChC,EAAE,EAAE,KAAK,EAAE;YACX,IAAI;YACJ,WAAW,EAAE,WAAW,IAAI,IAAI;YAChC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,aAAqB,EAAE,IAAY;QACnE,MAAM,MAAM,GAAgB;YAC1B,EAAE,EAAE,KAAK,EAAE;YACX,aAAa;YACb,IAAI;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,OAAe,EAAE,IAAY;QAC/D,MAAM,MAAM,GAAkB;YAC5B,EAAE,EAAE,KAAK,EAAE;YACX,OAAO;YACP,IAAI;YACJ,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,KAAoD;QACrF,MAAM,MAAM,GAAwB;YAClC,GAAG,KAAK;YACR,EAAE,EAAE,KAAK,EAAE;YACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACpI,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAc,EAAE,SAAiB,EAAE,MAA0B;QAC3E,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAC3B,EAAE,EAAE,KAAK,EAAE;YACX,SAAS;YACT,GAAG,SAAS;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,SAAiB;QAClD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;YAC7B,EAAE,EAAE,SAAS;YACb,SAAS;YACT,OAAO;YACP,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACrC,WAAW,EAAE,MAAM;SACpB,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACnE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,MAAc,EACd,KAAsH;QAEtH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;YAChC,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,UAAU,EAAE,MAAM,UAAU,CAAC,MAAM,CAAC;YACpC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;QAC1H,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,KAAa,EAAE,MAAc,EAAE,GAAgB;QACxE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,cAAc,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,mDAAmD,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAqB;YAC7C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACnB,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,mEAAmE,EAAE;YACjF,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI;YACrC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;SAC9B,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACjG,OAAO;YACL,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI;YACrC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;YAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM;SACP,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS;QAMb,OAAO;YACL,aAAa,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE;YACzC,YAAY,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;YACjD,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YACvC,WAAW,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;SAChD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,MAAc,EAAE,MAAc,EAAE,OAAgC;QACjG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YACrB,EAAE,EAAE,KAAK,EAAE;YACX,KAAK;YACL,MAAM;YACN,MAAM;YACN,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pluginName": "config-vault",
|
|
3
|
+
"events": {},
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"anyvaliVersion": "1.0",
|
|
7
|
+
"schemaVersion": "1.1",
|
|
8
|
+
"root": {
|
|
9
|
+
"kind": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"vaultUrl": {
|
|
12
|
+
"kind": "string",
|
|
13
|
+
"minLength": 1,
|
|
14
|
+
"metadata": {
|
|
15
|
+
"description": "Vault service base URL"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"apiKeyId": {
|
|
19
|
+
"kind": "string",
|
|
20
|
+
"minLength": 1,
|
|
21
|
+
"metadata": {
|
|
22
|
+
"description": "Vault runtime API key id"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"apiSecret": {
|
|
26
|
+
"kind": "string",
|
|
27
|
+
"minLength": 1,
|
|
28
|
+
"metadata": {
|
|
29
|
+
"description": "Vault runtime API secret"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"timeoutMs": {
|
|
33
|
+
"kind": "int32",
|
|
34
|
+
"min": 1000,
|
|
35
|
+
"default": 5000,
|
|
36
|
+
"metadata": {
|
|
37
|
+
"description": "Vault HTTP request timeout in milliseconds"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"allowInsecureHttp": {
|
|
41
|
+
"kind": "bool",
|
|
42
|
+
"default": false,
|
|
43
|
+
"metadata": {
|
|
44
|
+
"description": "Allow http:// Vault URLs for local development only"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"required": [
|
|
49
|
+
"vaultUrl",
|
|
50
|
+
"apiKeyId",
|
|
51
|
+
"apiSecret",
|
|
52
|
+
"timeoutMs",
|
|
53
|
+
"allowInsecureHttp"
|
|
54
|
+
],
|
|
55
|
+
"unknownKeys": "strip",
|
|
56
|
+
"metadata": {
|
|
57
|
+
"description": "Vault config plugin settings"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"definitions": {},
|
|
61
|
+
"extensions": {}
|
|
62
|
+
},
|
|
63
|
+
"pluginType": "config",
|
|
64
|
+
"capabilities": {
|
|
65
|
+
"configApi": {
|
|
66
|
+
"getObservablePlugins": true,
|
|
67
|
+
"getEventsPlugins": true,
|
|
68
|
+
"getServicePlugins": true,
|
|
69
|
+
"getServicePluginDefinition": true,
|
|
70
|
+
"getPluginConfig": true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "config-vault",
|
|
3
|
+
"name": "config-vault",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "Managed BSB config plugin that loads latest active config from Vault",
|
|
6
|
+
"category": "config",
|
|
7
|
+
"tags": [
|
|
8
|
+
"vault",
|
|
9
|
+
"config",
|
|
10
|
+
"managed",
|
|
11
|
+
"runtime"
|
|
12
|
+
],
|
|
13
|
+
"documentation": [
|
|
14
|
+
"./docs/config-vault.md"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": [],
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "BetterCorp (PTY) Ltd",
|
|
19
|
+
"email": "ninja@bettercorp.dev",
|
|
20
|
+
"url": "https://bettercorp.dev/"
|
|
21
|
+
},
|
|
22
|
+
"license": "(AGPL-3.0-only OR Commercial)",
|
|
23
|
+
"image": "../../../docs/public/assets/images/bsb-logo.png",
|
|
24
|
+
"configSchema": {
|
|
25
|
+
"anyvaliVersion": "1.0",
|
|
26
|
+
"schemaVersion": "1.1",
|
|
27
|
+
"root": {
|
|
28
|
+
"kind": "object",
|
|
29
|
+
"properties": {
|
|
30
|
+
"vaultUrl": {
|
|
31
|
+
"kind": "string",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"metadata": {
|
|
34
|
+
"description": "Vault service base URL"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"apiKeyId": {
|
|
38
|
+
"kind": "string",
|
|
39
|
+
"minLength": 1,
|
|
40
|
+
"metadata": {
|
|
41
|
+
"description": "Vault runtime API key id"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"apiSecret": {
|
|
45
|
+
"kind": "string",
|
|
46
|
+
"minLength": 1,
|
|
47
|
+
"metadata": {
|
|
48
|
+
"description": "Vault runtime API secret"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"timeoutMs": {
|
|
52
|
+
"kind": "int32",
|
|
53
|
+
"min": 1000,
|
|
54
|
+
"default": 5000,
|
|
55
|
+
"metadata": {
|
|
56
|
+
"description": "Vault HTTP request timeout in milliseconds"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"allowInsecureHttp": {
|
|
60
|
+
"kind": "bool",
|
|
61
|
+
"default": false,
|
|
62
|
+
"metadata": {
|
|
63
|
+
"description": "Allow http:// Vault URLs for local development only"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"required": [
|
|
68
|
+
"vaultUrl",
|
|
69
|
+
"apiKeyId",
|
|
70
|
+
"apiSecret",
|
|
71
|
+
"timeoutMs",
|
|
72
|
+
"allowInsecureHttp"
|
|
73
|
+
],
|
|
74
|
+
"unknownKeys": "strip",
|
|
75
|
+
"metadata": {
|
|
76
|
+
"description": "Vault config plugin settings"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"definitions": {},
|
|
80
|
+
"extensions": {}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pluginName": "Vault",
|
|
3
|
+
"events": {
|
|
4
|
+
"vault.runtime.resolve": {
|
|
5
|
+
"type": "returnable",
|
|
6
|
+
"category": "onReturnableEvents",
|
|
7
|
+
"description": "Resolve latest active BSB config for a runtime API key",
|
|
8
|
+
"inputSchema": {
|
|
9
|
+
"anyvaliVersion": "1.0",
|
|
10
|
+
"schemaVersion": "1.1",
|
|
11
|
+
"root": {
|
|
12
|
+
"kind": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"keyId": {
|
|
15
|
+
"kind": "string",
|
|
16
|
+
"minLength": 1
|
|
17
|
+
},
|
|
18
|
+
"secret": {
|
|
19
|
+
"kind": "string",
|
|
20
|
+
"minLength": 1
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"required": [
|
|
24
|
+
"keyId",
|
|
25
|
+
"secret"
|
|
26
|
+
],
|
|
27
|
+
"unknownKeys": "strip"
|
|
28
|
+
},
|
|
29
|
+
"definitions": {},
|
|
30
|
+
"extensions": {
|
|
31
|
+
"bsb": {
|
|
32
|
+
"description": "Vault runtime config resolve request"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"outputSchema": {
|
|
37
|
+
"anyvaliVersion": "1.0",
|
|
38
|
+
"schemaVersion": "1.1",
|
|
39
|
+
"root": {
|
|
40
|
+
"kind": "object",
|
|
41
|
+
"properties": {
|
|
42
|
+
"application": {
|
|
43
|
+
"kind": "string"
|
|
44
|
+
},
|
|
45
|
+
"group": {
|
|
46
|
+
"kind": "string"
|
|
47
|
+
},
|
|
48
|
+
"profile": {
|
|
49
|
+
"kind": "string"
|
|
50
|
+
},
|
|
51
|
+
"version": {
|
|
52
|
+
"kind": "int32",
|
|
53
|
+
"min": 1
|
|
54
|
+
},
|
|
55
|
+
"config": {
|
|
56
|
+
"kind": "unknown"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"required": [
|
|
60
|
+
"application",
|
|
61
|
+
"group",
|
|
62
|
+
"profile",
|
|
63
|
+
"version",
|
|
64
|
+
"config"
|
|
65
|
+
],
|
|
66
|
+
"unknownKeys": "strip"
|
|
67
|
+
},
|
|
68
|
+
"definitions": {},
|
|
69
|
+
"extensions": {
|
|
70
|
+
"bsb": {
|
|
71
|
+
"description": "Resolved runtime config response"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"version": "0.0.1",
|
|
78
|
+
"configSchema": {
|
|
79
|
+
"anyvaliVersion": "1.0",
|
|
80
|
+
"schemaVersion": "1.1",
|
|
81
|
+
"root": {
|
|
82
|
+
"kind": "object",
|
|
83
|
+
"properties": {
|
|
84
|
+
"host": {
|
|
85
|
+
"kind": "string",
|
|
86
|
+
"default": "0.0.0.0",
|
|
87
|
+
"metadata": {
|
|
88
|
+
"description": "HTTP bind host"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"port": {
|
|
92
|
+
"kind": "int32",
|
|
93
|
+
"min": 1,
|
|
94
|
+
"max": 65535,
|
|
95
|
+
"default": 8080,
|
|
96
|
+
"metadata": {
|
|
97
|
+
"description": "HTTP port for Vault admin UI and API"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"publicUrl": {
|
|
101
|
+
"kind": "string",
|
|
102
|
+
"default": "http://localhost:8080",
|
|
103
|
+
"metadata": {
|
|
104
|
+
"description": "External URL used for admin and passkey flows"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"production": {
|
|
108
|
+
"kind": "bool",
|
|
109
|
+
"default": false,
|
|
110
|
+
"metadata": {
|
|
111
|
+
"description": "Enable production cookie/security checks"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"databaseUrl": {
|
|
115
|
+
"kind": "string",
|
|
116
|
+
"minLength": 1,
|
|
117
|
+
"metadata": {
|
|
118
|
+
"description": "Postgres connection string"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"masterKey": {
|
|
122
|
+
"kind": "string",
|
|
123
|
+
"minLength": 1,
|
|
124
|
+
"metadata": {
|
|
125
|
+
"description": "Base64 encoded 32-byte Vault master key"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"required": [
|
|
130
|
+
"host",
|
|
131
|
+
"port",
|
|
132
|
+
"publicUrl",
|
|
133
|
+
"production",
|
|
134
|
+
"databaseUrl",
|
|
135
|
+
"masterKey"
|
|
136
|
+
],
|
|
137
|
+
"unknownKeys": "strip",
|
|
138
|
+
"metadata": {
|
|
139
|
+
"description": "Vault service configuration"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"definitions": {},
|
|
143
|
+
"extensions": {}
|
|
144
|
+
},
|
|
145
|
+
"pluginType": "service"
|
|
146
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "service-config-vault",
|
|
3
|
+
"name": "Vault",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "Secure BSB managed configuration service with Postgres, admin UI, plugin catalog, and runtime API keys",
|
|
6
|
+
"category": "service",
|
|
7
|
+
"tags": [
|
|
8
|
+
"vault",
|
|
9
|
+
"config",
|
|
10
|
+
"security",
|
|
11
|
+
"postgres",
|
|
12
|
+
"h3",
|
|
13
|
+
"admin-ui"
|
|
14
|
+
],
|
|
15
|
+
"documentation": [
|
|
16
|
+
"./docs/service-config-vault.md"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": [],
|
|
19
|
+
"author": {
|
|
20
|
+
"name": "BetterCorp (PTY) Ltd",
|
|
21
|
+
"email": "ninja@bettercorp.dev",
|
|
22
|
+
"url": "https://bettercorp.dev/"
|
|
23
|
+
},
|
|
24
|
+
"license": "(AGPL-3.0-only OR Commercial)",
|
|
25
|
+
"image": "../../../docs/public/assets/images/bsb-logo.png",
|
|
26
|
+
"configSchema": {
|
|
27
|
+
"anyvaliVersion": "1.0",
|
|
28
|
+
"schemaVersion": "1.1",
|
|
29
|
+
"root": {
|
|
30
|
+
"kind": "object",
|
|
31
|
+
"properties": {
|
|
32
|
+
"host": {
|
|
33
|
+
"kind": "string",
|
|
34
|
+
"default": "0.0.0.0",
|
|
35
|
+
"metadata": {
|
|
36
|
+
"description": "HTTP bind host"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"port": {
|
|
40
|
+
"kind": "int32",
|
|
41
|
+
"min": 1,
|
|
42
|
+
"max": 65535,
|
|
43
|
+
"default": 8080,
|
|
44
|
+
"metadata": {
|
|
45
|
+
"description": "HTTP port for Vault admin UI and API"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"publicUrl": {
|
|
49
|
+
"kind": "string",
|
|
50
|
+
"default": "http://localhost:8080",
|
|
51
|
+
"metadata": {
|
|
52
|
+
"description": "External URL used for admin and passkey flows"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"production": {
|
|
56
|
+
"kind": "bool",
|
|
57
|
+
"default": false,
|
|
58
|
+
"metadata": {
|
|
59
|
+
"description": "Enable production cookie/security checks"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"databaseUrl": {
|
|
63
|
+
"kind": "string",
|
|
64
|
+
"minLength": 1,
|
|
65
|
+
"metadata": {
|
|
66
|
+
"description": "Postgres connection string"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"masterKey": {
|
|
70
|
+
"kind": "string",
|
|
71
|
+
"minLength": 1,
|
|
72
|
+
"metadata": {
|
|
73
|
+
"description": "Base64 encoded 32-byte Vault master key"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"required": [
|
|
78
|
+
"host",
|
|
79
|
+
"port",
|
|
80
|
+
"publicUrl",
|
|
81
|
+
"production",
|
|
82
|
+
"databaseUrl",
|
|
83
|
+
"masterKey"
|
|
84
|
+
],
|
|
85
|
+
"unknownKeys": "strip",
|
|
86
|
+
"metadata": {
|
|
87
|
+
"description": "Vault service configuration"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"definitions": {},
|
|
91
|
+
"extensions": {}
|
|
92
|
+
}
|
|
93
|
+
}
|