Merge pull request #261 from mvanhorn/fix/234-secret-env-redaction
fix(server): redact secret-sourced env vars in logs by provenance
This commit is contained in:
@@ -245,7 +245,7 @@ export function agentRoutes(db: Db) {
|
||||
adapterConfig: Record<string, unknown>,
|
||||
) {
|
||||
if (adapterType !== "opencode_local") return;
|
||||
const runtimeConfig = await secretsSvc.resolveAdapterConfigForRuntime(companyId, adapterConfig);
|
||||
const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(companyId, adapterConfig);
|
||||
const runtimeEnv = asRecord(runtimeConfig.env) ?? {};
|
||||
try {
|
||||
await ensureOpenCodeModelConfiguredAndAvailable({
|
||||
@@ -420,7 +420,7 @@ export function agentRoutes(db: Db) {
|
||||
inputAdapterConfig,
|
||||
{ strictMode: strictSecretsMode },
|
||||
);
|
||||
const runtimeAdapterConfig = await secretsSvc.resolveAdapterConfigForRuntime(
|
||||
const { config: runtimeAdapterConfig } = await secretsSvc.resolveAdapterConfigForRuntime(
|
||||
companyId,
|
||||
normalizedAdapterConfig,
|
||||
);
|
||||
@@ -1264,7 +1264,7 @@ export function agentRoutes(db: Db) {
|
||||
}
|
||||
|
||||
const config = asRecord(agent.adapterConfig) ?? {};
|
||||
const runtimeConfig = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, config);
|
||||
const { config: runtimeConfig } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, config);
|
||||
const result = await runClaudeLogin({
|
||||
runId: `claude-login-${randomUUID()}`,
|
||||
agent: {
|
||||
|
||||
@@ -1240,11 +1240,16 @@ export function heartbeatService(db: Db) {
|
||||
const mergedConfig = issueAssigneeOverrides?.adapterConfig
|
||||
? { ...config, ...issueAssigneeOverrides.adapterConfig }
|
||||
: config;
|
||||
const resolvedConfig = await secretsSvc.resolveAdapterConfigForRuntime(
|
||||
const { config: resolvedConfig, secretKeys } = await secretsSvc.resolveAdapterConfigForRuntime(
|
||||
agent.companyId,
|
||||
mergedConfig,
|
||||
);
|
||||
const onAdapterMeta = async (meta: AdapterInvocationMeta) => {
|
||||
if (meta.env && secretKeys.size > 0) {
|
||||
for (const key of secretKeys) {
|
||||
if (key in meta.env) meta.env[key] = "***REDACTED***";
|
||||
}
|
||||
}
|
||||
await appendRunEvent(currentRun, seq++, {
|
||||
eventType: "adapter.invoke",
|
||||
stream: "system",
|
||||
|
||||
@@ -308,10 +308,11 @@ export function secretService(db: Db) {
|
||||
return normalized;
|
||||
},
|
||||
|
||||
resolveEnvBindings: async (companyId: string, envValue: unknown) => {
|
||||
resolveEnvBindings: async (companyId: string, envValue: unknown): Promise<{ env: Record<string, string>; secretKeys: Set<string> }> => {
|
||||
const record = asRecord(envValue);
|
||||
if (!record) return {} as Record<string, string>;
|
||||
if (!record) return { env: {} as Record<string, string>, secretKeys: new Set<string>() };
|
||||
const resolved: Record<string, string> = {};
|
||||
const secretKeys = new Set<string>();
|
||||
|
||||
for (const [key, rawBinding] of Object.entries(record)) {
|
||||
if (!ENV_KEY_RE.test(key)) {
|
||||
@@ -326,20 +327,22 @@ export function secretService(db: Db) {
|
||||
resolved[key] = binding.value;
|
||||
} else {
|
||||
resolved[key] = await resolveSecretValue(companyId, binding.secretId, binding.version);
|
||||
secretKeys.add(key);
|
||||
}
|
||||
}
|
||||
return resolved;
|
||||
return { env: resolved, secretKeys };
|
||||
},
|
||||
|
||||
resolveAdapterConfigForRuntime: async (companyId: string, adapterConfig: Record<string, unknown>) => {
|
||||
resolveAdapterConfigForRuntime: async (companyId: string, adapterConfig: Record<string, unknown>): Promise<{ config: Record<string, unknown>; secretKeys: Set<string> }> => {
|
||||
const resolved = { ...adapterConfig };
|
||||
const secretKeys = new Set<string>();
|
||||
if (!Object.prototype.hasOwnProperty.call(adapterConfig, "env")) {
|
||||
return resolved;
|
||||
return { config: resolved, secretKeys };
|
||||
}
|
||||
const record = asRecord(adapterConfig.env);
|
||||
if (!record) {
|
||||
resolved.env = {};
|
||||
return resolved;
|
||||
return { config: resolved, secretKeys };
|
||||
}
|
||||
const env: Record<string, string> = {};
|
||||
for (const [key, rawBinding] of Object.entries(record)) {
|
||||
@@ -355,10 +358,11 @@ export function secretService(db: Db) {
|
||||
env[key] = binding.value;
|
||||
} else {
|
||||
env[key] = await resolveSecretValue(companyId, binding.secretId, binding.version);
|
||||
secretKeys.add(key);
|
||||
}
|
||||
}
|
||||
resolved.env = env;
|
||||
return resolved;
|
||||
return { config: resolved, secretKeys };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user