Secrets from env vars and files

It would be great if we could have secrets fed in from env vars. Right now n8n requires you to create a credential_entity thereby requiring you to manage your database contents like you manage your deployment secrets.

But IRL many of the deployment secrets are stored outside the database; you simply don’t want to pass along machine credentials with the backup files, since the backup files are handled by one type of person/role in a company, but secrets are handled by another.

Furthermore, having the credentials as env vars or files, would make it much easier to do gitops and save them as cipher text in the repo (for decryption by a k8s controller upon deployment)

It is not documented yet but environment variables would already be possible.
You can use the following in any credential parameter:

={{$env.SECRET_PASSWORD}}

The above example would resolve to the value of the environment variable SECRET_PASSWORD.

The parameter will then change afterward to an expression-field and the = will disappear.

No, that’s not a n8n secret. It’s the environment variable.

I’m talking about secrets that I can use in the “select secret” dropdown menu.

Are you sure this works as you’re describing @jan (running 0.104.2)? When running via standard Docker image I can only access {{$env.NODE_ENV}} in expressions but none of the other environment variables (even the explicitly defined ones in the config).

I checked the Docker and CLI readmes to see if there was a way to explicitly expose ENV to the node app at runtime and walked through the CLI package config.ts but didn’t come up with anything that worked. I also looked at the convict docs but that’s just loading config/args/env into the app config object. I may be missing something obvious but I’ve tried all the standard ways to pass ENV into node so I’m either having a Docker-specific issues or you have to explicitly expose these differently than simply exporting them in your shell env before starting the n8n.

No, nothing has to be especially exposed to Node.js and also is totally unrelated to convict but maybe there is a misunderstanding where the environment variables have to be set.
If you run n8n within Docker it is like running on a totally different machine. So it has its own set of environment variables. So if you set an environment variable in your terminal and then start n8n via Docker it will not be able to see it.

So you have to tell Docker like in the bellow example with the environment variable ‘MY_SECRET’.

docker run -it --rm \
	--name n8n \
	-e MY_SECRET=asdf \
	-p 5678:5678 \
	-v ~/.n8n:/home/node/.n8n \
	n8nio/n8n

Yup, I’m well versed in Docker/k8s and nodejs. I am definitely checking the ENV inside the running container and have tried the standard and alpine variants as well as a custom build. I also tried to explicitly pass in a variable when manually running the start command with node, but that yielded nothing in process.env either. I am comfortable working with node env and argv in other express-based frameworks which is even more confusing why this is being difficult.

I’ll can do a deeper debug later in the week, just checking things out right now. I really appreciate the help and the library is very intriguing so far!

Hi, I’m sorry but how to do ENV vars is off topic in this thread. This thread is about creating secrets from env vars.

It is probably not the right topic for a “Feature Request” (as this topic is) but generally do I think that such discussions, if related to the problem, can be helpful as very often they are the actual underlying problem. It does not seem to be the case here for @unfrgivn but maybe for other people in the future.

@jan @haf I am trying to accomplish the same as you, sorry if it seemed like I was diverting the conversation.

I am able to access ENV vars via both $env.MY_KEY in expressions and $evalutateExpression('{{$env.MY_KEY}}') in functions and now have absolutely no clue how to reproduce the behavior from the other day… Gremlins (or tired eyes)!

So to the original question, you can’t store the credential like a keychain, but you can store the individual pieces which I am doing. For instance:

ENV

DB_NAME=db1
DB_USER=user
DB_PASSWORD=password
API_KEY=12345

In the n8n credentials create a new DB connection and for each field enter an expression with the output being {{ $env.DB_USER }} or {{ $env.API_KEY }} etc… I even have fields that conditionally build the output for different DB names based on ENV values.

Now on the deployment side, use any external KMS, cloud secret or something like bitnami’s sealed secrets (https://github.com/bitnami-labs/sealed-secrets) if you want to commit them. And in your deployment/sts files you can load the ENV values used by your n8n credentials from these secrets. I don’t know if I missed a requirement in your use case, but working great on my end now.

Thanks again for taking the time @jan!

1 Like

You’re right. I faultily assumed the credential entities didn’t allow templating.

Weird! I’m facing the exact issue what @unfrgivn was facing! I’m able to access only $env.NODE_ENV and not any other variables. Is there anything specific which you did @unfrgivn to get it working?