How to inject a secret into the environment via a systemd service definition?
I want to inject a secret (password) into the environment for a systemd service, using either Environment=
or EnvironmentFile=
.
What I tried (and what failed):
1. Environment
Environment=password=$(op read op://Vault/Item/password)
However, since such service is not a script, the password will be set to this literal text; the command itself, not its result...
2. EnvironmentFile
As an override:
[Service] ExecStartPre=op inject -i /etc/default/myservice.tpl -o /etc/default/myservice ExecStartPost=rm /etc/default/myservice
with this additional line in etc/default/myservice.tpl
:
password=op://Vault/Item/password
However, apparently the environment file is read before executing the ExecStartPre
command...
Any tips on how I can inject the password into the environment for this service?
1Password Version: CLI 2.0.0
Extension Version: n/a
OS Version: Raspberry Pi OS Bullseye
Comments
-
Hey @XIII, thanks for reaching out to us!
I think another solution here might be to pass the secret references as environment variables, and to use
op run
to prefix your ExecStart Command. I played a bit with this with the manual authentication process, hardcoding my session token, and managed to get something like this working:[Service] User=horia Environment="OP_CONFIG_DIR=/home/horia/.config/op" Environment="VAR=op://test-vault/docker/username" Environment="OP_SESSION_<my_id>=<my_session_token>" ExecStart=/usr/bin/op run --no-masking -- bash -c 'echo $VAR'
I assume this can be ported over to the biometric authentication process as well, but, in case you encounter any hurdles, let us know such that we can take another look, in more detail!
Best,
Horia0 -
That's exactly what I (already) did... (and that indeed works!)
However, this service's
ExecStart
is pretty complicated; I'd rather not overwrite that (since I manually have to copy the original one each time the author changes it).0 -
Turns out this does not work as good as I hoped, I always get these errors when I try to restart a service:
Apr 10 17:06:32 pi systemd[1]: my.service: Found left-over process 1944 (op) in control group while starting unit. Ignoring. Apr 10 17:06:32 pi systemd[1]: This usually indicates unclean termination of a previous run, or service implementation deficiencies.
How to fix this?
0 -
Might be because this service was using this (which is not recommended):
KillMode=process
Removed that line (to get the default mode
control-group
) and that seems to work better (so far).0 -
I am glad you got this working. Is there anything else that we can help with, here?
Looking forward to hearing from you!
Best,
Horia0 -
Hi @XIII ! Another option is to write the secret into a private temp file and read it from there into your app. This is secure because systemd creates private temp files in a separate application-specific namespace. In fact by some accounts it's even more secure than environment variables, which can be queried pretty easily from other processes!
My suggestion would look like:
[Service] ExecStartPre=/path/to/op read op://Vault/Item/password >/tmp/item ExecStart=/some/app # reads file /tmp/item contents into memory as password PrivateTmp=yes # Enforces creating /tmp/* in private namespace for the service
0 -
Thanks for sharing @sKCZWuLeiGrwVP!
0