evOo-local/packages/adapters/src/agent-environment.ts
Cursor Agent be9c310e1e fix(adapters): scope agent secrets to run owner in shared Spaces
Agent secrets are owner-managed via the API but the executor loaded every
secret in the Space and injected decrypted values into shell environment
variables for any member's bot run.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
2026-09-22 06:20:51 +00:00

47 lines
1.4 KiB
TypeScript

import { AgentSecretInputSchema } from "@rakazo/contracts";
import { redactSecrets } from "@rakazo/core";
type EncryptedAgentSecret = {
name: string;
secret: { id: string; ciphertext: string };
};
type SecretLoader = {
load(ciphertext: string, recordId: string): string;
};
export function agentSecretScopeForRun(spaceId: string, userId: string) {
return { spaceId, createdByUserId: userId };
}
export function decryptAgentEnvironment(
rows: EncryptedAgentSecret[],
secrets: SecretLoader,
): Record<string, string> {
return Object.fromEntries(
rows.map((row) => {
AgentSecretInputSchema.shape.name.parse(row.name);
return [row.name, secrets.load(row.secret.ciphertext, row.secret.id)];
}),
);
}
export function formatAgentEnvironmentInstruction(
environment: Record<string, string>,
): string | undefined {
const names = Object.keys(environment).sort();
if (names.length === 0) return undefined;
return `Managed credentials are available to shell commands as these environment variables: ${names.join(", ")}. Use them without printing, logging, or embedding their values in files or messages.`;
}
export function redactAgentCommandResult(
result: { stdout: string; stderr: string; code: number },
secrets: string[],
) {
return {
...result,
stdout: redactSecrets(result.stdout, secrets),
stderr: redactSecrets(result.stderr, secrets),
};
}