mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 19:35:13 +01:00
fix(e2e): recognize durable Codex runtime auth
This commit is contained in:
1 parent
168e94b016
commit
5b8e31f3c4
3 files changed
+55
-7
No files matched your search
@@ -25,6 +25,7 @@ import { assertEmbeddedDatabaseIsolation } from "./instance-isolation.js";
|
||||
import {
|
||||
assertSecretFree,
|
||||
findSecretLeakInDirectory,
|
||||
isEphemeralCodexRuntimeAuthFile,
|
||||
normalizedSecrets,
|
||||
sanitizeJson,
|
||||
} from "./redaction.js";
|
||||
@@ -519,15 +520,9 @@ async function runAttempt(input: {
|
||||
ignoreFile: (file) => expectedEphemeralCredentials.has(file),
|
||||
});
|
||||
if (!leak) break;
|
||||
const relative = path
|
||||
.relative(paperclipHome, leak.file)
|
||||
.split(path.sep)
|
||||
.join("/");
|
||||
const isManagedCodexRuntimeAuth =
|
||||
label === "Paperclip home" &&
|
||||
/^instances\/[^/]+\/companies\/[^/]+\/agents\/[^/]+\/codex-home\/auth\.json$/.test(
|
||||
relative,
|
||||
);
|
||||
isEphemeralCodexRuntimeAuthFile(paperclipHome, leak.file);
|
||||
if (isManagedCodexRuntimeAuth) {
|
||||
const metadata = await lstat(leak.file);
|
||||
if (metadata.isFile() && (metadata.mode & 0o777) === 0o600) {
|
||||
|
||||
@@ -19,6 +19,21 @@ export function normalizedSecrets(values: readonly (string | undefined)[]) {
|
||||
].sort((left, right) => right.length - left.length);
|
||||
}
|
||||
|
||||
export function isEphemeralCodexRuntimeAuthFile(
|
||||
paperclipHome: string,
|
||||
file: string,
|
||||
) {
|
||||
const relative = path.relative(paperclipHome, file).split(path.sep).join("/");
|
||||
return (
|
||||
/^instances\/[^/]+\/companies\/[^/]+\/agents\/[^/]+\/codex-home\/auth\.json$/.test(
|
||||
relative,
|
||||
) ||
|
||||
/^instances\/[^/]+\/runtime\/paperclip-runner\/durable-sessions\/[^/]+\/codex-home\/auth\.json$/.test(
|
||||
relative,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function redactText(value: string, secrets: readonly string[]) {
|
||||
let redacted = redactDiagnosticText(value, "[REDACTED]");
|
||||
return redactKnownSecretsAndShapes(redacted, secrets);
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
findSecretLeak,
|
||||
findSecretLeakInJsonValues,
|
||||
findSecretLeakInDirectory,
|
||||
isEphemeralCodexRuntimeAuthFile,
|
||||
redactText,
|
||||
sanitizeJson,
|
||||
} from "./redaction.js";
|
||||
@@ -483,6 +484,43 @@ describe("runner E2E evidence redaction", () => {
|
||||
).resolves.toMatchObject({ file: forbiddenConfig });
|
||||
});
|
||||
|
||||
it("recognizes both managed and durable-session Codex runtime auth files", () => {
|
||||
const root = path.join(os.tmpdir(), "paperclip-home");
|
||||
expect(
|
||||
isEphemeralCodexRuntimeAuthFile(
|
||||
root,
|
||||
path.join(
|
||||
root,
|
||||
"instances/instance-1/companies/company-1/agents/agent-1/codex-home/auth.json",
|
||||
),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
isEphemeralCodexRuntimeAuthFile(
|
||||
root,
|
||||
path.join(
|
||||
root,
|
||||
"instances/instance-1/runtime/paperclip-runner/durable-sessions/session-1/codex-home/auth.json",
|
||||
),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
isEphemeralCodexRuntimeAuthFile(
|
||||
root,
|
||||
path.join(root, "instances/instance-1/runtime/auth.json"),
|
||||
),
|
||||
).toBe(false);
|
||||
expect(
|
||||
isEphemeralCodexRuntimeAuthFile(
|
||||
root,
|
||||
path.join(
|
||||
root,
|
||||
"instances/instance-1/runtime/paperclip-runner/durable-sessions/session-1/codex-home/config.toml",
|
||||
),
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("publishes only allowlisted sanitized files and reports source leaks", async () => {
|
||||
const root = await mkdtemp(
|
||||
path.join(os.tmpdir(), "runner-e2e-evidence-test-"),
|
||||
|
||||
Reference in new issue
Block a user