Angular 6, should I put secret environment variables in environment.ts file?
Asked Answered
L

1

31

There are two sub-questions:

  1. Should I put secret environment variables in the environment.ts file?

  2. The process variable shim is gone. If I use it, tsc will throw an error: Cannot find name 'process'.

Here is my thing:

About Q1: I don't think put secret environment variables in environment.ts file is correct. Because these files will be a push to source code management, like GitHub, GitLab, bitbucket. It's not safe. So I think secret environment variables should be passed through process.env, like process.env.ACCESS_TOKEN, or, if use docker-compose, should put the secret environment variables in .env file and add this file to .gitignore file.

About Q2: If I use Heroku to set up my environment variables, it depends on the process variable. Now, angular6 get rid of the shim of process, How can I work with Heroku? Also, using docker-compose pass environment variables through .env file depends on process too.

And if use .env file for docker-compose, there is a new question come out: How to pass variables in .env file to angular6 environment.ts file

update 1:

Here is a case:

First, there is no back-end

I use GitHub API and another open API, and there is an environment variable named access_token, If I put this in the environment.ts file and push my front-end source code to Github, Github will detect the secret information and give me a warning, they say:

You should not put the GitHub access token in your source code and push it to repo, so they will revoke my access token.

So I want to use process.env.ACCESS_TOKEN, but the process variable shim is gone in Angular6, how can I solve this? Should I add environment.ts file to the .gitignore file or what?

update 2

Here is another case

Continue with update 1. Now, I add docker-compose.yaml and Dockerfile to run my front-end app in the docker container.

Here is the workflow:

  1. Write Dockerfile, run npm run build command and copy ./build directory to nginx static file directory of docker container. the ./build directory contains index.html, bundle.js file and so on.

  2. Put access_token and other secret environment variables into .env file.

  3. Run docker-compose up to run my app in a docker container.

I think this workflow is solid. No need back-end service, the secret environment variables in .env and .gitignore contains .env file, so it will not be pushed to Github repo.

But, the key point is process shim is gone. I can't get environment variables through process.

update 3

I think my question focus on front-end app development phase. I continue to use above case to explain.

For production ready, the workflow is:

  1. Make a back-end service for github oauth, when the oauth workflow is done. Back-end service send access_token to front-end.

  2. front-end login successfully, get the access_token from back-end service and store it in localStorage or cookie. Don't need get access_token from process.env

But for development phase, Front-end and back-end development are separated for the general situation. So, Front-end should not depend on the back-end service.

And I don't want to build the whole big system for the beginning.

So I think the question is:

Where to store secret environment variables and how to get within Angular6 front-end application code? Several situations need to be considered:

  • Work with PaaS Heroku config vars
  • Dockerized(docker-compose, Dockerfile), .env file.
  • Without back-end service.
  • Add the environment variables file to .gitignore, don't push to SCM(Github, GitLab and so on)
Lasagne answered 24/7, 2018 at 3:7 Comment(2)
Is your website designed to be public? Should access token be public information? If yes, then build it into the JS code; otherwise hide it in a back-end server. You can hide nothing in front end.Iota
Putting sensitive data in the source code is not a good idea at all (for a security measure), take a look on how to set external env variables smaillns.medium.com/…Disorientate
V
35

TL; DR

You should not treat environment.ts as something similar to process.env.

The name is similar but the behaviour is absolutely not. All the settings from environment.ts will directly go to your code. That's why it is not secure to put secrets to environments.ts in any way.

The browser alternatives to environment variables (process.env) are

  • sessionStorage: behaves like export VAR=value
  • localStorage: behaves like export VAR=value but put into your .bash_profile and is persistent across sessions
  • indexedDB: same as localStorage with only difference its asynchronous
  • cookies: does not really look like process.env, but still in some cases can send the secrets automatically to some backends
  • backend: it is always an option to get secrets from backend, asynchronous

Long version

There is no such a thing as a secret in the client side application. Since your code in the browser will be able to get those variables, everybody will be able to get those variables in the runtime.

That means, all libraries you explicitly or implicitly use, user's browser extensions and anybody who is able to sniff your / your user's traffic - all they will get your secrets quite easily.

It does not matter how you pass it. Through process.env or environment.ts, all will end up in the generated main.js file where they are so much not secret anymore that the furhter discussion is actually useless.

Answer to updated part 1:

If access_token is your (or your synthetic user) token, then you have two options:

  1. Write a backend service that pushes the code on behalf of this Github user. That means the token will be stored in the environment variable on a backend side, which is a very much appropriate way of doing stuff
  2. Ask your user to enter the token for every push or ask it once and store it in a localStorage. This make sense only in case when every user has its own / different token

Answer to updated part 2:

You can build a docker around your frontend, run it within a kubernetes cluster inside a virtual machine which is hosted on the most secure server in the world, it will not make your token secure if you put it as angular environment variable because what is public cannot be secret.

You seem to be not understanding the main point: GitHub gives you an error and does not allow to push the code, you should already be grateful that it finds a problem in your architecture. If you want to solve the problem then use the solutions above. If you want to simply bypass the validation of GitHub and you don't care about the security then simply split your token string into two pieces and store it apart and GitHub will not be able to find it.

Answer to updated part 3:

You can perform GitHub's Oauth2 requests directly from your frontend. Every of your users should have an account there and that would solve all your problems. That's actually the same what was proposed as a solution #2.

If you go with solution #1 with a backend, for development purposes just pre-set up the cookie or use localStorage.setItem('your-token-here'). This is way more than enough for development purposes.

Viquelia answered 24/7, 2018 at 3:26 Comment(5)
yeah, I know this, no matter through process.env or environment.ts , after compile and build, the final bundle.js file will contain every environment variables at runtime, even the secret environment variables.Lasagne
Then they are not secret. That’s the point. You can store them in git or show it to the user in a pop up right away - it is nearly the same level of security. Front end code is not a place for any secret variable.Viquelia
Reply Answer to updated part 2:, Oh no, I just want to develop an Angular 6 front-end app. Kubernetes, docker-machine...These things are production ready things. That adds too many things. Just for developing an Angular 6 front-end? NO! Even perform GitHub's Oauth2 requests directly from your frontend, that's too heavy either. Like I said, I don't want to build a whole big system at beginning. Just for secret environment variables? NO! The last advice is simple and good enough. Store my access_token to localStorage directly.Lasagne
the kubernetes thing was sarcasm :) Please check the updated top of the answer. I think that's the main thing we discussViquelia
looks like the only solution is having a backend? I am on the same boat. I have a tool that makes api call to bitbucket and jira. Currently I am hardcoding username/password in the code but I want to move it to .env...the tool will not need to ask for login and it will use my read only credentials...Particularism

© 2022 - 2024 — McMap. All rights reserved.