openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
574 lines (573 loc) • 32.7 kB
JavaScript
import { c as normalizeOptionalLowercaseString } from "./string-coerce-CIXf7egm.js";
import { n as createLazyPromise } from "./lazy-promise-DGqyc4Y4.js";
import { n as isTruthyEnvValue } from "./env-M3R40TOb.js";
import { C as applyConfigOverrides, u as readConfigFileSnapshotWithPluginMetadata } from "./io.runtime-B9iJRs3w.js";
import { c as isNixMode } from "./paths-D2sRr1a_.js";
import { i as tryGetLegacyDefaultAgentId, r as retainLegacyDefaultAgentId, t as inheritLegacyDefaultAgentId } from "./legacy.default-agent-owner-BGwEdQRe.js";
import { o as measureDiagnosticsTimelineSpan } from "./diagnostics-timeline-CRX1LXmg.js";
import { i as materializeLegacyDefaultAgentRoles } from "./legacy.roster-CQ9vDbV2.js";
import { c as hasUnresolvedConfigPath, n as copyConfigResolutionFacts, r as copyConfigResolutionFactsExcept } from "./resolution-facts-Dks1tbik.js";
import { t as createInvalidConfigError } from "./io.invalid-config-xEPg4zuq.js";
import { n as isPluginPackagingRuntimeOutputInvalidConfigSnapshot } from "./recovery-policy-CsUZ07YX.js";
import "./io-bdCzpGWJ.js";
import { n as evaluateGatewayAuthSurfaceStates, t as GATEWAY_AUTH_SURFACE_PATHS } from "./runtime-gateway-auth-surfaces-M-CtMPEM.js";
import { a as isProviderScopedSecretResolutionError } from "./resolve-errors-C2XRFrol.js";
import { r as resolveGatewayAuthForConfig } from "./auth-resolve-O5AKX-sb.js";
import { n as formatPluginPackagingRuntimeOutputRecoveryHint, t as formatInvalidConfigRecoveryHint } from "./config-recovery-hints-BS5G0aQ-.js";
import { t as renderConfigValidationIssueLines } from "./issue-location-Dbpi1Rol.js";
import { t as resolveAuthProfileSecretOwnerId } from "./runtime-auth-profile-owner-DA1NOJfL.js";
import { a as classifySecretResolutionErrorDegradations, h as redactSecretDegradationReason, l as isRetryableSecretDegradationReason, m as listSecretResolutionErrorOwners, t as SECRET_DEGRADATION_RETRY_HINT } from "./runtime-degraded-state-D5EZZ925.js";
import { t as applyPluginAutoEnable } from "./plugin-auto-enable-Tv_C18cS.js";
import { l as hasLegacyAuthProfileSourcesForStartup } from "./legacy-source-diagnostic-BNaogmw1.js";
import { c as getActiveSecretsRuntimeSnapshotRevisionState, f as graftActiveSecretsRuntimeAuthState, g as hasSameSecretReloadContract, l as getActiveSecretsRuntimeSnapshotState, m as hasCurrentAuthStoreCredentialsRevision, p as hasActiveSecretsRuntimeSnapshotLineage, t as activateSecretsRuntimeSnapshotState } from "./runtime-state-C4aJ8Hzz.js";
import { i as assertGatewayAuthNotKnownWeak, n as mergeGatewayAuthConfig, r as mergeGatewayTailscaleConfig, t as ensureGatewayStartupAuth } from "./startup-auth-D92BVWdq.js";
import { a as collectCandidateAgentDirs, c as prepareSecretsRuntimeFastPathSnapshot, r as registerProviderAuthRuntimeSnapshotActivationOwner } from "./runtime-provider-auth-activation-D3tJdpt4.js";
import { isDeepStrictEqual } from "node:util";
//#region src/secrets/runtime-provider-auth-scope.ts
/** Classifies degradation state owned by provider and auth-profile refreshes. */
function listProviderAuthDegradedOwners(snapshot) {
const modelProviderOwnerIds = new Set(Object.keys(snapshot.sourceConfig.models?.providers ?? {}).map((providerId) => normalizeOptionalLowercaseString(providerId) ?? providerId));
const authOwnerIds = new Set(snapshot.authStores.flatMap(({ agentDir, store }) => Object.keys(store.profiles).map((profileId) => resolveAuthProfileSecretOwnerId({
agentDir,
profileId
}))));
return (snapshot.degradedOwners ?? []).filter((owner) => owner.ownerKind === "provider" && modelProviderOwnerIds.has(owner.ownerId) || owner.ownerKind === "account" && authOwnerIds.has(owner.ownerId));
}
/** Whether a config-source repair may recover without replacing active auth-store state. */
function preparedDegradationSupportsSourceOnlyRecovery(snapshot) {
const degradedOwners = snapshot.degradedOwners ?? [];
const authOwnerIds = new Set(snapshot.authStores.flatMap(({ agentDir, store }) => Object.keys(store.profiles).map((profileId) => resolveAuthProfileSecretOwnerId({
agentDir,
profileId
}))));
return degradedOwners.length > 0 && degradedOwners.every((owner) => owner.degradationState === "cold" && !(owner.ownerKind === "account" && authOwnerIds.has(owner.ownerId)));
}
function resolvePreparedSecretsStateScope(snapshot) {
const degradedOwners = snapshot.degradedOwners ?? [];
return degradedOwners.length > 0 && listProviderAuthDegradedOwners(snapshot).length === degradedOwners.length ? "provider-auth" : "full";
}
//#endregion
//#region src/secrets/runtime-warning-log.ts
function logRuntimeSecretWarnings(params) {
const providerFailurePaths = new Set((params.snapshot.degradedOwners ?? []).flatMap((owner) => owner.providerFailures?.length && !owner.refFailureReason ? owner.paths : []));
const activeDegradedPaths = params.ownerUnavailable === "active-only" ? new Set((params.snapshot.degradedOwners ?? []).flatMap((owner) => owner.paths)) : null;
for (const warning of params.snapshot.warnings) {
if (warning.code === "SECRETS_OWNER_UNAVAILABLE") {
if (params.ownerUnavailable === "exclude") continue;
if (activeDegradedPaths && !activeDegradedPaths.has(warning.path)) continue;
if (providerFailurePaths.has(warning.path)) continue;
} else if (params.ownerUnavailable === "active-only") continue;
params.log.warn(`[${warning.code}] ${warning.message}`);
}
}
//#endregion
//#region src/gateway/server-startup-config-helpers.ts
/** Throw a formatted startup error when the loaded config snapshot is invalid. */
function assertValidGatewayStartupConfigSnapshot(snapshot, options = {}) {
if (snapshot.valid) return;
const issues = snapshot.issues.length > 0 ? renderConfigValidationIssueLines(snapshot, "").join("\n") : "Unknown validation issue.";
const recoveryHint = options.includeDoctorHint && isPluginPackagingRuntimeOutputInvalidConfigSnapshot(snapshot) ? `\n${formatPluginPackagingRuntimeOutputRecoveryHint()}` : options.includeDoctorHint ? `\n${formatInvalidConfigRecoveryHint()}` : "";
throw createInvalidConfigError(snapshot.path, `${issues}${recoveryHint}`, { recovery: isPluginPackagingRuntimeOutputInvalidConfigSnapshot(snapshot) ? "manual" : "doctor" });
}
function withRuntimeConfig(snapshot, runtimeConfig) {
copyConfigResolutionFacts(snapshot.sourceConfig, runtimeConfig);
return {
...snapshot,
runtimeConfig,
config: runtimeConfig
};
}
/** Load and validate the config snapshot, applying runtime-only plugin auto-enable changes. */
async function loadGatewayStartupConfigSnapshot(params) {
const measure = params.measure ?? (async (_name, run) => await run());
const snapshotRead = params.initialSnapshotRead ?? await measure("config.snapshot.read", () => readConfigFileSnapshotWithPluginMetadata({ measure }));
const configSnapshot = snapshotRead.snapshot;
const pluginMetadataSnapshot = snapshotRead.pluginMetadataSnapshot;
const wroteConfig = false;
if (configSnapshot.legacyIssues.length > 0 && isNixMode) throw createInvalidConfigError(configSnapshot.path, "Legacy config entries detected while running in Nix mode. Update your Nix config to the latest schema and restart.", { recovery: "manual" });
if (configSnapshot.exists) assertValidGatewayStartupConfigSnapshot(configSnapshot, { includeDoctorHint: true });
const autoEnable = params.minimalTestGateway ? {
config: configSnapshot.config,
changes: []
} : await measure("config.snapshot.auto-enable", () => applyPluginAutoEnable({
config: configSnapshot.sourceConfig,
env: process.env,
...pluginMetadataSnapshot?.manifestRegistry ? { manifestRegistry: pluginMetadataSnapshot.manifestRegistry } : {},
discovery: pluginMetadataSnapshot?.discovery
}));
if (autoEnable.changes.length === 0) return {
snapshot: configSnapshot,
wroteConfig,
...pluginMetadataSnapshot ? { pluginMetadataSnapshot } : {}
};
params.log.info(`gateway: auto-enabled plugins for this runtime without writing config:\n${autoEnable.changes.map((entry) => `- ${entry}`).join("\n")}`);
const legacyDefaultAgentId = tryGetLegacyDefaultAgentId(configSnapshot.sourceConfig);
const runtimeConfig = legacyDefaultAgentId ? materializeLegacyDefaultAgentRoles(autoEnable.config, legacyDefaultAgentId).config : autoEnable.config;
retainLegacyDefaultAgentId(runtimeConfig, legacyDefaultAgentId);
return {
snapshot: withRuntimeConfig(configSnapshot, runtimeConfig),
wroteConfig,
...pluginMetadataSnapshot ? { pluginMetadataSnapshot } : {}
};
}
function hasActiveGatewayAuthSecretRef(config) {
const states = evaluateGatewayAuthSurfaceStates({
config,
defaults: config.secrets?.defaults,
env: process.env
});
return GATEWAY_AUTH_SURFACE_PATHS.some((path) => {
const state = states[path];
return state.hasSecretRef && state.active;
});
}
function assertRuntimeGatewayAuthNotKnownWeak(config) {
assertGatewayAuthNotKnownWeak(resolveGatewayAuthForConfig({
config,
env: process.env,
tailscaleMode: config.gateway?.tailscale?.mode ?? "off"
}));
}
function logGatewayAuthSurfaceDiagnostics(prepared, logSecrets) {
const states = evaluateGatewayAuthSurfaceStates({
config: prepared.sourceConfig,
defaults: prepared.sourceConfig.secrets?.defaults,
env: process.env
});
const inactiveWarnings = /* @__PURE__ */ new Map();
for (const warning of prepared.warnings) {
if (warning.code !== "SECRETS_REF_IGNORED_INACTIVE_SURFACE") continue;
inactiveWarnings.set(warning.path, warning.message);
}
for (const path of GATEWAY_AUTH_SURFACE_PATHS) {
const state = states[path];
if (!state.hasSecretRef) continue;
const stateLabel = state.active ? "active" : "inactive";
const details = (!state.active && inactiveWarnings.get(path) ? inactiveWarnings.get(path) : void 0) ?? state.reason;
logSecrets.info(`[SECRETS_GATEWAY_AUTH_SURFACE] ${path} is ${stateLabel}. ${details}`);
}
}
function applyGatewayAuthOverridesForStartupPreflight(config, overrides) {
if (!overrides.auth && !overrides.tailscale) return config;
const next = {
...config,
gateway: {
...config.gateway,
auth: mergeGatewayAuthConfig(config.gateway?.auth, overrides.auth),
tailscale: mergeGatewayTailscaleConfig(config.gateway?.tailscale, overrides.tailscale)
}
};
copyConfigResolutionFactsExcept(config, next, [...overrides.auth?.token !== void 0 ? ["gateway.auth.token"] : [], ...overrides.auth?.password !== void 0 ? ["gateway.auth.password"] : []]);
return next;
}
//#endregion
//#region src/gateway/server-startup-secret-diagnostics.ts
/** Aggregates redacted SecretRef degradation diagnostics at the Gateway activation boundary. */
function logSecretDegradation(log, degradation) {
const reason = redactSecretDegradationReason(degradation.reason);
log.warn(`[SECRETS_DEGRADED] ${degradation.state} ${degradation.kind}:${degradation.id}: ${reason}. Retry: ${degradation.retryHint}.`, {
event: "secrets.degraded",
ownerKind: degradation.kind,
ownerId: degradation.id,
reason,
state: degradation.state,
retryHint: degradation.retryHint
});
}
function logSecretProviderDegradation(log, providerFailure, degradations) {
const reason = redactSecretDegradationReason(degradations[0]?.reason ?? "secret resolution failed");
const affectedOwners = degradations.map(({ kind, id, state }) => ({
ownerKind: kind,
ownerId: id,
state
})).toSorted((left, right) => left.ownerKind.localeCompare(right.ownerKind) || left.ownerId.localeCompare(right.ownerId));
const affectedOwnerSummary = affectedOwners.map((owner) => `${owner.state} ${owner.ownerKind}:${owner.ownerId}`).join(", ");
log.warn(`[SECRETS_PROVIDER_DEGRADED] ${providerFailure.source}:${providerFailure.provider}: ${reason}. Affected owners: ${affectedOwnerSummary}. Retry: ${SECRET_DEGRADATION_RETRY_HINT}.`, {
event: "secrets.provider_degraded",
source: providerFailure.source,
provider: providerFailure.provider,
reason,
affectedOwners,
retryHint: SECRET_DEGRADATION_RETRY_HINT
});
}
/** Logs one provider diagnostic per failed provider and owner diagnostics for ref failures. */
function logPreparedSecretDegradations(log, owners) {
const providerDegradations = /* @__PURE__ */ new Map();
for (const owner of owners) {
const degradation = {
kind: owner.ownerKind,
id: owner.ownerId,
reason: owner.reason,
state: owner.degradationState ?? "cold",
retryHint: SECRET_DEGRADATION_RETRY_HINT
};
if (!owner.providerFailures?.length) {
logSecretDegradation(log, degradation);
continue;
}
if (owner.refFailureReason) logSecretDegradation(log, {
...degradation,
reason: owner.refFailureReason
});
for (const providerFailure of owner.providerFailures) {
const key = `${providerFailure.source}\0${providerFailure.provider}`;
const group = providerDegradations.get(key);
if (group) group.degradations.push({
...degradation,
reason: "secret provider failed"
});
else providerDegradations.set(key, {
providerFailure,
degradations: [{
...degradation,
reason: "secret provider failed"
}]
});
}
}
for (const group of providerDegradations.values()) logSecretProviderDegradation(log, group.providerFailure, group.degradations);
}
/** Logs typed thrown failures with the same provider-level aggregation as prepared snapshots. */
function logThrownSecretDegradations(log, error, degradations) {
if (isProviderScopedSecretResolutionError(error)) {
logSecretProviderDegradation(log, {
source: error.source,
provider: error.provider
}, degradations);
return;
}
for (const degradation of degradations) logSecretDegradation(log, degradation);
}
//#endregion
//#region src/gateway/server-startup-secret-surfaces.ts
function resolveGatewayStartupSourceConfig(config, env) {
if (!(isTruthyEnvValue(env.OPENCLAW_SKIP_CHANNELS) || isTruthyEnvValue(env.OPENCLAW_SKIP_PROVIDERS)) || !config.channels) return config;
return {
...config,
channels: void 0
};
}
//#endregion
//#region src/gateway/server-startup-config.ts
const runtimeSecretsStatePublishers = /* @__PURE__ */ new WeakMap();
/** Publishes a deferred degradation or recovery after the prepared snapshot wins its commit CAS. */
function publishRuntimeSecretsStateTransition(activateRuntimeSecrets, snapshot, options) {
runtimeSecretsStatePublishers.get(activateRuntimeSecrets)?.(snapshot, options);
}
/** Create the serialized secrets activation function used by startup and reload paths. */
function createRuntimeSecretsActivator(params) {
let secretsDegraded = false;
let degradationGeneration = 0;
let activeDegradationGeneration = null;
let activeDegradationConfig = null;
let activeDegradationSupportsSourceOnlyRecovery = false;
let activeDegradationScope = null;
const deferredStateTransitions = /* @__PURE__ */ new WeakMap();
let pendingDeferredLineageRevision = null;
let secretsActivationTail = Promise.resolve();
const loadSecretsRuntime = createLazyPromise(() => import("./runtime-BTfxhatB.js"), { cacheRejections: true });
const loadAuthProfiles = createLazyPromise(() => import("./auth-profiles-DH_4tHev.js"), { cacheRejections: true });
const startupManifestRegistry = params.manifestRegistry ?? params.pluginMetadataSnapshot?.manifestRegistry;
const runWithSecretsActivationLock = async (operation) => {
const run = secretsActivationTail.then(operation, operation);
secretsActivationTail = run.then(() => void 0, () => void 0);
return await run;
};
const loadActivateRuntimeSecretsSnapshot = async () => {
if (params.activateRuntimeSecretsSnapshot) return params.activateRuntimeSecretsSnapshot;
return (await loadSecretsRuntime()).activateSecretsRuntimeSnapshot;
};
const publishRecovery = (config, expectedGeneration, scope = "full") => {
if (!secretsDegraded || expectedGeneration !== void 0 && activeDegradationGeneration !== expectedGeneration || scope === "provider-auth" && activeDegradationScope !== "provider-auth") return;
const recoveredMessage = "Secret resolution recovered; runtime remained on last-known-good during the outage.";
params.logSecrets.info(`[SECRETS_RELOADER_RECOVERED] ${recoveredMessage}`);
params.emitStateEvent("SECRETS_RELOADER_RECOVERED", recoveredMessage, config);
secretsDegraded = false;
activeDegradationGeneration = null;
activeDegradationConfig = null;
activeDegradationSupportsSourceOnlyRecovery = false;
activeDegradationScope = null;
};
const publishDegradation = (prepared, reason, scope = "full", activationScope = "full") => {
logPreparedSecretDegradations(params.logSecrets, prepared.degradedOwners ?? []);
if (reason === "startup") return;
if (activationScope === "provider-auth" && activeDegradationScope === "full") return;
if (!secretsDegraded) params.emitStateEvent("SECRETS_RELOADER_DEGRADED", "Secret resolution degraded one or more owners; healthy owners were refreshed.", prepared.config);
const currentSupportsSourceOnlyRecovery = preparedDegradationSupportsSourceOnlyRecovery(prepared);
activeDegradationSupportsSourceOnlyRecovery = secretsDegraded ? activeDegradationSupportsSourceOnlyRecovery && currentSupportsSourceOnlyRecovery : currentSupportsSourceOnlyRecovery;
secretsDegraded = true;
activeDegradationGeneration = ++degradationGeneration;
activeDegradationConfig = structuredClone(prepared.sourceConfig);
activeDegradationScope = scope;
};
const finishPreparedSnapshot = async (prepared, activationParams, options) => {
assertRuntimeGatewayAuthNotKnownWeak(prepared.config);
if (activationParams.activate && !options?.alreadyActivated) (options?.activateRuntimeSecretsSnapshot ?? await loadActivateRuntimeSecretsSnapshot())(prepared);
if (activationParams.activate) {
options?.onActivated?.();
logGatewayAuthSurfaceDiagnostics(prepared, params.logSecrets);
}
logRuntimeSecretWarnings({
snapshot: prepared,
log: params.logSecrets,
ownerUnavailable: activationParams.activate && activationParams.deferStatePublication !== true ? "include" : "exclude"
});
const statePrepared = options?.stateDegradedOwners ? {
...prepared,
degradedOwners: options.stateDegradedOwners
} : prepared;
const stateScope = options?.stateScope ?? resolvePreparedSecretsStateScope(statePrepared);
const activationScope = options?.stateScope ?? "full";
if (activationParams.activate && (statePrepared.degradedOwners?.length ?? 0) > 0) {
if (activationParams.deferStatePublication === true) {
const activationRevision = getActiveSecretsRuntimeSnapshotRevisionState();
deferredStateTransitions.set(prepared, {
kind: "degraded",
activationRevision,
reason: activationParams.reason,
activationScope
});
pendingDeferredLineageRevision = activationRevision;
} else publishDegradation(statePrepared, activationParams.reason, stateScope, activationScope);
} else if (activationParams.activate && secretsDegraded) {
if (activationParams.deferStatePublication === true) {
if (activeDegradationGeneration !== null) {
const activationRevision = getActiveSecretsRuntimeSnapshotRevisionState();
deferredStateTransitions.set(prepared, {
kind: "recovered",
activationRevision,
degradationGeneration: activeDegradationGeneration,
reason: activationParams.reason,
activationScope
});
pendingDeferredLineageRevision = activationRevision;
}
} else publishRecovery(prepared.config, void 0, stateScope);
}
return prepared;
};
const handleSecretsActivationError = (err, activationParams, eventConfig) => {
const mayPublishReloadDegradation = (activationParams.activate || activationParams.publishFailureAsDegraded === true) && (activationParams.canPublishFailureAsDegraded?.() ?? true);
const degradations = classifySecretResolutionErrorDegradations(err);
const retryableDegradations = degradations.filter((degradation) => isRetryableSecretDegradationReason(degradation.reason));
if (retryableDegradations.length > 0 && (activationParams.reason === "startup" || mayPublishReloadDegradation)) {
logThrownSecretDegradations(params.logSecrets, err, retryableDegradations);
if (activationParams.reason !== "startup") {
if (!secretsDegraded) params.emitStateEvent("SECRETS_RELOADER_DEGRADED", "Secret resolution failed; runtime remains on the last-known-good snapshot.", eventConfig);
const failedOwners = listSecretResolutionErrorOwners(err).filter((owner) => owner.failureMatched);
const currentFailureSupportsSourceOnlyRecovery = failedOwners.length > 0 && failedOwners.every((owner) => owner.source === "config" && owner.degradationState === "cold");
activeDegradationSupportsSourceOnlyRecovery = secretsDegraded ? activeDegradationSupportsSourceOnlyRecovery && currentFailureSupportsSourceOnlyRecovery : currentFailureSupportsSourceOnlyRecovery;
secretsDegraded = true;
activeDegradationGeneration = ++degradationGeneration;
activeDegradationConfig = structuredClone(eventConfig);
activeDegradationScope = "full";
}
}
if (activationParams.reason === "startup") {
if (degradations.length > 0) throw new Error("Startup failed: required secrets are unavailable.");
throw new Error(`Startup failed: required secrets are unavailable. ${String(err)}`, { cause: err });
}
throw err;
};
const activateRuntimeSecrets = (async (config, activationParams) => await runWithSecretsActivationLock(async () => {
let activationSourceConfig = config;
try {
const sourceConfig = resolveGatewayStartupSourceConfig(config, activationParams.env ?? process.env);
activationSourceConfig = sourceConfig;
const startupPreflight = activationParams.reason === "startup" || activationParams.reason === "restart-check";
if (activationParams.reason === "startup" && activationParams.activate && !params.prepareRuntimeSecretsSnapshot && !params.activateRuntimeSecretsSnapshot) {
const startupEnv = activationParams.env ?? process.env;
const fastPath = hasLegacyAuthProfileSourcesForStartup({
agentDirs: collectCandidateAgentDirs(sourceConfig, startupEnv),
env: startupEnv
}) ? null : prepareSecretsRuntimeFastPathSnapshot({
config: sourceConfig,
env: startupEnv,
...startupManifestRegistry ? { manifestRegistry: startupManifestRegistry } : {}
});
if (fastPath) return await finishPreparedSnapshot(fastPath.snapshot, activationParams, { activateRuntimeSecretsSnapshot: (snapshot) => activateSecretsRuntimeSnapshotState({
snapshot,
refreshContext: fastPath.refreshContext,
refreshHandler: {
preflight: async (refreshParams) => await (await loadSecretsRuntime()).preflightActiveSecretsRuntimeSnapshotRefresh(refreshParams),
refresh: async (refreshParams) => await (await loadSecretsRuntime()).refreshActiveSecretsRuntimeSnapshotForConfig(refreshParams)
}
}) });
}
const loadAuthStore = startupPreflight ? (await loadAuthProfiles()).loadAuthProfileStoreWithoutExternalProfiles : void 0;
const secretsRuntime = params.prepareRuntimeSecretsSnapshot && params.activateRuntimeSecretsSnapshot ? null : await loadSecretsRuntime();
const prepareRuntimeSecretsSnapshot = params.prepareRuntimeSecretsSnapshot ?? secretsRuntime.prepareSecretsRuntimeSnapshot;
const allowUnavailableSecretOwners = activationParams.reason !== "startup" || getActiveSecretsRuntimeSnapshotState() === null;
const prepared = await measureDiagnosticsTimelineSpan("secrets.prepare", () => prepareRuntimeSecretsSnapshot({
config: sourceConfig,
allowUnavailableSecretOwners,
...activationParams.env ? { env: activationParams.env } : {},
includeAuthStoreRefs: activationParams.includeAuthStoreRefs,
forceColdRefKeys: activationParams.forceColdRefKeys,
...startupManifestRegistry ? { manifestRegistry: startupManifestRegistry } : {},
...params.pluginMetadataSnapshot ? { pluginMetadataSnapshot: params.pluginMetadataSnapshot } : {},
...loadAuthStore ? { loadAuthStore } : {}
}), {
attributes: {
activate: activationParams.activate,
gatewayAuthSecretRef: hasActiveGatewayAuthSecretRef(config),
reason: activationParams.reason
},
config,
env: activationParams.env ?? process.env,
omitErrorMessage: true,
phase: activationParams.reason
});
if (activationParams.includeAuthStoreRefs === false) graftActiveSecretsRuntimeAuthState(prepared);
return await finishPreparedSnapshot(prepared, activationParams);
} catch (err) {
return handleSecretsActivationError(err, activationParams, activationSourceConfig);
}
}));
activateRuntimeSecrets.activatePreparedSnapshot = async (snapshot, activationParams) => await runWithSecretsActivationLock(async () => {
try {
return await finishPreparedSnapshot(snapshot, activationParams);
} catch (err) {
return handleSecretsActivationError(err, activationParams, snapshot.sourceConfig);
}
});
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent = async (snapshot, expectedRevision, activationParams, onActivated, canActivate) => {
const runtimeSourceConfig = activationParams.runtimeSourceConfig;
const activateRuntimeSecretsSnapshot = activationParams.activate ? runtimeSourceConfig ? ((runtime) => (preparedSnapshot) => runtime.activateSecretsRuntimeSnapshotWithSource(preparedSnapshot, runtimeSourceConfig))(await loadSecretsRuntime()) : await loadActivateRuntimeSecretsSnapshot() : void 0;
return await runWithSecretsActivationLock(async () => {
if (getActiveSecretsRuntimeSnapshotRevisionState() !== expectedRevision || !hasCurrentAuthStoreCredentialsRevision(snapshot) || canActivate && !canActivate()) return null;
let activated;
let publication;
try {
activated = await finishPreparedSnapshot(snapshot, activationParams, activateRuntimeSecretsSnapshot ? {
activateRuntimeSecretsSnapshot,
...onActivated ? { onActivated: () => {
publication = Promise.resolve(onActivated());
} } : {}
} : void 0);
} catch (err) {
return handleSecretsActivationError(err, activationParams, snapshot.sourceConfig);
}
await publication;
return activated;
});
};
const providerAuthActivationParams = {
reason: "reload",
activate: true
};
registerProviderAuthRuntimeSnapshotActivationOwner({
runExclusive: runWithSecretsActivationLock,
isCurrent: (snapshot, expectedRevision) => getActiveSecretsRuntimeSnapshotRevisionState() === expectedRevision && hasCurrentAuthStoreCredentialsRevision(snapshot),
assertValid: (snapshot) => assertRuntimeGatewayAuthNotKnownWeak(snapshot.config),
publish: async (snapshot) => {
if (pendingDeferredLineageRevision !== null && hasActiveSecretsRuntimeSnapshotLineage(pendingDeferredLineageRevision)) return;
await finishPreparedSnapshot(snapshot, providerAuthActivationParams, {
alreadyActivated: true,
stateScope: "provider-auth",
stateDegradedOwners: listProviderAuthDegradedOwners(snapshot)
});
},
onError: (error, snapshot) => handleSecretsActivationError(error, providerAuthActivationParams, snapshot.sourceConfig)
});
runtimeSecretsStatePublishers.set(activateRuntimeSecrets, (snapshot, options) => {
const transition = deferredStateTransitions.get(snapshot);
deferredStateTransitions.delete(snapshot);
if (transition && pendingDeferredLineageRevision === transition.activationRevision) pendingDeferredLineageRevision = null;
if (!transition) {
const activeSnapshot = options?.sourceOnly === true && options.expectedRevision !== void 0 && hasActiveSecretsRuntimeSnapshotLineage(options.expectedRevision) ? getActiveSecretsRuntimeSnapshotState() : null;
const sourceOnlyDegradationGeneration = activeDegradationGeneration;
if (activeSnapshot !== null && sourceOnlyDegradationGeneration !== null && activeDegradationSupportsSourceOnlyRecovery && activeDegradationConfig !== null && !hasSameSecretReloadContract(activeDegradationConfig, activeSnapshot.sourceConfig)) {
if ((activeSnapshot.degradedOwners?.length ?? 0) > 0) {
const activeScope = resolvePreparedSecretsStateScope(activeSnapshot);
publishDegradation(activeSnapshot, "reload", activeScope);
} else publishRecovery(activeSnapshot.config, sourceOnlyDegradationGeneration);
}
return;
}
if (!hasActiveSecretsRuntimeSnapshotLineage(transition.activationRevision)) return;
const activeSnapshot = getActiveSecretsRuntimeSnapshotState();
if (!activeSnapshot) return;
logRuntimeSecretWarnings({
snapshot: activeSnapshot,
log: params.logSecrets,
ownerUnavailable: "active-only"
});
if ((activeSnapshot.degradedOwners?.length ?? 0) > 0) {
const activeScope = resolvePreparedSecretsStateScope(activeSnapshot);
const { reason, activationScope } = transition;
publishDegradation(activeSnapshot, reason, activeScope, activationScope);
return;
}
if (options?.sourceOnly === true && (!activeDegradationSupportsSourceOnlyRecovery || activeDegradationConfig === null || hasSameSecretReloadContract(activeDegradationConfig, activeSnapshot.sourceConfig))) return;
const generation = transition.kind === "recovered" ? transition.degradationGeneration : void 0;
publishRecovery(activeSnapshot.config, generation, transition.activationScope);
});
return activateRuntimeSecrets;
}
/** Prepare the effective Gateway startup config after auth, overrides, and secrets activation. */
async function prepareGatewayStartupConfig(params) {
const measure = params.measure ?? (async (_name, run) => await run());
await measure("config.auth.snapshot-validate", () => assertValidGatewayStartupConfigSnapshot(params.configSnapshot));
const runtimeConfig = await measure("config.auth.runtime-overrides", () => applyConfigOverrides(params.configSnapshot.config));
copyConfigResolutionFacts(params.configSnapshot.config, runtimeConfig);
const startupPreflightConfig = await measure("config.auth.startup-overrides", () => applyGatewayAuthOverridesForStartupPreflight(runtimeConfig, {
auth: params.authOverride,
tailscale: params.tailscaleOverride
}));
const needsAuthSecretPreflight = await measure("config.auth.secret-surface", () => hasActiveGatewayAuthSecretRef(startupPreflightConfig));
let preflightPrepared;
const preflightConfig = await measure("config.auth.secret-preflight", async () => {
if (!needsAuthSecretPreflight) return startupPreflightConfig;
preflightPrepared = await params.activateRuntimeSecrets(startupPreflightConfig, {
reason: "startup",
activate: false
});
return preflightPrepared.config;
}, { omitErrorMessage: true });
const canReusePreflightPreparedSnapshot = (config) => Boolean(preflightPrepared && params.activateRuntimeSecrets.activatePreparedSnapshot && isDeepStrictEqual(resolveGatewayStartupSourceConfig(config, process.env), preflightPrepared.sourceConfig));
const activateStartupSecrets = async (config) => {
if (preflightPrepared && canReusePreflightPreparedSnapshot(config)) return await params.activateRuntimeSecrets.activatePreparedSnapshot(preflightPrepared, {
reason: "startup",
activate: true
});
return await params.activateRuntimeSecrets(config, {
reason: "startup",
activate: true
});
};
const preflightAuthOverride = await measure("config.auth.preflight-override", () => {
const token = preflightConfig.gateway?.auth?.token;
const password = preflightConfig.gateway?.auth?.password;
const resolvedToken = typeof token === "string" && !hasUnresolvedConfigPath(preflightConfig, "gateway.auth.token");
const resolvedPassword = typeof password === "string" && !hasUnresolvedConfigPath(preflightConfig, "gateway.auth.password");
return resolvedToken || resolvedPassword ? {
...params.authOverride,
...resolvedToken ? { token } : {},
...resolvedPassword ? { password } : {}
} : params.authOverride;
});
const authBootstrap = await measure("config.auth.ensure", () => ensureGatewayStartupAuth({
cfg: runtimeConfig,
env: process.env,
authOverride: preflightAuthOverride,
tailscaleOverride: params.tailscaleOverride,
warn: params.log?.warn,
persist: params.persistStartupAuth ?? false,
baseHash: params.configSnapshot.hash
}));
const runtimeStartupConfig = await measure("config.auth.runtime-startup-overrides", () => applyGatewayAuthOverridesForStartupPreflight(authBootstrap.cfg, {
auth: params.authOverride,
tailscale: params.tailscaleOverride
}));
const activatedConfig = (await measure("config.auth.secrets-activate", () => activateStartupSecrets(runtimeStartupConfig), { omitErrorMessage: true })).config;
const config = inheritLegacyDefaultAgentId(params.configSnapshot.config, activatedConfig);
copyConfigResolutionFacts(activatedConfig, config);
return {
...authBootstrap,
cfg: config
};
}
//#endregion
export { loadGatewayStartupConfigSnapshot as i, prepareGatewayStartupConfig as n, publishRuntimeSecretsStateTransition as r, createRuntimeSecretsActivator as t };