Skip to content

fix: copy the keystore credential to a 0600 runtime file in sponsord.service - #37

Merged
thiras merged 2 commits into
mainfrom
fix/systemd-keystore-credential-mode
Oct 5, 2026
Merged

thiras merged 2 commits into
mainfrom
fix/systemd-keystore-credential-mode

Conversation

@thiras

@thiras thiras commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

What

On systemd 255 (Ubuntu 24.04), LoadCredential= files land at mode 0440. The reference unit pointed SPONSORD_TREASURY_KEYSTORE straight at %d/treasury-keystore.json. decdn's validate_keystore_file refuses any group or other bit, so the daemon crash-looped. systemd 252 uses 0400, so Debian 12 was not affected.

The unit now copies the keystore credential to %t/sponsord/treasury-keystore.json at 0600 in ExecStartPre, inside a 0700 RuntimeDirectory=, and points the daemon at the copy. The decdn/devops Ansible role already does the same (decdn/devops#82).

Closes #36

Reviewer notes

  • The copy is still the encrypted keystore. The password stays in %d.
  • ExecStartPre runs as the same DynamicUser, so the copy is owned by the service user. RuntimeDirectory= is writable under ProtectSystem=strict, and it is removed when the service stops.
  • api-token and treasury-password stay in %d, because sponsord does not check their file modes. sponsord-onramp.service loads no keystore and is unchanged.
  • Not changed on purpose: the decdn keystore check. Loosening it for $CREDENTIALS_DIRECTORY would mean a change in decdn.

Verification

  • systemd-analyze verify deploy/systemd/sponsord.service on systemd 255 (255.4-1ubuntu8.17): the unit parses. The only warning is that /usr/local/bin/sponsord is not installed on this host.

  • markdownlint-cli2 on the changed Markdown: 0 issues.

  • The issue reporter verified the same unit snippet on systemd 252 and 255 with the real binary. It gets past credential loading, the permission check and decryption. I did not re-run that here.

  • No Rust changes, so the cargo items do not apply.

  • User-visible change: entry in the changed crate's crates/<dir>/CHANGELOG.md

  • PR title uses a type the pr-title check allows

🤖 Generated with Claude Code

…service

systemd 255 loads LoadCredential= files at 0440, and decdn's keystore
check refuses any group or other bit, so the reference unit crash-looped
on Ubuntu 24.04. Copy the keystore into a private RuntimeDirectory at
0600 in ExecStartPre and point SPONSORD_TREASURY_KEYSTORE there. The
copy is still the encrypted keystore; the password stays in %d.

Closes #36

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 5, 2026 10:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The unit change directly addresses #36 and is consistently documented.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes sponsord startup failures on systemd 255 by creating a private 0600 runtime copy of the keystore credential.

Changes:

  • Adds the runtime keystore copy to the systemd unit.
  • Documents the workaround.
  • Records the fix in the changelog.
File Description
deploy/​systemd/​sponsord.service Creates and uses the private runtime keystore.
docs/​operator.md Documents systemd credential handling.
crates/​sponsord/​CHANGELOG.md Records the systemd 255 fix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

… docs

The 0440 mode comes from systemd 254+ on Linux 6.4+, where credentials
live on tmpfs and access is granted through an ACL whose mask shows in
the group bits; it is not systemd 255 specifically, nor literally
group-readable. Say "some systemd versions (254+ on Linux 6.4+, seen on
255)", note that /run/sponsord is removed on stop, and tell operators
with an installed copy of the unit which lines to take.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thiras
thiras merged commit f86ef7e into main Oct 5, 2026
21 checks passed
@thiras
thiras deleted the fix/systemd-keystore-credential-mode branch October 5, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deploy/systemd/sponsord.service: daemon refuses its keystore credential on systemd 255 (0440)

2 participants