Using valid env vars names for .npmrc #12746
theoephraim
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
First off, thanks for the env-variables-in-repository-npmrc post and for closing the
${ENV}-in-repo-file exfiltration hole. Locking expansion to trusted sources is the right call. This is a follow-up on the part you flagged as open to suggestions: the suggested env-var form doesn't work in most places people actually inject secrets.The problem with the current advice
The canonical config key lives in the variable name:
The name contains
/,:, and., so as the post notes,exportandNAME=valuereject it and you needenv "...=...". Butenv-prefixing only helps in an interactive or scripted shell. It does nothing for the places that inject secrets by name, which is most of CI/CD:ENV/--env, Compose, Kubernetes SecretsEnvironment=.envfiles and secret managersAll of those require a POSIX-valid identifier:
[A-Za-z_][A-Za-z0-9_]*. So the current guidance quietly excludes declarative injection entirely.Root cause
The pain comes from putting the registry URL (which carries
/ : . @) into the variable name. Any fix that keeps the key in the name forces an ugly, lossy escaping scheme (base64,:-to-__, etc.).The key is data. Put it in the value, and the name becomes a fixed, identifier-safe label.
Proposal: coupled records in the value
Primary form: one npmrc line per variable
Parse rule: collect every
PNPM_CONFIG_NPMRC_<suffix>variable, treat each value as a line of npmrc, and merge them using the existing parser.Why this shape:
~/.npmrc, delivered inline. There is no file path that a cloned repo could point back at itself, which is the lingering weakness of thePNPM_CONFIG_NPMRC_AUTH_FILE=.npmrclast resort.Convenience form: one variable, whole npmrc
For "one secret store hands me everything":
JSON could be auto-detected as an alternative encoding to avoid multiline quoting in environments like Docker
ENVthat mangle newlines. The two forms should merge, so you can mix "all at once" and per-line shards.Details that matter
0..Nand stop at the first gap, or a credential silently vanishes and fails in confusing ways. Allowing non-numeric suffixes (_NPMJS,_MYCO) sidesteps numbering entirely.${ENV}expansion on it, or the original hole reopens via nesting.Alternative: grouped field variables
If individual fields are preferred over npmrc-line values, a grouped form also works:
The handle (
NPMJS,MYCO) is arbitrary and identifier-safe. This reads nicely and maps onto secret stores that emit one secret per variable. Two caveats worth knowing:@scope:registryis a second keyspace (npm scope to URL, not a credential), so a group needs an extra scope field and multi-scope handling.Because of (1), I'd lead with the coupled value form and offer grouped fields as a secondary option for people who want individual fields.
Where varlock fits
Whatever shape you pick, in some scenarios the sensitive token may still be sitting in a plaintext file, vulnerable to supply chain attacks. varlock is built for exactly this last mile, keeping it out of plaintext (either behind encryption or using plugins to load from external vaults) and injecting it securely. It also adds log redaction and extra guardrails, and can help with the expansion/composition into the format pnpm expects. For example, a .env.schema which sets the necessary vars:
We could make some changes to make it possible to inject into the environment as is it currently supported, but I think it's better to migrate to supporting standard env vars.
Happy to open a PR sketching the parser changes for the per-line form if there's interest.
Beta Was this translation helpful? Give feedback.
All reactions