@kitsy/cnos 1.10.0 → 1.11.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/dist/build/index.cjs +331 -63
- package/dist/build/index.d.cts +1 -1
- package/dist/build/index.d.ts +1 -1
- package/dist/build/index.js +13 -15
- package/dist/{chunk-A5U7EZCJ.js → chunk-2DMCB3PK.js} +1 -1
- package/dist/{chunk-RTHKUGJV.js → chunk-5JGNRADB.js} +1 -1
- package/dist/{chunk-3EZGPQCE.js → chunk-DPC2BV3S.js} +1 -1
- package/dist/{chunk-FHXLOWAB.js → chunk-KJ57PF47.js} +1 -1
- package/dist/{chunk-ESBHCFC6.js → chunk-NU25VFA2.js} +1 -1
- package/dist/{chunk-UGLATJJD.js → chunk-RNTTPI5S.js} +1 -1
- package/dist/{chunk-UKNL2Y4N.js → chunk-T3E57MSQ.js} +1 -1
- package/dist/{chunk-CSA4L64V.js → chunk-V3USPV5U.js} +8 -8
- package/dist/{chunk-MQ4WG3K6.js → chunk-WPB4HB2K.js} +320 -49
- package/dist/{chunk-EIK7OUFP.js → chunk-X4PBPUKL.js} +157 -37
- package/dist/configure/index.cjs +329 -59
- package/dist/configure/index.d.cts +3 -3
- package/dist/configure/index.d.ts +3 -3
- package/dist/configure/index.js +8 -8
- package/dist/{core-Ud1o2MBn.d.cts → core-CGJObpyy.d.cts} +40 -2
- package/dist/{core-Ud1o2MBn.d.ts → core-CGJObpyy.d.ts} +40 -2
- package/dist/{envNaming-DxxqiGKN.d.cts → envNaming-DIaBgT6E.d.cts} +1 -1
- package/dist/{envNaming-CPwXl4I6.d.ts → envNaming-_WD9sLZI.d.ts} +1 -1
- package/dist/index.cjs +480 -91
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -10
- package/dist/internal.cjs +89 -23
- package/dist/internal.d.cts +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.js +2 -2
- package/dist/plugin/basic-schema.cjs +4 -1
- package/dist/plugin/basic-schema.d.cts +1 -1
- package/dist/plugin/basic-schema.d.ts +1 -1
- package/dist/plugin/basic-schema.js +2 -2
- package/dist/plugin/cli-args.cjs +4 -1
- package/dist/plugin/cli-args.d.cts +1 -1
- package/dist/plugin/cli-args.d.ts +1 -1
- package/dist/plugin/cli-args.js +2 -2
- package/dist/plugin/dotenv.cjs +6 -3
- package/dist/plugin/dotenv.d.cts +2 -2
- package/dist/plugin/dotenv.d.ts +2 -2
- package/dist/plugin/dotenv.js +2 -2
- package/dist/plugin/env-export.cjs +5 -2
- package/dist/plugin/env-export.d.cts +2 -2
- package/dist/plugin/env-export.d.ts +2 -2
- package/dist/plugin/env-export.js +2 -2
- package/dist/plugin/filesystem.cjs +13 -10
- package/dist/plugin/filesystem.d.cts +1 -1
- package/dist/plugin/filesystem.d.ts +1 -1
- package/dist/plugin/filesystem.js +2 -2
- package/dist/plugin/process-env.cjs +4 -1
- package/dist/plugin/process-env.d.cts +2 -2
- package/dist/plugin/process-env.d.ts +2 -2
- package/dist/plugin/process-env.js +2 -2
- package/dist/runtime/index.cjs +480 -91
- package/dist/runtime/index.d.cts +13 -6
- package/dist/runtime/index.d.ts +13 -6
- package/dist/runtime/index.js +10 -10
- package/dist/{toPublicEnv-fUZMRUOz.d.cts → toPublicEnv-C3A8aLjo.d.cts} +1 -1
- package/dist/{toPublicEnv-C9wPSpRo.d.ts → toPublicEnv-DLNNcEso.d.ts} +1 -1
- package/package.json +1 -1
package/dist/configure/index.cjs
CHANGED
|
@@ -1603,11 +1603,19 @@ function normalizeVaults(vaults) {
|
|
|
1603
1603
|
throw new CnosManifestError(`Vault "${name}" requires a provider`);
|
|
1604
1604
|
}
|
|
1605
1605
|
const normalizedAuth = normalizeVaultAuth(name, provider, definition.auth);
|
|
1606
|
-
const normalizedMapping =
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1606
|
+
const normalizedMapping = normalizeVaultMapping(definition.mapping);
|
|
1607
|
+
const fallback = (definition.fallback ?? []).map((entry, index) => {
|
|
1608
|
+
const fallbackProvider = entry.provider?.trim();
|
|
1609
|
+
if (!fallbackProvider) {
|
|
1610
|
+
throw new CnosManifestError(`Vault "${name}" fallback ${index + 1} requires a provider`);
|
|
1611
|
+
}
|
|
1612
|
+
const fallbackMapping = normalizeVaultMapping(entry.mapping);
|
|
1613
|
+
return {
|
|
1614
|
+
provider: fallbackProvider,
|
|
1615
|
+
auth: normalizeVaultAuth(name, fallbackProvider, entry.auth),
|
|
1616
|
+
...Object.keys(fallbackMapping).length > 0 ? { mapping: fallbackMapping } : {}
|
|
1617
|
+
};
|
|
1618
|
+
});
|
|
1611
1619
|
return [
|
|
1612
1620
|
name,
|
|
1613
1621
|
{
|
|
@@ -1615,12 +1623,20 @@ function normalizeVaults(vaults) {
|
|
|
1615
1623
|
auth: normalizedAuth,
|
|
1616
1624
|
...Object.keys(normalizedMapping).length > 0 ? {
|
|
1617
1625
|
mapping: normalizedMapping
|
|
1618
|
-
} : {}
|
|
1626
|
+
} : {},
|
|
1627
|
+
...fallback.length > 0 ? { fallback } : {}
|
|
1619
1628
|
}
|
|
1620
1629
|
];
|
|
1621
1630
|
})
|
|
1622
1631
|
);
|
|
1623
1632
|
}
|
|
1633
|
+
function normalizeVaultMapping(mapping) {
|
|
1634
|
+
return Object.fromEntries(
|
|
1635
|
+
Object.entries(mapping ?? {}).filter(
|
|
1636
|
+
(entry) => typeof entry[0] === "string" && typeof entry[1] === "string"
|
|
1637
|
+
).map(([envVar, logicalRef]) => [envVar.trim(), logicalRef.trim()]).filter(([envVar, logicalRef]) => envVar.length > 0 && logicalRef.length > 0)
|
|
1638
|
+
);
|
|
1639
|
+
}
|
|
1624
1640
|
function normalizeAuthSources(value) {
|
|
1625
1641
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1626
1642
|
return void 0;
|
|
@@ -2568,7 +2584,7 @@ function isObject(value) {
|
|
|
2568
2584
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2569
2585
|
}
|
|
2570
2586
|
function isSecretReference(value) {
|
|
2571
|
-
return isObject(value) && typeof value.provider === "string" && value.provider.trim().length > 0 && typeof value.ref === "string" && value.ref.trim().length > 0 && (value.vault === void 0 && true || typeof value.vault === "string" && value.vault.trim().length > 0) && Object.keys(value).every((key) => ["provider", "ref", "vault"].includes(key));
|
|
2587
|
+
return isObject(value) && (value.provider === void 0 || typeof value.provider === "string" && value.provider.trim().length > 0) && typeof value.ref === "string" && value.ref.trim().length > 0 && (value.vault === void 0 && true || typeof value.vault === "string" && value.vault.trim().length > 0) && Object.keys(value).every((key) => ["provider", "ref", "vault"].includes(key));
|
|
2572
2588
|
}
|
|
2573
2589
|
function resolveSecretStoreRoot(processEnv = process.env) {
|
|
2574
2590
|
return import_node_path11.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
|
|
@@ -2915,6 +2931,23 @@ var SecretCache = class {
|
|
|
2915
2931
|
get(vaultId, ref) {
|
|
2916
2932
|
return this.cache.get(`${vaultId}:${ref}`);
|
|
2917
2933
|
}
|
|
2934
|
+
delete(vaultId, ref) {
|
|
2935
|
+
this.cache.delete(`${vaultId}:${ref}`);
|
|
2936
|
+
}
|
|
2937
|
+
replace(vaultId, secrets) {
|
|
2938
|
+
this.clear(vaultId);
|
|
2939
|
+
this.load(vaultId, secrets);
|
|
2940
|
+
}
|
|
2941
|
+
entriesForVault(vaultId) {
|
|
2942
|
+
const entries = /* @__PURE__ */ new Map();
|
|
2943
|
+
for (const [key, value] of this.cache) {
|
|
2944
|
+
const prefix = `${vaultId}:`;
|
|
2945
|
+
if (key.startsWith(prefix)) {
|
|
2946
|
+
entries.set(key.slice(prefix.length), value);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
return entries;
|
|
2950
|
+
}
|
|
2918
2951
|
clear(vaultId) {
|
|
2919
2952
|
if (!vaultId) {
|
|
2920
2953
|
this.cache.clear();
|
|
@@ -3080,7 +3113,7 @@ var LocalSecretVaultProvider = class _LocalSecretVaultProvider {
|
|
|
3080
3113
|
};
|
|
3081
3114
|
|
|
3082
3115
|
// ../core/src/secrets/providers/registry.ts
|
|
3083
|
-
function createSecretVaultProvider(vaultId, definition, processEnv) {
|
|
3116
|
+
function createSecretVaultProvider(vaultId, definition, processEnv, factories = []) {
|
|
3084
3117
|
if (definition.provider === "local") {
|
|
3085
3118
|
return new LocalSecretVaultProvider(vaultId, definition, processEnv);
|
|
3086
3119
|
}
|
|
@@ -3090,9 +3123,30 @@ function createSecretVaultProvider(vaultId, definition, processEnv) {
|
|
|
3090
3123
|
if (definition.provider === "github-secrets") {
|
|
3091
3124
|
return new GithubSecretsVaultProvider(vaultId, definition, processEnv);
|
|
3092
3125
|
}
|
|
3126
|
+
const factory = factories.find((candidate) => candidate.provider === definition.provider);
|
|
3127
|
+
if (factory) {
|
|
3128
|
+
return factory.create(vaultId, definition, processEnv);
|
|
3129
|
+
}
|
|
3093
3130
|
throw new CnosManifestError(`Unsupported vault provider: ${definition.provider}`);
|
|
3094
3131
|
}
|
|
3095
3132
|
|
|
3133
|
+
// ../core/src/secrets/providerCompatibility.ts
|
|
3134
|
+
function assertSecretRefVaultProviderCompatible(manifest, ref, logicalKey = "secret ref") {
|
|
3135
|
+
if (!ref.vault || !ref.provider) {
|
|
3136
|
+
return;
|
|
3137
|
+
}
|
|
3138
|
+
const definition = manifest.vaults[ref.vault];
|
|
3139
|
+
if (!definition || definition.provider === ref.provider) {
|
|
3140
|
+
return;
|
|
3141
|
+
}
|
|
3142
|
+
throw new CnosManifestError(
|
|
3143
|
+
`Secret ref "${logicalKey}" declares provider "${ref.provider}" but vault "${ref.vault}" uses provider "${definition.provider}". Remove the ref provider or use a matching vault.`
|
|
3144
|
+
);
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
// ../core/src/secrets/resolveAuth.ts
|
|
3148
|
+
var import_promises12 = require("fs/promises");
|
|
3149
|
+
|
|
3096
3150
|
// ../core/src/secrets/prompt.ts
|
|
3097
3151
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
3098
3152
|
var import_node_stream = require("stream");
|
|
@@ -3133,6 +3187,23 @@ function toAuthError(vaultId, sources) {
|
|
|
3133
3187
|
`Cannot authenticate to vault "${vaultId}". Tried: ${sources.join(", ")}. Set ${getVaultPassphraseEnvVar(vaultId)} or run cnos vault auth ${vaultId}.`
|
|
3134
3188
|
);
|
|
3135
3189
|
}
|
|
3190
|
+
async function resolveTokenFromSource(source, processEnv) {
|
|
3191
|
+
if (source.startsWith("env:")) {
|
|
3192
|
+
return processEnv[source.slice(4)] || void 0;
|
|
3193
|
+
}
|
|
3194
|
+
if (source.startsWith("file:")) {
|
|
3195
|
+
try {
|
|
3196
|
+
const value = await (0, import_promises12.readFile)(expandHomePath(source.slice("file:".length)), "utf8");
|
|
3197
|
+
return value.trim() || void 0;
|
|
3198
|
+
} catch {
|
|
3199
|
+
return void 0;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
if (source.startsWith("keychain:")) {
|
|
3203
|
+
return readKeychain(source.slice("keychain:".length));
|
|
3204
|
+
}
|
|
3205
|
+
return void 0;
|
|
3206
|
+
}
|
|
3136
3207
|
async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
3137
3208
|
const sessionKey = await resolveVaultSessionKey(vaultId, processEnv);
|
|
3138
3209
|
if (sessionKey) {
|
|
@@ -3148,6 +3219,32 @@ async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
|
3148
3219
|
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3149
3220
|
};
|
|
3150
3221
|
}
|
|
3222
|
+
if (definition.auth?.method === "iam") {
|
|
3223
|
+
return {
|
|
3224
|
+
method: "iam",
|
|
3225
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3226
|
+
};
|
|
3227
|
+
}
|
|
3228
|
+
if (definition.auth?.method === "environment") {
|
|
3229
|
+
return {
|
|
3230
|
+
method: "environment",
|
|
3231
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3232
|
+
};
|
|
3233
|
+
}
|
|
3234
|
+
const tokenSources = definition.auth?.token?.from ?? [];
|
|
3235
|
+
for (const source of tokenSources) {
|
|
3236
|
+
const token = await resolveTokenFromSource(source, processEnv);
|
|
3237
|
+
if (token) {
|
|
3238
|
+
return {
|
|
3239
|
+
token,
|
|
3240
|
+
method: "token",
|
|
3241
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3242
|
+
};
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
if (definition.auth?.method === "token") {
|
|
3246
|
+
throw toAuthError(vaultId, [getVaultSessionKeyEnvVar(vaultId), ...tokenSources]);
|
|
3247
|
+
}
|
|
3151
3248
|
const sources = definition.auth?.passphrase?.from ?? [getVaultPassphraseEnvVar(vaultId)];
|
|
3152
3249
|
for (const source of sources) {
|
|
3153
3250
|
if (source.startsWith("env:")) {
|
|
@@ -3199,22 +3296,76 @@ function collectSecretDescriptors(graph) {
|
|
|
3199
3296
|
ref: entry.value
|
|
3200
3297
|
}));
|
|
3201
3298
|
}
|
|
3202
|
-
|
|
3299
|
+
function secretGroupKey(manifest, descriptor) {
|
|
3300
|
+
assertSecretRefVaultProviderCompatible(manifest, descriptor.ref, descriptor.logicalKey);
|
|
3301
|
+
const vaultId = descriptor.ref.vault ?? "default";
|
|
3302
|
+
const provider = descriptor.ref.provider ?? manifest.vaults[vaultId]?.provider ?? "local";
|
|
3303
|
+
return `${vaultId}\0${provider}`;
|
|
3304
|
+
}
|
|
3305
|
+
function vaultDefinitionForRef(manifest, ref) {
|
|
3306
|
+
assertSecretRefVaultProviderCompatible(manifest, ref);
|
|
3307
|
+
const vaultId = ref.vault ?? "default";
|
|
3308
|
+
const base = manifest.vaults[vaultId] ?? { provider: "local", auth: { passphrase: { from: [] } } };
|
|
3309
|
+
if (!ref.provider || ref.provider === base.provider) {
|
|
3310
|
+
return base;
|
|
3311
|
+
}
|
|
3312
|
+
return {
|
|
3313
|
+
...base,
|
|
3314
|
+
provider: ref.provider
|
|
3315
|
+
};
|
|
3316
|
+
}
|
|
3317
|
+
async function resolveFromDefinition(vaultId, definition, refs, processEnv, factories) {
|
|
3318
|
+
const runtimeDefinition = {
|
|
3319
|
+
provider: definition.provider,
|
|
3320
|
+
...definition.auth ? { auth: definition.auth } : {},
|
|
3321
|
+
...definition.mapping ? { mapping: definition.mapping } : {}
|
|
3322
|
+
};
|
|
3323
|
+
const provider = createSecretVaultProvider(vaultId, runtimeDefinition, processEnv, factories);
|
|
3324
|
+
const auth = await resolveVaultAuth(vaultId, runtimeDefinition, processEnv);
|
|
3325
|
+
await provider.authenticate(auth);
|
|
3326
|
+
return provider.batchGet(refs.map((entry) => entry.ref.ref));
|
|
3327
|
+
}
|
|
3328
|
+
async function batchResolveSecrets(graph, manifest, processEnv = process.env, factories = []) {
|
|
3203
3329
|
const cache = new SecretCache();
|
|
3204
3330
|
const descriptors = collectSecretDescriptors(graph);
|
|
3205
3331
|
const grouped = descriptors.reduce((accumulator, descriptor) => {
|
|
3206
|
-
const
|
|
3207
|
-
const bucket = accumulator.get(
|
|
3332
|
+
const key = secretGroupKey(manifest, descriptor);
|
|
3333
|
+
const bucket = accumulator.get(key) ?? [];
|
|
3208
3334
|
bucket.push(descriptor);
|
|
3209
|
-
accumulator.set(
|
|
3335
|
+
accumulator.set(key, bucket);
|
|
3210
3336
|
return accumulator;
|
|
3211
3337
|
}, /* @__PURE__ */ new Map());
|
|
3212
|
-
for (const
|
|
3213
|
-
const
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
const
|
|
3338
|
+
for (const refs of grouped.values()) {
|
|
3339
|
+
const first = refs[0];
|
|
3340
|
+
if (!first) {
|
|
3341
|
+
continue;
|
|
3342
|
+
}
|
|
3343
|
+
const vaultId = first.ref.vault ?? "default";
|
|
3344
|
+
const definition = vaultDefinitionForRef(manifest, first.ref);
|
|
3345
|
+
const definitions = [definition, ...definition.fallback ?? []];
|
|
3346
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
3347
|
+
let remaining = refs;
|
|
3348
|
+
let lastError;
|
|
3349
|
+
for (const candidate of definitions) {
|
|
3350
|
+
try {
|
|
3351
|
+
const candidateValues = await resolveFromDefinition(vaultId, candidate, remaining, processEnv, factories);
|
|
3352
|
+
for (const descriptor of remaining) {
|
|
3353
|
+
const value = candidateValues.get(descriptor.ref.ref);
|
|
3354
|
+
if (value !== void 0) {
|
|
3355
|
+
resolved.set(descriptor.ref.ref, value);
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
remaining = remaining.filter((descriptor) => !resolved.has(descriptor.ref.ref));
|
|
3359
|
+
if (remaining.length === 0) {
|
|
3360
|
+
break;
|
|
3361
|
+
}
|
|
3362
|
+
} catch (error) {
|
|
3363
|
+
lastError = error;
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
if (resolved.size === 0 && lastError) {
|
|
3367
|
+
throw lastError;
|
|
3368
|
+
}
|
|
3218
3369
|
cache.load(vaultId, resolved);
|
|
3219
3370
|
await appendAuditEvent(
|
|
3220
3371
|
{
|
|
@@ -3235,7 +3386,11 @@ function resolveSecretEntryValue(key, value, cache) {
|
|
|
3235
3386
|
return value;
|
|
3236
3387
|
}
|
|
3237
3388
|
const vaultId = value.vault ?? "default";
|
|
3238
|
-
|
|
3389
|
+
const resolved = cache.get(vaultId, value.ref);
|
|
3390
|
+
if (resolved !== void 0 || cache.isVaultAuthenticated(vaultId)) {
|
|
3391
|
+
return resolved;
|
|
3392
|
+
}
|
|
3393
|
+
return value;
|
|
3239
3394
|
}
|
|
3240
3395
|
|
|
3241
3396
|
// ../core/src/runtime/projection.ts
|
|
@@ -3338,19 +3493,117 @@ function configHash(values) {
|
|
|
3338
3493
|
function shouldProjectResolvedValue(sourceId) {
|
|
3339
3494
|
return sourceId !== "process-env";
|
|
3340
3495
|
}
|
|
3496
|
+
var SAFE_PROJECTED_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
3497
|
+
"address",
|
|
3498
|
+
"audience",
|
|
3499
|
+
"clientid",
|
|
3500
|
+
"endpoint",
|
|
3501
|
+
"mount",
|
|
3502
|
+
"namespace",
|
|
3503
|
+
"path",
|
|
3504
|
+
"projectid",
|
|
3505
|
+
"region",
|
|
3506
|
+
"scope",
|
|
3507
|
+
"scopes",
|
|
3508
|
+
"serviceaccountemail",
|
|
3509
|
+
"tenant",
|
|
3510
|
+
"tenantid",
|
|
3511
|
+
"url",
|
|
3512
|
+
"version",
|
|
3513
|
+
"vaulturl"
|
|
3514
|
+
]);
|
|
3515
|
+
function isSafeProjectedConfigKey(key) {
|
|
3516
|
+
return SAFE_PROJECTED_CONFIG_KEYS.has(key.replace(/[^A-Za-z0-9]/g, "").toLowerCase());
|
|
3517
|
+
}
|
|
3518
|
+
function sanitizeProjectedConfigValue(value) {
|
|
3519
|
+
if (Array.isArray(value)) {
|
|
3520
|
+
return value.map((item) => sanitizeProjectedConfigValue(item));
|
|
3521
|
+
}
|
|
3522
|
+
if (!value || typeof value !== "object") {
|
|
3523
|
+
return value;
|
|
3524
|
+
}
|
|
3525
|
+
return stableSortObject(
|
|
3526
|
+
Object.fromEntries(
|
|
3527
|
+
Object.entries(value).map(([key, item]) => [key, sanitizeProjectedConfigValue(item)]).filter(([key, item]) => {
|
|
3528
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
3529
|
+
return Object.keys(item).length > 0;
|
|
3530
|
+
}
|
|
3531
|
+
return isSafeProjectedConfigKey(key);
|
|
3532
|
+
})
|
|
3533
|
+
)
|
|
3534
|
+
);
|
|
3535
|
+
}
|
|
3536
|
+
function sanitizeProjectedConfig(config) {
|
|
3537
|
+
const sanitized = sanitizeProjectedConfigValue(config);
|
|
3538
|
+
if (!sanitized || typeof sanitized !== "object" || Array.isArray(sanitized)) {
|
|
3539
|
+
return void 0;
|
|
3540
|
+
}
|
|
3541
|
+
return Object.keys(sanitized).length > 0 ? sanitized : void 0;
|
|
3542
|
+
}
|
|
3543
|
+
function projectVaultAuth(definition) {
|
|
3544
|
+
const auth = definition.auth;
|
|
3545
|
+
if (!auth) {
|
|
3546
|
+
return void 0;
|
|
3547
|
+
}
|
|
3548
|
+
const config = auth.config ? sanitizeProjectedConfig(auth.config) : void 0;
|
|
3549
|
+
const projected = {
|
|
3550
|
+
...auth.method ? { method: auth.method } : {},
|
|
3551
|
+
...auth.passphrase?.from ? {
|
|
3552
|
+
passphrase: {
|
|
3553
|
+
from: [...auth.passphrase.from]
|
|
3554
|
+
}
|
|
3555
|
+
} : {},
|
|
3556
|
+
...auth.token?.from ? {
|
|
3557
|
+
token: {
|
|
3558
|
+
from: [...auth.token.from]
|
|
3559
|
+
}
|
|
3560
|
+
} : {},
|
|
3561
|
+
...config ? { config } : {}
|
|
3562
|
+
};
|
|
3563
|
+
return Object.keys(projected).length > 0 ? projected : void 0;
|
|
3564
|
+
}
|
|
3565
|
+
function projectVaultDefinition(definition) {
|
|
3566
|
+
const auth = projectVaultAuth(definition);
|
|
3567
|
+
const mapping = definition.mapping ? stableSortObject(definition.mapping) : void 0;
|
|
3568
|
+
const fallback = definition.fallback?.map((entry) => projectVaultDefinition({
|
|
3569
|
+
provider: entry.provider,
|
|
3570
|
+
...entry.auth ? { auth: entry.auth } : {},
|
|
3571
|
+
...entry.mapping ? { mapping: entry.mapping } : {}
|
|
3572
|
+
}));
|
|
3573
|
+
return {
|
|
3574
|
+
provider: definition.provider,
|
|
3575
|
+
...auth ? { auth } : {},
|
|
3576
|
+
...mapping && Object.keys(mapping).length > 0 ? { mapping } : {},
|
|
3577
|
+
...fallback && fallback.length > 0 ? { fallback } : {}
|
|
3578
|
+
};
|
|
3579
|
+
}
|
|
3580
|
+
function projectReferencedVaults(manifest, vaultIds) {
|
|
3581
|
+
const projected = {};
|
|
3582
|
+
for (const vaultId of Array.from(vaultIds).sort((left, right) => left.localeCompare(right))) {
|
|
3583
|
+
const definition = manifest.vaults[vaultId];
|
|
3584
|
+
if (definition) {
|
|
3585
|
+
projected[vaultId] = projectVaultDefinition(definition);
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
return Object.keys(projected).length > 0 ? projected : void 0;
|
|
3589
|
+
}
|
|
3341
3590
|
function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers = {}) {
|
|
3342
3591
|
const values = {};
|
|
3343
3592
|
const derived = {};
|
|
3344
3593
|
const secretRefs = {};
|
|
3594
|
+
const referencedVaultIds = /* @__PURE__ */ new Set();
|
|
3345
3595
|
const namespaces = /* @__PURE__ */ new Set();
|
|
3346
3596
|
const runtimeNamespaces = /* @__PURE__ */ new Set();
|
|
3347
3597
|
const publicKeys = Array.from(graph.entries.values()).filter((entry) => entry.namespace === "public").map((entry) => entry.key.slice("public.".length)).sort((left, right) => left.localeCompare(right));
|
|
3348
3598
|
for (const [key, entry] of graph.entries) {
|
|
3349
3599
|
if (entry.namespace === "secret" && isSecretReference(entry.value)) {
|
|
3600
|
+
assertSecretRefVaultProviderCompatible(manifest, entry.value, key);
|
|
3350
3601
|
const vaultId = entry.value.vault ?? "default";
|
|
3602
|
+
const provider = entry.value.provider ?? manifest.vaults[vaultId]?.provider ?? "local";
|
|
3351
3603
|
const envVar = resolveProjectedEnvVar(manifest, vaultId, entry.value.ref);
|
|
3604
|
+
referencedVaultIds.add(vaultId);
|
|
3352
3605
|
secretRefs[key.slice("secret.".length)] = {
|
|
3353
|
-
provider
|
|
3606
|
+
provider,
|
|
3354
3607
|
vault: vaultId,
|
|
3355
3608
|
ref: entry.value.ref,
|
|
3356
3609
|
...envVar ? {
|
|
@@ -3396,6 +3649,7 @@ function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers
|
|
|
3396
3649
|
namespaces.add(entry.namespace);
|
|
3397
3650
|
}
|
|
3398
3651
|
}
|
|
3652
|
+
const vaults = projectReferencedVaults(manifest, referencedVaultIds);
|
|
3399
3653
|
return {
|
|
3400
3654
|
version: 1,
|
|
3401
3655
|
workspace: graph.workspace.workspaceId,
|
|
@@ -3405,6 +3659,7 @@ function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers
|
|
|
3405
3659
|
values: stableSortObject(values),
|
|
3406
3660
|
derived: stableSortObject(derived),
|
|
3407
3661
|
secretRefs: stableSortObject(secretRefs),
|
|
3662
|
+
...vaults ? { vaults } : {},
|
|
3408
3663
|
publicKeys,
|
|
3409
3664
|
runtimeNamespaces: Array.from(runtimeNamespaces).sort((left, right) => left.localeCompare(right)),
|
|
3410
3665
|
meta: {
|
|
@@ -3519,9 +3774,10 @@ function toPublicEnv(graph, manifest, options = {}, helpers = {}) {
|
|
|
3519
3774
|
}
|
|
3520
3775
|
|
|
3521
3776
|
// ../core/src/orchestrator/runtime.ts
|
|
3522
|
-
function createRuntime(manifest, graph, plugins = [], secretCache, processEnv = process.env, cnosVersion = "0.0.0-dev") {
|
|
3777
|
+
function createRuntime(manifest, graph, plugins = [], secretCache, processEnv = process.env, cnosVersion = "0.0.0-dev", secretVaultProviders = []) {
|
|
3523
3778
|
const runtimeProviders = createDefaultRuntimeProviders(manifest, processEnv);
|
|
3524
3779
|
const derivedSupport = createDerivedRuntimeSupport(graph, manifest, runtimeProviders);
|
|
3780
|
+
let activeSecretCache = secretCache;
|
|
3525
3781
|
function resolveProjectedSourceKey(key) {
|
|
3526
3782
|
if (!key.startsWith("public.")) {
|
|
3527
3783
|
return key;
|
|
@@ -3538,30 +3794,38 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3538
3794
|
if (!entry || entry.namespace !== "secret" || !isSecretReference(entry.value)) {
|
|
3539
3795
|
return;
|
|
3540
3796
|
}
|
|
3541
|
-
if (!
|
|
3797
|
+
if (!activeSecretCache) {
|
|
3542
3798
|
return;
|
|
3543
3799
|
}
|
|
3544
3800
|
const vaultId = entry.value.vault ?? "default";
|
|
3545
|
-
const
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3801
|
+
const refreshed = await batchResolveSecrets(
|
|
3802
|
+
{
|
|
3803
|
+
...graph,
|
|
3804
|
+
entries: /* @__PURE__ */ new Map([[key, entry]])
|
|
3805
|
+
},
|
|
3806
|
+
manifest,
|
|
3807
|
+
processEnv,
|
|
3808
|
+
secretVaultProviders
|
|
3809
|
+
);
|
|
3810
|
+
const resolved = refreshed.get(vaultId, entry.value.ref);
|
|
3811
|
+
const existing = activeSecretCache.entriesForVault(vaultId);
|
|
3812
|
+
existing.delete(entry.value.ref);
|
|
3813
|
+
if (resolved !== void 0) {
|
|
3814
|
+
existing.set(entry.value.ref, resolved);
|
|
3555
3815
|
}
|
|
3816
|
+
activeSecretCache.replace(vaultId, existing);
|
|
3556
3817
|
}
|
|
3557
3818
|
async function refreshAllSecrets() {
|
|
3558
|
-
if (!
|
|
3819
|
+
if (!activeSecretCache) {
|
|
3559
3820
|
return;
|
|
3560
3821
|
}
|
|
3561
|
-
const
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3822
|
+
const refreshed = await batchResolveSecrets(
|
|
3823
|
+
graph,
|
|
3824
|
+
manifest,
|
|
3825
|
+
processEnv,
|
|
3826
|
+
secretVaultProviders
|
|
3827
|
+
);
|
|
3828
|
+
activeSecretCache = refreshed;
|
|
3565
3829
|
}
|
|
3566
3830
|
function readLogicalKey(key) {
|
|
3567
3831
|
const resolved = derivedSupport.read(key, (ref) => {
|
|
@@ -3569,10 +3833,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3569
3833
|
if (!entry2) {
|
|
3570
3834
|
return void 0;
|
|
3571
3835
|
}
|
|
3572
|
-
if (!
|
|
3836
|
+
if (!activeSecretCache) {
|
|
3573
3837
|
return entry2.value;
|
|
3574
3838
|
}
|
|
3575
|
-
return resolveSecretEntryValue(ref, entry2.value,
|
|
3839
|
+
return resolveSecretEntryValue(ref, entry2.value, activeSecretCache);
|
|
3576
3840
|
});
|
|
3577
3841
|
if (resolved !== void 0 || graph.entries.has(key) || manifest.runtimeNamespaces[key.split(".")[0] ?? ""]) {
|
|
3578
3842
|
return resolved;
|
|
@@ -3581,10 +3845,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3581
3845
|
if (!entry) {
|
|
3582
3846
|
return void 0;
|
|
3583
3847
|
}
|
|
3584
|
-
if (!
|
|
3848
|
+
if (!activeSecretCache) {
|
|
3585
3849
|
return entry.value;
|
|
3586
3850
|
}
|
|
3587
|
-
return resolveSecretEntryValue(key, entry.value,
|
|
3851
|
+
return resolveSecretEntryValue(key, entry.value, activeSecretCache);
|
|
3588
3852
|
}
|
|
3589
3853
|
return {
|
|
3590
3854
|
manifest,
|
|
@@ -3621,10 +3885,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3621
3885
|
if (!entry) {
|
|
3622
3886
|
return void 0;
|
|
3623
3887
|
}
|
|
3624
|
-
if (!
|
|
3888
|
+
if (!activeSecretCache) {
|
|
3625
3889
|
return entry.value;
|
|
3626
3890
|
}
|
|
3627
|
-
return resolveSecretEntryValue(candidate, entry.value,
|
|
3891
|
+
return resolveSecretEntryValue(candidate, entry.value, activeSecretCache);
|
|
3628
3892
|
})
|
|
3629
3893
|
});
|
|
3630
3894
|
},
|
|
@@ -3815,7 +4079,12 @@ async function createCnos(options = {}) {
|
|
|
3815
4079
|
});
|
|
3816
4080
|
const schemaApplied = applySchemaRules(graph, loadedManifest.manifest.schema);
|
|
3817
4081
|
const promotedGraph = promoteToPublic(schemaApplied.graph, loadedManifest.manifest);
|
|
3818
|
-
const secretCache = options.secretResolution === "lazy" ? new SecretCache() : await batchResolveSecrets(
|
|
4082
|
+
const secretCache = options.secretResolution === "lazy" ? new SecretCache() : await batchResolveSecrets(
|
|
4083
|
+
promotedGraph,
|
|
4084
|
+
loadedManifest.manifest,
|
|
4085
|
+
options.processEnv,
|
|
4086
|
+
options.secretVaultProviders
|
|
4087
|
+
);
|
|
3819
4088
|
return createRuntime(
|
|
3820
4089
|
loadedManifest.manifest,
|
|
3821
4090
|
appendMetaEntries({
|
|
@@ -3825,12 +4094,13 @@ async function createCnos(options = {}) {
|
|
|
3825
4094
|
plugins,
|
|
3826
4095
|
secretCache,
|
|
3827
4096
|
options.processEnv,
|
|
3828
|
-
options.cnosVersion
|
|
4097
|
+
options.cnosVersion,
|
|
4098
|
+
options.secretVaultProviders
|
|
3829
4099
|
);
|
|
3830
4100
|
}
|
|
3831
4101
|
|
|
3832
4102
|
// ../core/src/runtime/dump.ts
|
|
3833
|
-
var
|
|
4103
|
+
var import_promises13 = require("fs/promises");
|
|
3834
4104
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
3835
4105
|
function buildDumpFiles(graph, options = {}) {
|
|
3836
4106
|
const basePath = options.flatten ? "" : import_node_path13.default.posix.join("workspaces", graph.workspace.workspaceId);
|
|
@@ -3866,8 +4136,8 @@ async function writeDump(graph, options) {
|
|
|
3866
4136
|
const plan = planDump(graph, options);
|
|
3867
4137
|
for (const file of plan.files) {
|
|
3868
4138
|
const destination = import_node_path13.default.join(root, file.path);
|
|
3869
|
-
await (0,
|
|
3870
|
-
await (0,
|
|
4139
|
+
await (0, import_promises13.mkdir)(import_node_path13.default.dirname(destination), { recursive: true });
|
|
4140
|
+
await (0, import_promises13.writeFile)(destination, file.content, "utf8");
|
|
3871
4141
|
}
|
|
3872
4142
|
return {
|
|
3873
4143
|
...plan,
|
|
@@ -3910,7 +4180,7 @@ function envVarToLogicalKey(envVar, config = {}) {
|
|
|
3910
4180
|
// package.json
|
|
3911
4181
|
var package_default = {
|
|
3912
4182
|
name: "@kitsy/cnos",
|
|
3913
|
-
version: "1.
|
|
4183
|
+
version: "1.11.1",
|
|
3914
4184
|
description: "Batteries-included CNOS runtime package wired with the official plugins.",
|
|
3915
4185
|
type: "module",
|
|
3916
4186
|
main: "./dist/index.cjs",
|
|
@@ -4109,7 +4379,7 @@ function createCliArgsPlugin() {
|
|
|
4109
4379
|
}
|
|
4110
4380
|
|
|
4111
4381
|
// ../../plugins/dotenv/src/index.ts
|
|
4112
|
-
var
|
|
4382
|
+
var import_promises14 = require("fs/promises");
|
|
4113
4383
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
4114
4384
|
var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
|
|
4115
4385
|
function parseDoubleQuoted(value) {
|
|
@@ -4196,7 +4466,7 @@ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId =
|
|
|
4196
4466
|
}
|
|
4197
4467
|
async function readIfPresent(filePath) {
|
|
4198
4468
|
try {
|
|
4199
|
-
return await (0,
|
|
4469
|
+
return await (0, import_promises14.readFile)(filePath, "utf8");
|
|
4200
4470
|
} catch {
|
|
4201
4471
|
return void 0;
|
|
4202
4472
|
}
|
|
@@ -4262,16 +4532,16 @@ function createPublicEnvExportPlugin() {
|
|
|
4262
4532
|
}
|
|
4263
4533
|
|
|
4264
4534
|
// ../../plugins/filesystem/src/filesystemSecretsReader.ts
|
|
4265
|
-
var
|
|
4535
|
+
var import_promises16 = require("fs/promises");
|
|
4266
4536
|
|
|
4267
4537
|
// ../../plugins/filesystem/src/helpers.ts
|
|
4268
|
-
var
|
|
4538
|
+
var import_promises15 = require("fs/promises");
|
|
4269
4539
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
4270
4540
|
var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
|
|
4271
4541
|
var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
|
|
4272
4542
|
async function existsDirectory(targetPath) {
|
|
4273
4543
|
try {
|
|
4274
|
-
const stat2 = await (0,
|
|
4544
|
+
const stat2 = await (0, import_promises15.readdir)(targetPath);
|
|
4275
4545
|
void stat2;
|
|
4276
4546
|
return true;
|
|
4277
4547
|
} catch {
|
|
@@ -4279,7 +4549,7 @@ async function existsDirectory(targetPath) {
|
|
|
4279
4549
|
}
|
|
4280
4550
|
}
|
|
4281
4551
|
async function collectYamlFiles(root) {
|
|
4282
|
-
const entries = await (0,
|
|
4552
|
+
const entries = await (0, import_promises15.readdir)(root, { withFileTypes: true });
|
|
4283
4553
|
const results = [];
|
|
4284
4554
|
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
4285
4555
|
const absolutePath = import_node_path15.default.join(root, entry.name);
|
|
@@ -4381,7 +4651,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
4381
4651
|
);
|
|
4382
4652
|
const entries = [];
|
|
4383
4653
|
for (const file of files) {
|
|
4384
|
-
const document = await (0,
|
|
4654
|
+
const document = await (0, import_promises16.readFile)(file.absolutePath, "utf8");
|
|
4385
4655
|
const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
|
|
4386
4656
|
for (const entry of fileEntries) {
|
|
4387
4657
|
const metadata = toSecretReferenceMetadata(entry.value);
|
|
@@ -4397,7 +4667,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
4397
4667
|
}
|
|
4398
4668
|
|
|
4399
4669
|
// ../../plugins/filesystem/src/filesystemValuesReader.ts
|
|
4400
|
-
var
|
|
4670
|
+
var import_promises17 = require("fs/promises");
|
|
4401
4671
|
function filesystemValuesReader(filePath, document, workspaceId = "default") {
|
|
4402
4672
|
return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
|
|
4403
4673
|
}
|
|
@@ -4418,7 +4688,7 @@ function createFilesystemValuesPlugin() {
|
|
|
4418
4688
|
).map(([namespace]) => namespace);
|
|
4419
4689
|
const entries = [];
|
|
4420
4690
|
for (const file of files) {
|
|
4421
|
-
const document = await (0,
|
|
4691
|
+
const document = await (0, import_promises17.readFile)(file.absolutePath, "utf8");
|
|
4422
4692
|
entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
|
|
4423
4693
|
}
|
|
4424
4694
|
for (const namespace of customNamespaces) {
|
|
@@ -4433,7 +4703,7 @@ function createFilesystemValuesPlugin() {
|
|
|
4433
4703
|
layers
|
|
4434
4704
|
);
|
|
4435
4705
|
for (const file of namespaceFiles) {
|
|
4436
|
-
const document = await (0,
|
|
4706
|
+
const document = await (0, import_promises17.readFile)(file.absolutePath, "utf8");
|
|
4437
4707
|
entries.push(...yamlObjectToEntries(document, file.relativePath, namespace, "filesystem-values", file.workspaceId));
|
|
4438
4708
|
}
|
|
4439
4709
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-
|
|
2
|
-
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-
|
|
3
|
-
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-
|
|
1
|
+
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-CGJObpyy.cjs';
|
|
2
|
+
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-CGJObpyy.cjs';
|
|
3
|
+
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-C3A8aLjo.cjs';
|
|
4
4
|
|
|
5
5
|
declare function planDump(graph: ResolvedGraph, options?: DumpPlanOptions): DumpPlan;
|
|
6
6
|
declare function writeDump(graph: ResolvedGraph, options: DumpOptions): Promise<DumpResult>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-
|
|
2
|
-
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-
|
|
3
|
-
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-
|
|
1
|
+
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-CGJObpyy.js';
|
|
2
|
+
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-CGJObpyy.js';
|
|
3
|
+
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-DLNNcEso.js';
|
|
4
4
|
|
|
5
5
|
declare function planDump(graph: ResolvedGraph, options?: DumpPlanOptions): DumpPlan;
|
|
6
6
|
declare function writeDump(graph: ResolvedGraph, options: DumpOptions): Promise<DumpResult>;
|