Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Environment Variable Prefix (Instead if REACT_APP_) #2865

Closed
goldcaddy77 opened this issue Jul 27, 2017 · 24 comments
Closed

Custom Environment Variable Prefix (Instead if REACT_APP_) #2865

goldcaddy77 opened this issue Jul 27, 2017 · 24 comments

Comments

@goldcaddy77
Copy link

At my company, we have standard environment variable naming conventions. create-react-apps hard-coded default - REACT_APP_ does not adhere to these. It would be nice to be able to configure these by either:

  1. Supplying config in package.json or
  2. Passing a flag to the react-scripts command
  3. Setting another environment variable? (perhaps too meta)

(1) and (2) would also allow running multiple create-react-app projects with global environment variables as well (as opposed to using the .env files)

Are others running into this?

@gaearon
Copy link
Contributor

gaearon commented Jul 27, 2017

To be honest this sounds a bit too esoteric to add as a configuration flag or environment variable. I understand where you’re coming from, but I don’t think supporting this is worth the complexity (both in implementation, testing, and in explaining how it works).

@goldcaddy77
Copy link
Author

Wow, 2 minute SLA... impressive! Makes sense - if you're 2865 issues in and this is the first time it's come up, it's probably somewhat of an edge case. I'll just write something that copies MY_PREFIX_ -> REACT_APP_ in my npm scripts or something - doing everything we can to not eject. :)

@gaearon
Copy link
Contributor

gaearon commented Jul 27, 2017

Sounds good. Let’s keep it open for a little while but unless there is overwhelming support I don’t think we’ll get to doing this.

@heyimalex
Copy link
Contributor

It's not too bad to do without ejecting.

const spawnSync = require("child_process").spawnSync;

const MY_PREFIX = /^MY_PREFIX_/i;

const transformedEnv = Object.keys(process.env)
  .filter(key => MY_PREFIX.test(key))
  .reduce((env, key) => {
    const craKey = key.replace(MY_PREFIX, "REACT_APP_");
    env[craKey] = process.env[key];
    return env;
  }, {});

spawnSync("npm", ["run", "build"], {
  shell: true,
  stdio: [0, 1, 2],
  env: transformedEnv
});

@rafales
Copy link

rafales commented Aug 1, 2017

@goldcaddy77 you can fork create-react-app and make modifications needed for your company. It's not ideal as it will require a little bit of maintenance.

@miraage
Copy link

miraage commented Aug 8, 2017

I would like to mention that require('dotenv').config() returns all parsed keys. I think it might help to get rid of these prefixes.

https://github.com/motdotla/dotenv/blob/v4.0.0/lib/main.js#L66

// EDIT

The drawback is that we can not import variables defined outside the app (e.g. in build scripts, etc..)

@sandys
Copy link

sandys commented Aug 29, 2017

hi guys,
this is a requirement for us as well. We use kubernetes and we inject a lot of variables. Please note that in all other nodejs frameworks, process.env works homogenously - it picks up environment variables.

I concur with the original request to have another variable (say process.osenv) to make available all of these in both the javascript code as well as the index.html. This will be super useful to all of us who have server environments that may be restricted.

It would be awesome if this were available.

@rafales
Copy link

rafales commented Aug 29, 2017

REACT_APP_ prefix is there for a reason. Otherwise it'll be really easy to shoot yourself in the foot (leak sensitive env variables into the JS file).

@miraage
Copy link

miraage commented Aug 29, 2017

I think it would be nice to have something like array appEnvVars in package.json.
Only these variables along with NODE_ENV and PUBLIC_URL will be passed to the application.

@sandys
Copy link

sandys commented Aug 29, 2017

@rafales thanks for replying. we are not proposing putting these variables into the env.

what we are requesting is that a lot of us already have environment variables injected using other infrastructure tools. So in all other containers I have env variable "AWS_SECRET". But only for my create-react-app container, I need to somehow pass "REACT_APP_AWS_SECRET" . Or in my top level secrets store (like Hashicorp Vault), I need to duplicate all my environment variables.

I'm not asking to change any of your standard tooling - if you could please give me an additional variable process.osenv , I can then change my application code to comply with my deployment environment.

@gaearon
Copy link
Contributor

gaearon commented Aug 29, 2017

Replace react-scripts start and similar in package.json with your own custom scripts that first load and "redirect" necessary variables, then delegate to react-scripts. This is just code, you can do anything you want there.

@sandys
Copy link

sandys commented Aug 29, 2017

@gaearon i dont think that works. Atleast I tried - create-react-app deletes all existing values in process.env . Or are you suggesting I create my own process.osenv ?

This is an interesting example - https://github.com/mikehanssen/create-react-app-buildpack#runtime-configuration from Heroku. They have actually created a plugin that creates a different variable that they recommend we use on Heroku rather than the create-react-app ones.
this is because Heroku does secrets management using "heroku config:set". So either I change all my other apps to play nice with create-react-app semantics ... or i just use heroku's plugin.

this is available only on heroku though.

@rafales
Copy link

rafales commented Aug 29, 2017

@sandys passing something like AWS_SECRET to the javascript output file is a bad idea, that's why the prefix exists. What @gaearon suggests is for you to create a separate file, eg. build.sh and explicitly re-export variables you need with REACT_APP_ prefix, for example:

#!/bin/bash
export REACT_APP_PAGE_NAME = $PAGE_NAME
exec react-scripts build "$@"

And change build script in package.json so it points to your build.sh file.

@sandys
Copy link

sandys commented Aug 29, 2017 via email

@rafales
Copy link

rafales commented Aug 29, 2017

@sandys actually in the heroku link you provided - they also require REACT_APP_ prefix (otherwise all your secrets like database password would be leaked).

@gaearon
Copy link
Contributor

gaearon commented Aug 29, 2017

In fact strongly so - for several business segments, committing any secret
to disk (even as a build output) is a criminal offence.

This is exactly why we force you to be explicit. Anything you include in JS will be written to disk and shipped to your users (unless you're only using variables in conditions and are extremely careful). This would have been dangerous without explicit opt-in.

i dont think that works. Atleast I tried - create-react-app deletes all existing values in process.env

I assure you it doesn’t. How can it possibly know which ones to delete? If you follow my suggestion and create a script that spawns the other script with different variables, it’s indistinguishable from passing them yourself.

If this is a strong philosophical stand

It’s not. It is purely practical. It is a very real security hole and attack vector to pass any variables through. An rogue npm package (perhaps a transitive dependency) can embed process.env.<whatever secret> in its code and thus trick you into shipping secrets in your bundle.

Explicitness helps protect against that. But if you disagree you can always run the process yourself and pass anything to it, like I described above. Everything you can do from the console, you can do from a Node script. Including passing variables.

@gaearon gaearon closed this as completed Aug 29, 2017
@sandys
Copy link

sandys commented Aug 29, 2017 via email

@gaearon
Copy link
Contributor

gaearon commented Aug 29, 2017

Create React App is always statically compiled. I can't say about Heroku but the whole principle of CRA is that it produces a HTML/CSS/JS bundle that is shipped to your users. Your code runs in the browser, so if it uses variables, they have to be available somehow :-)

@sandys
Copy link

sandys commented Aug 29, 2017 via email

@gaearon
Copy link
Contributor

gaearon commented Aug 29, 2017

You have an escape hatch as I noted—create a Node script that spawns react-script start and other commands with the rewritten environment variables.

@heyimalex
Copy link
Contributor

@sandys I really feel like you're not getting the security implications? Literally zero "secrets" should be needed by your frontend code. If they are, you are leaking them to your end users. The react-scripts build command creates a static bundle of files that is ultimately shipped to your end users. The javascript code that is generated runs in their browser. If you've embedded any secrets, they are accessible to your users.

Because you likely don't want to leak every private key you've got stored in an env var, creact-react-app makes you white-list the things you actually need for the build.

@sandys
Copy link

sandys commented Aug 29, 2017 via email

@heyimalex
Copy link
Contributor

@sandys I just don't understand why you would need to inject anything from vault into your build? If it is being injected, then it shouldn't be a secret, and if it's not being injected, then it doesn't need to be prefixed.

@goldcaddy77
Copy link
Author

@sandys are you using the term "secrets" in lieu of "config"? For instance, would you call MY_APP_API_ENDPOINT a "secret"? If so, this could be the disconnect.

@lock lock bot locked and limited conversation to collaborators Jan 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants