Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/numtide/systemd-vaultd

Provide access to vault secrets to systemd services
https://github.com/numtide/systemd-vaultd

buildbot-numtide nix nixos secrets vault

Last synced: 5 days ago
JSON representation

Provide access to vault secrets to systemd services

Awesome Lists containing this project

README

        

# systemd-vaultd - load vault credentials with systemd units

> Mostly written in a train

- Jörg Thalheim

systemd-vaultd is a proxy between systemd and [vault agent](https://vaultproject.io).
It provides a unix socket that can be used in systemd services in the
`LoadCredential` option and then waits for vault agent to write these secrets in
json format at `/run/systemd-vaultd/.service.json`.

This project's goal is to simplify the loading of [HashiCorp
Vault](https://www.vaultproject.io/) secrets from
[systemd](https://systemd.io/) units.

## Problem statement

Systemd has an option called `LoadCredentials` that allows to provide
credentials to a service:

```conf
# myservice.service
[Service]
ExecStart=/usr/bin/myservice.sh
LoadCredential=foobar:/etc/myfoobarcredential.txt
```

In this case systemd will load credential the file
`/etc/myfoobarcredential.txt` and provide it to the service at
`$CREDENTIAL_PATH/foobar`.

It's handy because it bypasses file permission issues.
/etc/myfoobarcredential.txt can be owned by root, and the unit run as a
different or dynamic user.

While vault agent also supports writing these secrets, a major issue is that
the consumer service may be started before vault agent was able to retrieve
secrets from vault. In that case, systemd would fail to start the service.

## The solution

In order to do so, I wrote a `systemd-vaultd` service which acts as a proxy
between systemd and vault agent that is running on the machine. It provides a
unix socket that can be used in systemd services in the `LoadCredential`
option and then waits for vault agent to write these secrets at
`/run/systemd-vaultd/.json`.

We take advantage that in addition to normal paths, systemd also supports
loading credentials from unix sockets.

With `systemd-vaultd` the service `myservice.service` would look like this:

```conf
[Service]
ExecStart=/usr/bin/myservice.sh
LoadCredential=foobar:/run/systemd-vaultd/sock
```

vault agent is then expected to write secrets to `/run/systemd-vaultd/` in json format.

```
template {
# this exposes all secrets in `secret/my-secret` to the service
contents = "#{{ with secret \"secret/my-secret\" }}{{ .Data.data | toJSON }}{{ end }}"

# an alternative is to expose only selected secrets like this:
# contents = <