I\'m attempting to load an RSA private key into my nodejs application using environment variables, but the newlines seem to be being auto-escaped.
For the following, ass
If you're using dotenv: We solved it this way, with newlines and JSON.parse (this allows any backslash escaped chars within the string, not just \n
):
in .env:
MY_KEY='-----BEGIN CERTIFICATE-----\nabcde...'
in server.ts:
myKey = JSON.parse(`"${process.env.MY_KEY}"`), // convert special chars
See thread: https://github.com/motdotla/dotenv/issues/218
Node.js does correctly reflect environment variables that have embedded actual newlines, as the following bash
snippet demonstrates:
$ PRIVATE_KEY=$'ab\ncde' node -p 'process.env["PRIVATE_KEY"].indexOf("\n")'
2 # 0-based index of the (first) actual newline char. in env. var. 'PRIVATE_KEY'
Note that $'...'
is a special type of bash
string in which escape sequences such as \n
are expanded, so in the command above PRIVATE_KEY
is indeed defined with 2 lines and passed as an environment variable to node
(simply by prepending the variable assignment to the command to invoke, which is a standard feature in POSIX-like shells).
In fact, Node doesn't interpret the value of environment variables in any way (which is the right thing to do).
It must be that your PRIVATE_KEY
variable doesn't contain actual newlines, but \n
literals (a \
char. followed by char. n
).
If the assignment command PRIVATE_KEY="..."
in the question is a shell command, that would explain it: In POSIX-like shells such as bash
, \n
inside a "..."
string is left as-is.
"..."
strings do interpolate escape sequences such as \n
, which is why passing such a string directly to console.log()
indeed outputs newlines; e.g., node -e 'console.log("ab\ncde")'
indeed outputs 2 lines.PRIVATE_KEY="ab\ncde" node -p 'process.env["PRIVATE_KEY"]'
(literally) outputs ab\ncde
, showing that \n
was retained as a literal.
You have two options to fix your problem:
Preferably, define your environment variable with actual newlines to begin with - see below.
Alternatively, if you do not control how the environment variable is set, expand the \n
literals to actual newlines in your Node.js (JavaScript) code: see Adriano Godoy's helpful answer.
To define PRIVATE_KEY
with actual newlines in POSIX-like shells, use one of the following techniques:
bash
, ksh
, zsh
: use an ANSI C-quoted string:export PRIVATE_KEY=$'-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----'
dash
(and from any shell script that uses sh
):export PRIVATE_KEY="$(printf %s '-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----')"
Alternatively, for better readability you can use a command substitution with a here-document:
export PRIVATE_KEY="$(cat <<'EOF'
-----BEGIN RSA PRIVATE KEY-----
...
...
-----END RSA PRIVATE KEY-----
EOF
)"