Skip to content

feat(api): load API key through systemd credentials with env fallback#2150

Open
blackxored wants to merge 2 commits intoseerr-team:developfrom
blackxored:feat/systemd-creds
Open

feat(api): load API key through systemd credentials with env fallback#2150
blackxored wants to merge 2 commits intoseerr-team:developfrom
blackxored:feat/systemd-creds

Conversation

@blackxored
Copy link

Description

On Linux systems, be a well-behaved daemon and prefer systemd credential api-key if passed to the service. This is done through a file, access is checked by the kernel, and there's no process inheritance, TL;DR is more secure than env vars. See: systemd Credentials.

It would still fallback to the API_KEY env var as there's no need for this to be a breaking change.

To-Dos

  • Disclosed any use of AI (see our policy)
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

@blackxored blackxored requested a review from a team as a code owner November 13, 2025 23:38
If provided, API key is read through systemd credential `api-key` passed
to the service and preferred, will fallback to environment var if not
present.

See: https://systemd.io/CREDENTIALS systemd.system-credentials(7)
@M0NsTeRRR
Copy link
Member

Hi @blackxored,

Instead of creating a new apiKeyFromEnvOrCred function, could you move the stringOrReadFileFromEnv function from server/datasource.ts to server/utils/env.ts? This way, we can reuse the same logic where needed.

Additionally, since this feature is similar to Docker secrets, it would be great to support both approaches simultaneously. By default, Docker secrets are mounted at /run/secrets. I think adding ENV CREDENTIALS_DIRECTORY="/run/secrets" to the Dockerfile would be enough to make them work out of the box. What do you think?

Reference: Docker Secrets Documentation

@benja1006
Copy link

I agree, it would work nicely to place the systemd credentials into /run/secrets, then we can access them using _FILE appended to the DB username, password and name. This would integrate cleanly into the default postgres behavior as well

@M0NsTeRRR
Copy link
Member

Any news @blackxored ?

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

This PR is stale because it has been open 30 days with no activity. Please address the feedback or provide an update to keep it open.

@github-actions github-actions bot added the stale label Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants