← Back to PRs

#18498: daemon: load systemd EnvironmentFile and drop-ins so gateway status probe uses same env as gateway

by saurav470 open 2026-02-16 19:23 View on GitHub →
gateway cli stale size: M
## Summary fix #18475 - **Problem:** After adding systemd user overrides with `EnvironmentFile=` (e.g. `/etc/openclaw/secrets/*.env`) for the openclaw-gateway service, `openclaw gateway status` reports a false **unauthorized: device token mismatch (rotate/reissue device token)** even though the gateway runs normally, the dashboard loads, and `openclaw status` / `openclaw doctor` work. - **Why it matters:** The status command’s RPC probe was using credentials from the CLI’s environment (or main unit only), while the gateway process gets env from systemd **including** EnvironmentFile and drop-ins. Any token/config set only in those files caused a credential mismatch and the misleading device-token error. - **What changed:** On Linux, `readSystemdServiceExecStart()` now loads **EnvironmentFile=** contents and parses **drop-in** dirs (`*.service.d/*.conf`) so the returned `environment` matches what the gateway process actually sees. The daemon status probe already merges this service env; it now gets the same token/config as the gateway. - **What did NOT change:** No change to gateway auth logic, config schema, or other platforms (LaunchAgent, schtasks). Only systemd unit parsing and env merge for the status probe. ## Change Type (select all) - [x] Bug fix - [x] Feature - [ ] Refactor - [ ] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [ ] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes #18475 - Related # ## User-visible / Behavior Changes - **Before:** `openclaw gateway status` could report "unauthorized: device token mismatch" when the gateway was started with `EnvironmentFile=` or drop-in overrides that set `OPENCLAW_GATEWAY_TOKEN` or `OPENCLAW_CONFIG_PATH`, even though the gateway and dashboard were healthy. - **After:** The status probe uses the same env (including vars from EnvironmentFile and drop-ins) as the gateway process, so the probe succeeds and no false device-token error is shown. ## Security Impact (required) - New permissions/capabilities? **No** - Secrets/tokens handling changed? **No** (we only read the same env files systemd already passes to the gateway; no new secrets exposure). - New/changed network calls? **No** - Command/tool execution surface changed? **No** - Data access scope changed? **No** - If any `Yes`, explain risk + mitigation: N/A ## Repro + Verification ### Environment - OS: Linux (e.g. Linux Mint 22.3) - Runtime/container: Node 22+, systemd user units - Relevant config: User override `~/.config/systemd/user/openclaw-gateway.service.d/secrets.conf` with `EnvironmentFile=/etc/openclaw/secrets/agent1.env` (and optionally more). ### Steps 1. Create `/etc/openclaw/secrets/agent1.env` (or placeholder) and `~/.config/systemd/user/openclaw-gateway.service.d/secrets.conf` with `[Service]` and `EnvironmentFile=...`. 2. `systemctl --user daemon-reload` and `openclaw gateway restart`. 3. Run `openclaw gateway status`. ### Expected - Status reports gateway reachable and RPC probe OK (no auth/device-token error). ### Actual (before fix) - Status reported "unauthorized: device token mismatch (rotate/reissue device token)" while gateway and dashboard remained functional. ## Evidence - [x] Failing test/log before + passing after: New unit tests in `src/daemon/systemd.test.ts` for EnvironmentFile=, drop-in merge, optional `-/path`, and `[Service]`-only parsing. - [x] Trace/log snippets: Issue #18475 describes the exact error and steps. ## Human Verification (required) - Verified scenarios: Unit tests for systemd env parsing (EnvironmentFile, drop-ins, optional file, section parsing); existing daemon + daemon-cli tests pass. - Edge cases checked: Optional EnvironmentFile; drop-in override order; [Service] vs [Unit] section. - What you did **not** verify: Live run on Linux with real systemd user gateway and override (reporter’s environment). ## Compatibility / Migration - Backward compatible? **Yes** - Config/env changes? **No** - Migration needed? **No** - If yes, exact upgrade steps: N/A ## Failure Recovery (if this breaks) - Revert the commit; no config or env changes to restore. - Known bad symptoms: If systemd unit or drop-in parsing regresses, `readSystemdServiceExecStart` could return `null` or incomplete env; status would then fall back to CLI env (previous behavior). ## Risks and Mitigations - **Risk:** Parsing of EnvironmentFile format (e.g. quoting) could differ from systemd in edge cases. - **Mitigation:** Parser follows simple KEY=VALUE and optional quoting; optional files use `-/path`; tests cover basic and override cases. Complex expansion is not implemented (systemd does it at run time; we only need same vars for probe). <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes `openclaw gateway status` reporting a false "unauthorized: device token mismatch" when the gateway's systemd unit uses EnvironmentFile directives or drop-in overrides. The status probe now loads the same env files and drop-in configs that systemd passes to the gateway process, so credentials match. - Extracted `parseSystemdServiceSection` to parse only the Service section - Added a parser for env files with basic quote support - The main function now loads EnvironmentFile entries and merges drop-in configs - Four new integration tests cover env file loading, drop-in override precedence, optional file handling, and section-scoped parsing - Only a clarifying comment added to `status.gather.ts`; no functional change **Resilience concern:** If a non-optional EnvironmentFile path is missing or a drop-in file is unreadable, the entire parse aborts and returns null, silently falling back to CLI env. This could mask config issues. <h3>Confidence Score: 3/5</h3> - PR is a net improvement but has resilience gaps in error handling that could silently hide misconfiguration - The core logic for parsing systemd EnvironmentFile and drop-in configs is correct and well-tested for the happy path. However, two error-handling gaps were identified: (1) a missing non-optional EnvironmentFile causes the entire function to silently return null via the outer catch, which is indistinguishable from a missing unit file and could reproduce the same silent credential mismatch the PR aims to fix; (2) a single unreadable drop-in file similarly aborts the full parse, inconsistent with the graceful readdir error handling. These are not regressions (previous code had no EnvironmentFile support at all) but they limit the fix's robustness. Tests are solid but don't cover the required-file-missing failure scenario. - src/daemon/systemd.ts — error handling in readSystemdServiceExecStart for required EnvironmentFile failures and drop-in read errors <sub>Last reviewed commit: 66d5c23</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs