Skip to content

security: create session dirs with private permissions#45901

Closed
Tiooo111 wants to merge 28 commits into
openclaw:mainfrom
Tiooo111:chore/pr-scout-2026-03-14
Closed

security: create session dirs with private permissions#45901
Tiooo111 wants to merge 28 commits into
openclaw:mainfrom
Tiooo111:chore/pr-scout-2026-03-14

Conversation

@Tiooo111

@Tiooo111 Tiooo111 commented Mar 14, 2026

Copy link
Copy Markdown

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: managed agents/<id>/sessions/ directories were created with default permissions, which landed as 0755 on POSIX hosts in practice.
  • Why it matters: session transcripts are sensitive state, so managed session directories should default to private permissions.
  • What changed: added ensurePrivateSessionsDir(...) for managed session directories and reused it across setup, onboarding, agent creation, and managed session store / transcript flows.
  • Scope guard: caller-supplied custom session store / transcript directories still use plain mkdir, while managed paths now reject symlinked final or ancestor components before permission hardening, including custom OPENCLAW_STATE_DIR roots.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #

User-visible / Behavior Changes

Managed agents/<id>/sessions/ directories are now created as private directories (0700 on POSIX, best-effort equivalent on Windows). Caller-supplied custom session store / transcript directories keep their previous plain-mkdir behavior.

Security Impact (required)

  • New permissions/capabilities? (Yes/No): No
  • Secrets/tokens handling changed? (Yes/No): No
  • New/changed network calls? (Yes/No): No
  • Command/tool execution surface changed? (Yes/No): No
  • Data access scope changed? (Yes/No): No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS 15.6.1
  • Runtime/container: Node 22.22.0, pnpm 10.23.0
  • Model/provider: N/A
  • Integration/channel (if any): local setup / managed session store paths
  • Relevant config (redacted): local OpenClaw state directories, including custom state-root coverage in tests

Steps

  1. Run setup or create a fresh managed session store under agents/<id>/sessions/.
  2. Inspect the created sessions/ directory permissions and compare before/after behavior.
  3. Repeat with custom caller-supplied store / transcript paths to confirm they still use plain directory creation.
  4. Exercise symlinked managed-path edge cases.

Expected

  • Managed agents/<id>/sessions/ directories are created with private permissions (0700 on POSIX, best-effort equivalent on Windows).
  • Custom caller-supplied directories are not re-permissioned.
  • Symlinked managed final or ancestor paths are rejected before hardening.

Actual

  • Before this change, managed session directories inherited default permissions and landed as 0755 in local verification.
  • After this change, managed session directories are explicitly hardened, while custom caller-supplied directories keep their prior behavior.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified locally:
    • pnpm test -- src/config/sessions/paths.test.ts src/config/sessions/sessions.test.ts src/commands/setup.test.ts
  • Edge cases checked:
    • managed session directories are hardened to private permissions on POSIX
    • Windows permission assertions stay best-effort in tests
    • symlinked managed final or ancestor paths are rejected in the session-path helper tests
    • custom caller-supplied store / transcript directories are not forced to 0700
  • What you did not verify locally:
    • full repo pnpm check
    • full cross-platform onboarding E2E flows

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): No
  • Migration needed? (Yes/No): No
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR's commit stack
  • Files/config to restore: src/config/sessions/paths.ts and the managed session-directory callers
  • Known bad symptoms reviewers should watch for: unexpected failures when managed session paths resolve through symlinked ancestors or unusual filesystems with restricted permission APIs

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: some filesystems may not honor the permission hardening path consistently.
    • Mitigation: the helper applies best-effort hardening and tests cover the intended managed-path behavior on supported platforms.
  • Risk: broadening hardening to caller-supplied custom paths would be a behavioral regression.
    • Mitigation: custom store / transcript paths stay on plain mkdir; only managed session paths are hardened.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime commands Command implementations size: S labels Mar 14, 2026
@greptile-apps

greptile-apps Bot commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens the security posture of session directory creation by replacing bare fs.mkdir(..., { recursive: true }) calls with a new ensurePrivateSessionsDir helper that creates the directory with 0o700 permissions and follows up with a best-effort chmod 0o700 to handle platforms where the mode option is not honoured by mkdir. The change is applied consistently across all production call-sites: setup.ts, onboard-helpers.ts, store.ts (session store saves), transcript.ts (transcript file creation), and agents.ts (agent creation). Tests verifying the 0o700 mode are added in setup.test.ts and sessions.test.ts, with appropriate Windows exemptions.

Key observations:

  • ensurePrivateSessionsDir correctly pairs mkdir with a trailing chmod so existing directories created by older versions are also hardened on the next run.
  • Only the leaf sessions/ directory is chmod'd; intermediate parent directories (agents/, agents/<id>/) retain default permissions, which is intentional since sensitive files live only under sessions/.
  • The chmod error is silently swallowed (best-effort) — this is appropriate for cross-platform support but means permission failures on unexpected platforms won't surface.
  • A duplicate import from "../config/sessions.js" was introduced in onboard-helpers.ts (lines 10–11) instead of merging the two named imports into one statement.

Confidence Score: 4/5

  • Safe to merge after fixing the minor duplicate import in onboard-helpers.ts; core security logic is sound.
  • The security hardening logic is correct and consistently applied across all affected production files. Tests are added and handle cross-platform edge cases. The only issue found is a cosmetic duplicate import statement in onboard-helpers.ts that doesn't affect runtime behaviour.
  • src/commands/onboard-helpers.ts — contains a duplicate import from the same module that should be merged.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/commands/onboard-helpers.ts
Line: 10-11

Comment:
**Duplicate import from same module**

Lines 10 and 11 are two separate `import` statements from the same `"../config/sessions.js"` module. They should be merged into a single statement:

```suggestion
import { resolveSessionTranscriptsDirForAgent, ensurePrivateSessionsDir } from "../config/sessions.js";
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 9e8262b

Comment thread src/commands/onboard-helpers.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e8262b95b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/config/sessions/paths.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58e760bdf0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/config/sessions/paths.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8f609b3fa7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/config/sessions/store.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea56a65155

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/config/sessions/transcript.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 91684c2296

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/config/sessions/paths.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 91cfea1ba7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/config/sessions/paths.ts Outdated
@Tiooo111
Tiooo111 force-pushed the chore/pr-scout-2026-03-14 branch from 91cfea1 to 24fa665 Compare March 14, 2026 10:08
@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web size: L and removed size: M labels Mar 14, 2026
@Tiooo111
Tiooo111 force-pushed the chore/pr-scout-2026-03-14 branch from f4816a8 to 0a426cd Compare March 14, 2026 10:36
@openclaw-barnacle openclaw-barnacle Bot removed channel: discord Channel integration: discord channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web labels Mar 14, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. impact:security Security boundary, credential, authz, sandbox, or sensitive-data risk. labels May 18, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@jesse-merhi jesse-merhi added security Security documentation and removed security Security documentation labels May 25, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 8, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 8, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 9, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 11, 2026
@clawsweeper

clawsweeper Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants