* fix(adapters): stop desktop shell from inheriting host secrets The this-mac shell spawned with the server process environment and ignored the command environment, so Autopilot could read deployment credentials that are not on the run redaction list. Drop credential-shaped host variables, then apply the request environment. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * style(adapters): biome format desktop-sandbox after env scrub Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
import { AGENT_SECRET_NAME_PATTERN } from "@rakazo/contracts";
|
|
|
|
/**
|
|
* Credential-shaped names from the evOo process. Docker exec starts from a fixed
|
|
* environment and then adds the command env; the desktop shell must not inherit
|
|
* deployment secrets that are absent from the run redaction list.
|
|
*/
|
|
const HOST_SECRET_ENV_NAME =
|
|
/(?:^|_)(?:secret|token|password|passwd|credential|api_key|private_key|database_url|encryption_key|auth_secret|authtoken|key)(?:_|$)|(?:password|passwd|secret|token|api_key)$/i;
|
|
|
|
export function desktopCommandEnvironment(
|
|
inherited: NodeJS.ProcessEnv,
|
|
requestEnv: Record<string, string> | undefined,
|
|
): NodeJS.ProcessEnv {
|
|
const env: NodeJS.ProcessEnv = {};
|
|
for (const [key, value] of Object.entries(inherited)) {
|
|
if (value === undefined || isHostSecretEnvName(key)) continue;
|
|
env[key] = value;
|
|
}
|
|
if (!requestEnv) return env;
|
|
for (const [key, value] of Object.entries(requestEnv)) {
|
|
if (!AGENT_SECRET_NAME_PATTERN.test(key) || value.includes("\0")) continue;
|
|
env[key] = value;
|
|
}
|
|
return env;
|
|
}
|
|
|
|
function isHostSecretEnvName(name: string): boolean {
|
|
return HOST_SECRET_ENV_NAME.test(name);
|
|
}
|