From 191c61d23b237b3fa74a28964459da8cf4671004 Mon Sep 17 00:00:00 2001 From: Priya Raman Date: Thu, 9 Jul 2026 00:30:00 +0000 Subject: [PATCH] fix(security): ignore materialized Paperclip runtime directory Adds .paperclip-runtime/ to the root .gitignore alongside the existing .paperclip/ and .paperclip-local/ entries, and adds a Vitest regression test that asserts git check-ignore covers adapter credential paths. Without this entry, adapters that materialize runtime state into /.paperclip-runtime//... expose those files as committable untracked entries inside the git working tree. A git add -A while an auth.json is materialized would stage plaintext credentials. Co-Authored-By: Paperclip --- .gitignore | 1 + packages/shared/src/gitignore-runtime.test.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 packages/shared/src/gitignore-runtime.test.ts diff --git a/.gitignore b/.gitignore index 42840131381..63de6b12829 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ diagnostics/ .vscode/ .claude/settings.local.json .paperclip-local/ +.paperclip-runtime/ /.idea/ /.agents/ diff --git a/packages/shared/src/gitignore-runtime.test.ts b/packages/shared/src/gitignore-runtime.test.ts new file mode 100644 index 00000000000..798dde7cc7d --- /dev/null +++ b/packages/shared/src/gitignore-runtime.test.ts @@ -0,0 +1,19 @@ +import { spawnSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; +import { describe, expect, it } from "vitest"; + +const repoRoot = fileURLToPath(new URL("../../..", import.meta.url)); + +describe("repository gitignore", () => { + it("ignores materialized Paperclip runtime credentials", () => { + const sensitiveRuntimePath = ".paperclip-runtime/codex/home/auth.json"; + const result = spawnSync("git", ["check-ignore", "-v", sensitiveRuntimePath], { + cwd: repoRoot, + encoding: "utf8", + }); + + expect(result.status).toBe(0); + expect(result.stdout).toContain(".paperclip-runtime/"); + expect(result.stdout).toContain(sensitiveRuntimePath); + }); +});