{"record":{"id":"fce7c1ccce689699","repo":"paperclipai/paperclip","slug":"codex-working-directory-cannot-overlap-sensitive-h","errorCode":null,"errorMessage":"Codex working directory cannot overlap sensitive host HOME state","messagePattern":"Codex working directory cannot overlap sensitive host HOME state","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts","lineNumber":82,"sourceCode":"      );\n    }\n    throw error;\n  }\n  if (resolved === parse(resolved).root) {\n    throw new Error(\"Codex working directory cannot be a filesystem root\");\n  }\n  const configuredRoot = environment.PAPERCLIP_WORKSPACE_CWD;\n  const hostHome = canonicalConfiguredPath(environment.HOME);\n  if (hostHome && pathContains(resolved, hostHome)) {\n    throw new Error(\"Codex working directory cannot contain the host HOME\");\n  }\n  if (\n    hostHome &&\n    SENSITIVE_HOST_HOME_DIRECTORIES.some((directory) =>\n      pathContains(resolve(hostHome, directory), resolved),\n    )\n  ) {\n    throw new Error(\n      \"Codex working directory cannot overlap sensitive host HOME state\",\n    );\n  }\n  if (\n    hostHome &&\n    pathContains(hostHome, resolved) &&\n    (configuredRoot === undefined || configuredRoot.trim().length === 0)\n  ) {\n    throw new Error(\n      \"Codex working directory inside the host HOME requires an assigned workspace\",\n    );\n  }\n  const codexHome = canonicalConfiguredPath(environment.CODEX_HOME);\n  if (codexHome) {\n    if (\n      pathContains(resolved, codexHome) ||\n      pathContains(codexHome, resolved)\n    ) {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts#L64-L100","documentation":"Beyond the HOME ancestor check, the validator blocks working directories that overlap a curated list of sensitive directories under the host HOME (things like ~/.ssh, ~/.aws, ~/.config style state). Even if the working directory is not an ancestor of HOME, landing inside one of these protected directories would expose secrets or allow tampering with host tooling.","triggerScenarios":"Setting the working directory to or inside a sensitive directory such as ~/.ssh, ~/.gnupg, ~/.aws, or any path listed in SENSITIVE_HOST_HOME_DIRECTORIES.","commonSituations":"Pointing the agent at its own credential folder to \"manage keys\"; configuring a workspace inside ~/.config/paperclip; copy-pasted HOME-relative defaults.","solutions":["Choose a neutral workspace path outside sensitive HOME subdirectories","Use the PAPERCLIP_WORKSPACE_CWD assigned workspace root for all agent sessions","Move the needed data into a workspace directory instead of running the agent in the sensitive one"],"exampleFix":"// before\nworkingDirectory: \"~/.ssh\"\n// after\nworkingDirectory: \"/workspaces/issue-123\"","handlingStrategy":"validation","validationCode":"const SENSITIVE = [\".ssh\", \".aws\", \".gnupg\", \".config\"]; // mirror SENSITIVE_HOST_HOME_DIRECTORIES\nconst hit = home && SENSITIVE.find((d) => contains(resolve(home, d), resolve(cwd)));\nif (hit) throw new Error(`workspace overlaps sensitive HOME dir ${hit}`);","typeGuard":"function outsideSensitiveHomeDirs(cwd: string, home?: string): boolean {\n  return !SENSITIVE.some((d) => home && contains(resolve(home, d), resolve(cwd)));\n}","tryCatchPattern":"try {\n  validateCodexWorkingDirectory(cwd);\n} catch (err) {\n  if (err.message.includes(\"sensitive host HOME state\")) {\n    throw new ConfigError(`refusing to run agent in protected directory ${cwd}`);\n  }\n  throw err;\n}","preventionTips":["Review workspace sources (user input, templates) for HOME-relative defaults","Keep a copy of the sensitive-directory list in test fixtures and assert workspaces avoid it","Move needed data into the workspace rather than running inside protected dirs"],"tags":["security","filesystem","secrets"],"backgroundTag":"path-traversal-blocked","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}