@ouro.bot/cli 0.1.0-alpha.557 → 0.1.0-alpha.559
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/changelog.json
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.559",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Cached agent-name lookups no longer emit `identity.resolve` on every call, cutting the largest repeated daemon log event source while preserving the first argv resolution event.",
|
|
8
|
+
"Identity tests now lock the lower-volume logging contract so cached `getAgentName()` calls stay quiet.",
|
|
9
|
+
"`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the daemon log volume release."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"version": "0.1.0-alpha.558",
|
|
14
|
+
"changes": [
|
|
15
|
+
"Rejected local vault unlock material is now cleared after Bitwarden proves it is wrong, so a stale Keychain/DPAPI/Secret Service/plaintext entry cannot keep retrying across fresh CLI processes and rate-limit the agent vault.",
|
|
16
|
+
"Legacy vault unlock entries are no longer copied to canonical coordinates during read. Ouro now canonicalizes them only after a successful vault login, preventing unvalidated local material from poisoning the primary unlock slot.",
|
|
17
|
+
"`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the invalid local unlock quarantine release."
|
|
18
|
+
]
|
|
19
|
+
},
|
|
4
20
|
{
|
|
5
21
|
"version": "0.1.0-alpha.557",
|
|
6
22
|
"changes": [
|
package/dist/heart/identity.js
CHANGED
|
@@ -218,12 +218,6 @@ let _agentConfigOverride = null;
|
|
|
218
218
|
*/
|
|
219
219
|
function getAgentName() {
|
|
220
220
|
if (_cachedAgentName) {
|
|
221
|
-
(0, runtime_1.emitNervesEvent)({
|
|
222
|
-
event: "identity.resolve",
|
|
223
|
-
component: "config/identity",
|
|
224
|
-
message: "resolved agent name from cache",
|
|
225
|
-
meta: { source: "cache" },
|
|
226
|
-
});
|
|
227
221
|
return _cachedAgentName;
|
|
228
222
|
}
|
|
229
223
|
const idx = process.argv.indexOf("--agent");
|
|
@@ -401,6 +401,8 @@ class BitwardenCredentialStore {
|
|
|
401
401
|
email;
|
|
402
402
|
masterPassword;
|
|
403
403
|
appDataDir;
|
|
404
|
+
onInvalidUnlockSecret;
|
|
405
|
+
onLoginSuccess;
|
|
404
406
|
sessionToken = null;
|
|
405
407
|
terminalLoginError = null;
|
|
406
408
|
bwBinaryPath = "bw";
|
|
@@ -410,6 +412,8 @@ class BitwardenCredentialStore {
|
|
|
410
412
|
this.email = email;
|
|
411
413
|
this.masterPassword = masterPassword;
|
|
412
414
|
this.appDataDir = options.appDataDir;
|
|
415
|
+
this.onInvalidUnlockSecret = options.onInvalidUnlockSecret;
|
|
416
|
+
this.onLoginSuccess = options.onLoginSuccess;
|
|
413
417
|
}
|
|
414
418
|
isReady() {
|
|
415
419
|
return true;
|
|
@@ -420,6 +424,27 @@ class BitwardenCredentialStore {
|
|
|
420
424
|
execBwWithPasswordEnv(args) {
|
|
421
425
|
return execBw([...args, "--passwordenv", BW_PASSWORD_ENV], undefined, this.appDataDir, undefined, this.bwBinaryPath, { [BW_PASSWORD_ENV]: this.masterPassword });
|
|
422
426
|
}
|
|
427
|
+
async notifyInvalidUnlockSecret(error) {
|
|
428
|
+
if (!this.onInvalidUnlockSecret)
|
|
429
|
+
return;
|
|
430
|
+
try {
|
|
431
|
+
await this.onInvalidUnlockSecret(error);
|
|
432
|
+
}
|
|
433
|
+
catch (callbackError) {
|
|
434
|
+
(0, runtime_1.emitNervesEvent)({
|
|
435
|
+
level: "warn",
|
|
436
|
+
event: "repertoire.bw_invalid_unlock_cleanup_failed",
|
|
437
|
+
component: "repertoire",
|
|
438
|
+
message: "failed to clean up rejected local vault unlock material",
|
|
439
|
+
meta: {
|
|
440
|
+
email: this.email,
|
|
441
|
+
serverUrl: this.serverUrl,
|
|
442
|
+
error: callbackError instanceof Error ? callbackError.message : String(callbackError),
|
|
443
|
+
originalError: error.message,
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
423
448
|
/**
|
|
424
449
|
* Ensure the bw CLI is authenticated and unlocked.
|
|
425
450
|
* Handles three states: logged out → login, locked → unlock, already unlocked → no-op.
|
|
@@ -438,6 +463,7 @@ class BitwardenCredentialStore {
|
|
|
438
463
|
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
439
464
|
try {
|
|
440
465
|
await this.loginAttempt();
|
|
466
|
+
await this.onLoginSuccess?.();
|
|
441
467
|
return;
|
|
442
468
|
}
|
|
443
469
|
catch (err) {
|
|
@@ -446,6 +472,9 @@ class BitwardenCredentialStore {
|
|
|
446
472
|
// Don't retry non-transient errors (auth failures, bw not installed)
|
|
447
473
|
if (!isTransientError(lastError)) {
|
|
448
474
|
this.terminalLoginError = lastError;
|
|
475
|
+
if (isBwInvalidUnlockSecretMessage(lastError.message)) {
|
|
476
|
+
await this.notifyInvalidUnlockSecret(lastError);
|
|
477
|
+
}
|
|
449
478
|
throw lastError;
|
|
450
479
|
}
|
|
451
480
|
// Don't retry after final attempt
|
|
@@ -462,6 +491,10 @@ class BitwardenCredentialStore {
|
|
|
462
491
|
}
|
|
463
492
|
}
|
|
464
493
|
this.terminalLoginError = lastError;
|
|
494
|
+
/* v8 ignore next -- invalid unlock errors are non-transient and exit through the non-retry path above @preserve */
|
|
495
|
+
if (isBwInvalidUnlockSecretMessage(lastError.message)) {
|
|
496
|
+
await this.notifyInvalidUnlockSecret(lastError);
|
|
497
|
+
}
|
|
465
498
|
throw lastError;
|
|
466
499
|
}
|
|
467
500
|
/** Single login attempt — called by login() retry loop. */
|
|
@@ -92,7 +92,63 @@ function getCredentialStore(agentNameInput) {
|
|
|
92
92
|
email: vaultConfig.email,
|
|
93
93
|
serverUrl: vaultConfig.serverUrl,
|
|
94
94
|
});
|
|
95
|
-
const
|
|
95
|
+
const unlockConfig = { agentName, email: vaultConfig.email, serverUrl: vaultConfig.serverUrl };
|
|
96
|
+
const unlockSource = unlock.source ?? unlockConfig;
|
|
97
|
+
let invalidUnlockCleared = false;
|
|
98
|
+
let canonicalUnlockStored = false;
|
|
99
|
+
const store = new bitwarden_store_1.BitwardenCredentialStore(vaultConfig.serverUrl, vaultConfig.email, unlock.secret, {
|
|
100
|
+
appDataDir: bitwardenAppDataDir(agentName, vaultConfig),
|
|
101
|
+
onInvalidUnlockSecret: (error) => {
|
|
102
|
+
if (invalidUnlockCleared)
|
|
103
|
+
return;
|
|
104
|
+
invalidUnlockCleared = true;
|
|
105
|
+
(0, vault_unlock_1.clearVaultUnlockSecret)({
|
|
106
|
+
agentName,
|
|
107
|
+
email: unlockSource.email,
|
|
108
|
+
serverUrl: unlockSource.serverUrl,
|
|
109
|
+
});
|
|
110
|
+
stores.delete(cacheKey);
|
|
111
|
+
(0, runtime_1.emitNervesEvent)({
|
|
112
|
+
level: "warn",
|
|
113
|
+
event: "repertoire.credential_store_invalid_unlock_cleared",
|
|
114
|
+
component: "repertoire",
|
|
115
|
+
message: "cleared rejected local vault unlock material",
|
|
116
|
+
meta: {
|
|
117
|
+
agentName,
|
|
118
|
+
serverUrl: vaultConfig.serverUrl,
|
|
119
|
+
email: vaultConfig.email,
|
|
120
|
+
sourceServerUrl: unlockSource.serverUrl,
|
|
121
|
+
error: error.message,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
onLoginSuccess: () => {
|
|
126
|
+
if (canonicalUnlockStored)
|
|
127
|
+
return;
|
|
128
|
+
if (unlockSource.serverUrl === vaultConfig.serverUrl && unlockSource.email === vaultConfig.email)
|
|
129
|
+
return;
|
|
130
|
+
canonicalUnlockStored = true;
|
|
131
|
+
try {
|
|
132
|
+
(0, vault_unlock_1.storeVaultUnlockSecret)(unlockConfig, unlock.secret);
|
|
133
|
+
(0, vault_unlock_1.noteVaultUnlockSelfHeal)(unlockConfig, unlock.store.kind, unlockSource.serverUrl);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
(0, runtime_1.emitNervesEvent)({
|
|
137
|
+
level: "warn",
|
|
138
|
+
event: "repertoire.vault_unlock_self_heal_failed",
|
|
139
|
+
component: "repertoire",
|
|
140
|
+
message: "failed to rewrite local unlock material using canonical vault coordinates",
|
|
141
|
+
meta: {
|
|
142
|
+
store: unlock.store.kind,
|
|
143
|
+
email: vaultConfig.email,
|
|
144
|
+
sourceServerUrl: unlockSource.serverUrl,
|
|
145
|
+
targetServerUrl: vaultConfig.serverUrl,
|
|
146
|
+
error: error instanceof Error ? error.message : String(error),
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
});
|
|
96
152
|
stores.set(cacheKey, store);
|
|
97
153
|
(0, runtime_1.emitNervesEvent)({
|
|
98
154
|
event: "repertoire.credential_store_init",
|
|
@@ -39,6 +39,8 @@ exports.isCredentialVaultNotConfiguredError = isCredentialVaultNotConfiguredErro
|
|
|
39
39
|
exports.vaultCreateRecoverFix = vaultCreateRecoverFix;
|
|
40
40
|
exports.promptConfirmedVaultUnlockSecret = promptConfirmedVaultUnlockSecret;
|
|
41
41
|
exports.resolveVaultUnlockStore = resolveVaultUnlockStore;
|
|
42
|
+
exports.noteVaultUnlockSelfHeal = noteVaultUnlockSelfHeal;
|
|
43
|
+
exports.clearVaultUnlockSecret = clearVaultUnlockSecret;
|
|
42
44
|
exports.readVaultUnlockSecret = readVaultUnlockSecret;
|
|
43
45
|
exports.storeVaultUnlockSecret = storeVaultUnlockSecret;
|
|
44
46
|
exports.getVaultUnlockStatus = getVaultUnlockStatus;
|
|
@@ -82,6 +84,12 @@ function vaultConfigCandidates(config) {
|
|
|
82
84
|
serverUrl,
|
|
83
85
|
}));
|
|
84
86
|
}
|
|
87
|
+
function exactVaultConfig(config) {
|
|
88
|
+
return {
|
|
89
|
+
...config,
|
|
90
|
+
serverUrl: config.serverUrl.trim().replace(/\/+$/, ""),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
85
93
|
function plaintextUnlockPath(config, deps) {
|
|
86
94
|
const digest = crypto.createHash("sha256").update(vaultKey(config)).digest("hex").slice(0, 24);
|
|
87
95
|
return path.join(homeDir(deps), PLAINTEXT_UNLOCK_DIR, `${digest}.secret`);
|
|
@@ -265,37 +273,13 @@ function noteVaultUnlockSelfHeal(config, storeKind, sourceServerUrl) {
|
|
|
265
273
|
},
|
|
266
274
|
});
|
|
267
275
|
}
|
|
268
|
-
function warnVaultUnlockSelfHealFailure(config, storeKind, sourceServerUrl, error) {
|
|
269
|
-
(0, runtime_1.emitNervesEvent)({
|
|
270
|
-
level: "warn",
|
|
271
|
-
component: "repertoire",
|
|
272
|
-
event: "repertoire.vault_unlock_self_heal_failed",
|
|
273
|
-
message: "failed to rewrite local unlock material using canonical vault coordinates",
|
|
274
|
-
meta: {
|
|
275
|
-
store: storeKind,
|
|
276
|
-
email: config.email,
|
|
277
|
-
sourceServerUrl,
|
|
278
|
-
targetServerUrl: config.serverUrl,
|
|
279
|
-
error: error instanceof Error ? error.message : String(error),
|
|
280
|
-
},
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
276
|
function readFromMacosKeychain(config, deps) {
|
|
284
277
|
const candidates = vaultConfigCandidates(config);
|
|
285
|
-
for (const
|
|
278
|
+
for (const candidate of candidates) {
|
|
286
279
|
const secret = readFromMacosKeychainExact(vaultKey(candidate), deps);
|
|
287
|
-
if (
|
|
288
|
-
|
|
289
|
-
if (index > 0) {
|
|
290
|
-
try {
|
|
291
|
-
writeToMacosKeychain(config, secret, deps);
|
|
292
|
-
noteVaultUnlockSelfHeal(config, "macos-keychain", candidate.serverUrl);
|
|
293
|
-
}
|
|
294
|
-
catch (error) {
|
|
295
|
-
warnVaultUnlockSelfHealFailure(config, "macos-keychain", candidate.serverUrl, error);
|
|
296
|
-
}
|
|
280
|
+
if (secret) {
|
|
281
|
+
return { secret, source: exactVaultConfig(candidate) };
|
|
297
282
|
}
|
|
298
|
-
return secret;
|
|
299
283
|
}
|
|
300
284
|
return null;
|
|
301
285
|
}
|
|
@@ -337,20 +321,11 @@ function readFromLinuxSecretServiceExact(accountKey, deps) {
|
|
|
337
321
|
}
|
|
338
322
|
function readFromLinuxSecretService(config, deps) {
|
|
339
323
|
const candidates = vaultConfigCandidates(config);
|
|
340
|
-
for (const
|
|
324
|
+
for (const candidate of candidates) {
|
|
341
325
|
const secret = readFromLinuxSecretServiceExact(vaultKey(candidate), deps);
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
if (index > 0) {
|
|
345
|
-
try {
|
|
346
|
-
writeToLinuxSecretService(config, secret, deps);
|
|
347
|
-
noteVaultUnlockSelfHeal(config, "linux-secret-service", candidate.serverUrl);
|
|
348
|
-
}
|
|
349
|
-
catch (error) {
|
|
350
|
-
warnVaultUnlockSelfHealFailure(config, "linux-secret-service", candidate.serverUrl, error);
|
|
351
|
-
}
|
|
326
|
+
if (secret) {
|
|
327
|
+
return { secret, source: exactVaultConfig(candidate) };
|
|
352
328
|
}
|
|
353
|
-
return secret;
|
|
354
329
|
}
|
|
355
330
|
return null;
|
|
356
331
|
}
|
|
@@ -417,20 +392,11 @@ function readFromWindowsDpapiExact(config, deps) {
|
|
|
417
392
|
}
|
|
418
393
|
function readFromWindowsDpapi(config, deps) {
|
|
419
394
|
const candidates = vaultConfigCandidates(config);
|
|
420
|
-
for (const
|
|
395
|
+
for (const candidate of candidates) {
|
|
421
396
|
const secret = readFromWindowsDpapiExact(candidate, deps);
|
|
422
|
-
if (
|
|
423
|
-
|
|
424
|
-
if (index > 0) {
|
|
425
|
-
try {
|
|
426
|
-
writeToWindowsDpapi(config, secret, deps);
|
|
427
|
-
noteVaultUnlockSelfHeal(config, "windows-dpapi", candidate.serverUrl);
|
|
428
|
-
}
|
|
429
|
-
catch (error) {
|
|
430
|
-
warnVaultUnlockSelfHealFailure(config, "windows-dpapi", candidate.serverUrl, error);
|
|
431
|
-
}
|
|
397
|
+
if (secret) {
|
|
398
|
+
return { secret, source: exactVaultConfig(candidate) };
|
|
432
399
|
}
|
|
433
|
-
return secret;
|
|
434
400
|
}
|
|
435
401
|
return null;
|
|
436
402
|
}
|
|
@@ -455,20 +421,11 @@ function readFromPlaintextFileExact(config, deps) {
|
|
|
455
421
|
}
|
|
456
422
|
function readFromPlaintextFile(config, deps) {
|
|
457
423
|
const candidates = vaultConfigCandidates(config);
|
|
458
|
-
for (const
|
|
424
|
+
for (const candidate of candidates) {
|
|
459
425
|
const secret = readFromPlaintextFileExact(candidate, deps);
|
|
460
|
-
if (
|
|
461
|
-
|
|
462
|
-
if (index > 0) {
|
|
463
|
-
try {
|
|
464
|
-
writeToPlaintextFile(config, secret, deps);
|
|
465
|
-
noteVaultUnlockSelfHeal(config, "plaintext-file", candidate.serverUrl);
|
|
466
|
-
}
|
|
467
|
-
catch (error) {
|
|
468
|
-
warnVaultUnlockSelfHealFailure(config, "plaintext-file", candidate.serverUrl, error);
|
|
469
|
-
}
|
|
426
|
+
if (secret) {
|
|
427
|
+
return { secret, source: exactVaultConfig(candidate) };
|
|
470
428
|
}
|
|
471
|
-
return secret;
|
|
472
429
|
}
|
|
473
430
|
return null;
|
|
474
431
|
}
|
|
@@ -505,20 +462,96 @@ function writeToStore(config, store, secret, deps) {
|
|
|
505
462
|
}
|
|
506
463
|
writeToPlaintextFile(config, secret, deps);
|
|
507
464
|
}
|
|
465
|
+
function deleteFromMacosKeychainExact(config, deps) {
|
|
466
|
+
const result = spawnSync(deps)("security", [
|
|
467
|
+
"delete-generic-password",
|
|
468
|
+
"-s",
|
|
469
|
+
VAULT_UNLOCK_SERVICE,
|
|
470
|
+
"-a",
|
|
471
|
+
vaultKey(config),
|
|
472
|
+
], { encoding: "utf8" });
|
|
473
|
+
if (result.status === 0)
|
|
474
|
+
return true;
|
|
475
|
+
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
476
|
+
const error = result.error instanceof Error ? result.error.message : "";
|
|
477
|
+
const detail = stderr || error;
|
|
478
|
+
if (!detail || /could not be found in the keychain/i.test(detail))
|
|
479
|
+
return false;
|
|
480
|
+
throw new Error(`failed to clear vault unlock secret from macOS Keychain: ${detail}`);
|
|
481
|
+
}
|
|
482
|
+
function deleteFromLinuxSecretServiceExact(config, deps) {
|
|
483
|
+
const result = spawnSync(deps)("secret-tool", [
|
|
484
|
+
"clear",
|
|
485
|
+
"service",
|
|
486
|
+
VAULT_UNLOCK_SERVICE,
|
|
487
|
+
"account",
|
|
488
|
+
vaultKey(config),
|
|
489
|
+
], { encoding: "utf8" });
|
|
490
|
+
if (result.status === 0)
|
|
491
|
+
return true;
|
|
492
|
+
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
493
|
+
const error = result.error instanceof Error ? result.error.message : "";
|
|
494
|
+
const detail = stderr || error;
|
|
495
|
+
if (!detail || /not found/i.test(detail))
|
|
496
|
+
return false;
|
|
497
|
+
throw new Error(`failed to clear vault unlock secret from Linux Secret Service: ${detail}`);
|
|
498
|
+
}
|
|
499
|
+
function deleteFromWindowsDpapiExact(config, deps) {
|
|
500
|
+
const filePath = windowsDpapiUnlockPath(config, deps);
|
|
501
|
+
const existed = fs.existsSync(filePath);
|
|
502
|
+
fs.rmSync(filePath, { force: true });
|
|
503
|
+
return existed;
|
|
504
|
+
}
|
|
505
|
+
function deleteFromPlaintextFileExact(config, deps) {
|
|
506
|
+
const filePath = plaintextUnlockPath(config, deps);
|
|
507
|
+
const existed = fs.existsSync(filePath);
|
|
508
|
+
fs.rmSync(filePath, { force: true });
|
|
509
|
+
return existed;
|
|
510
|
+
}
|
|
511
|
+
function deleteFromStoreExact(config, store, deps) {
|
|
512
|
+
if (store.kind === "macos-keychain")
|
|
513
|
+
return deleteFromMacosKeychainExact(config, deps);
|
|
514
|
+
if (store.kind === "linux-secret-service")
|
|
515
|
+
return deleteFromLinuxSecretServiceExact(config, deps);
|
|
516
|
+
if (store.kind === "windows-dpapi")
|
|
517
|
+
return deleteFromWindowsDpapiExact(config, deps);
|
|
518
|
+
return deleteFromPlaintextFileExact(config, deps);
|
|
519
|
+
}
|
|
520
|
+
function clearVaultUnlockSecret(config, deps = {}) {
|
|
521
|
+
const canonicalConfig = canonicalizeVaultUnlockConfig(config);
|
|
522
|
+
const store = resolveVaultUnlockStore(canonicalConfig, deps);
|
|
523
|
+
const deletedAccounts = new Set();
|
|
524
|
+
let deleted = false;
|
|
525
|
+
for (const candidate of vaultConfigCandidates(config)) {
|
|
526
|
+
const exactCandidate = exactVaultConfig(candidate);
|
|
527
|
+
const key = vaultKey(exactCandidate);
|
|
528
|
+
if (deletedAccounts.has(key))
|
|
529
|
+
continue;
|
|
530
|
+
deletedAccounts.add(key);
|
|
531
|
+
deleted = deleteFromStoreExact(exactCandidate, store, deps) || deleted;
|
|
532
|
+
}
|
|
533
|
+
(0, runtime_1.emitNervesEvent)({
|
|
534
|
+
component: "repertoire",
|
|
535
|
+
event: "repertoire.vault_unlock_cleared",
|
|
536
|
+
message: "cleared local vault unlock material",
|
|
537
|
+
meta: { store: store.kind, secure: store.secure, hasAgentName: !!config.agentName, deleted },
|
|
538
|
+
});
|
|
539
|
+
return store;
|
|
540
|
+
}
|
|
508
541
|
function readVaultUnlockSecret(config, deps = {}) {
|
|
509
542
|
const canonicalConfig = canonicalizeVaultUnlockConfig(config);
|
|
510
543
|
const store = resolveVaultUnlockStore(canonicalConfig, deps);
|
|
511
|
-
const
|
|
512
|
-
if (!
|
|
544
|
+
const loaded = readFromStore(canonicalConfig, store, deps);
|
|
545
|
+
if (!loaded) {
|
|
513
546
|
throw new Error(lockedMessage(canonicalConfig, store));
|
|
514
547
|
}
|
|
515
548
|
(0, runtime_1.emitNervesEvent)({
|
|
516
549
|
component: "repertoire",
|
|
517
550
|
event: "repertoire.vault_unlock_loaded",
|
|
518
551
|
message: "loaded vault unlock material from local store",
|
|
519
|
-
meta: { store: store.kind, secure: store.secure, hasAgentName: !!config.agentName },
|
|
552
|
+
meta: { store: store.kind, secure: store.secure, hasAgentName: !!config.agentName, sourceServerUrl: loaded.source.serverUrl },
|
|
520
553
|
});
|
|
521
|
-
return { secret, store };
|
|
554
|
+
return { secret: loaded.secret, store, source: loaded.source };
|
|
522
555
|
}
|
|
523
556
|
function storeVaultUnlockSecret(config, secret, deps = {}) {
|
|
524
557
|
const canonicalConfig = canonicalizeVaultUnlockConfig(config);
|