Skip to content

fix(launchd): set restrictive umask in generated gateway plist#32022

Merged
steipete merged 1 commit intoopenclaw:mainfrom
liuxiaopai-ai:codex/launchd-umask-31905
Mar 2, 2026
Merged

fix(launchd): set restrictive umask in generated gateway plist#32022
steipete merged 1 commit intoopenclaw:mainfrom
liuxiaopai-ai:codex/launchd-umask-31905

Conversation

@liuxiaopai-ai
Copy link

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: macOS launchd plist regeneration did not include Umask, so service restarts after updates could inherit system default 022 and create new gateway/state files as world-readable (644).
  • Why it matters: Sensitive local state should default to owner-only permissions without relying on later audits/fixes.
  • What changed: Added a launchd plist default Umask value of decimal 63 (octal 077) in the shared plist builder used by gateway LaunchAgent installation.
  • What changed: Added/updated launchd install test coverage to assert the generated plist includes Umask and the expected value.
  • What did NOT change (scope boundary): No changes to systemd/schtasks generation, no new config surface, and no runtime file-permission migration logic.

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

User-visible / Behavior Changes

  • Newly installed/reinstalled macOS gateway LaunchAgents now explicitly run with umask 077 (Umask=63 in launchd plist), so newly created files default to owner-only permissions.

Security Impact (required)

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

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 + pnpm
  • Model/provider: N/A
  • Integration/channel (if any): gateway launchd service
  • Relevant config (redacted): default launchd gateway install path

Steps

  1. Generate/install launchd plist via gateway install flow.
  2. Inspect generated plist content.
  3. Run daemon launchd tests.

Expected

  • Generated plist includes Umask key with value 63.
  • Existing keepalive/throttle behavior remains unchanged.

Actual

  • Verified: plist includes Umask=63 and launchd tests pass.

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 scenarios:
    • pnpm exec vitest run src/daemon/launchd.test.ts
    • pnpm lint
    • pnpm tsgo
  • Edge cases checked:
    • LaunchAgent plist contains both KeepAlive and Umask entries.
  • What you did not verify:
    • End-to-end live launchctl install on a local macOS host session.

Compatibility / Migration

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

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly:
    • Revert this PR commit.
  • Files/config to restore:
    • src/daemon/launchd-plist.ts
    • src/daemon/launchd.test.ts
  • Known bad symptoms reviewers should watch for:
    • launchctl bootstrap parse errors from malformed plist (not observed in tests).

Risks and Mitigations

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

  • Risk: Operators who intentionally relied on a more permissive launchd umask will now get stricter defaults.
    • Mitigation: This is a security-default hardening; custom/manual plist edits remain possible after install if explicitly desired.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

Adds explicit Umask=63 (octal 077) to generated macOS launchd plist to ensure gateway service creates files with owner-only permissions by default, preventing world-readable state files after service restarts.

  • Correctly implements umask in plist template with proper decimal value (63 = octal 077)
  • Adds targeted test coverage validating both key presence and expected value
  • Clean security hardening with no changes to runtime logic or other platforms
  • Backward compatible: only affects new installations or service reinstalls

Confidence Score: 5/5

  • Safe to merge - focused security hardening with proper test coverage and no breaking changes
  • This is a minimal, well-tested security improvement that correctly implements restrictive umask defaults for macOS launchd services. The change is isolated to plist generation, has appropriate unit test coverage validating the fix, and follows security best practices. No logical errors, malformed XML, or compatibility issues detected.
  • No files require special attention

Last reviewed commit: 368573e

@steipete steipete force-pushed the codex/launchd-umask-31905 branch from 368573e to 936569f Compare March 2, 2026 18:38
@steipete steipete merged commit c9558cd into openclaw:main Mar 2, 2026
9 checks passed
@steipete
Copy link
Contributor

steipete commented Mar 2, 2026

Landed via temp rebase onto main.

  • Gate: pnpm test src/daemon/launchd.test.ts -t "writes KeepAlive=true policy with restrictive umask"
  • Land commit: 936569f
  • Merge commit: c9558cd

Thanks @liuxiaopai-ai!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:LaunchD plist regeneration drops Umask — gateway writes world-readable files after update

2 participants