Skip to Content

Using Environment Variables in Your WunderGraph Application

Published: 2022-05-23

Using Environment Variables in Your WunderGraph Application comes with a bit of complexity. This chapter helps you understand the different options and how to use them.

The difference between wundergraph.config.ts and wundergraph.server.ts#

To start off, it's important that you understand the difference between wundergraph.config.ts and wundergraph.server.ts.

The purpose of the file wundergraph.config.ts is solely to generate the configuration for your WunderGraph application. That is, this file is used to generate the wundergraph.config.json file in the generated folder.

If you use secrets like API keys or passwords statically within the wundergraph.config.json file, they will be statically embedded into the wundergraph.config.json. If you're committing this file to a git repository, your secrets might be exposed to the audience of this git repository.

When we say "statically" we mean using either a String of the secret or process.env.MY_SECRET. Either approach will lead to the same result, the secret will be embedded into the wundergraph.config.json.

On the contrary, the file wundergraph.server.ts is used at runtime. You can safely use process.env.MY_SECRET in this file or any of its imports.

Using Environment Variables in wundergraph.config.ts#

As we've described above, using Environment Variables in your wundergraph.config.ts file comes with a bit of complexity as you might be leaking secrets into your wundergraph.config.json file.

For that reason, we'd like to explain a few best practices.

1. Don't use Strings for secrets in your wundergraph.config.ts file#

Here's an example of how NOT to do it:

configureWunderGraphApplication({
...
authentication: {
cookieBased: {
providers: [
authProviders.openIdConnect({
id: "keycloak",
clientId: "integration-demo",
clientSecret: "super-secret-string",
issuer: "https://lemur-9.cloud-iam.com/auth/realms/wundergraph-staging",
}),
],
authorizedRedirectUris: [
"http://localhost:3000"
]
},
},
});

The issue with this approach is that the client secret is embedded into the wundergraph.config.json file. If you git ignore the generated directory, this might be okay, otherwise you're exposing the secret to the repository audience.

Another way of creating the same issue is to use process.env in your wundergraph.config.ts file.

2. Use process.env in your wundergraph.config.ts file#

Here's an example that looks not suspicious:

configureWunderGraphApplication({
...
authentication: {
cookieBased: {
providers: [
authProviders.openIdConnect({
id: "keycloak",
clientId: "integration-demo",
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET,
issuer: "https://lemur-9.cloud-iam.com/auth/realms/wundergraph-staging",
}),
],
authorizedRedirectUris: [
"http://localhost:3000"
]
},
},
});

However, you're still embedding the secret into the wundergraph.config.json file.

3. Use new EnvironmentVariable() in your wundergraph.config.ts file#

Fields that expect a secret, e.g. setting Auth token, etc... accept an InputVariable instead of just a plain string. InputVariables are placeholders for environment variables. It's possible to pass a string, but you can also pass an object of type EnvironmentVariable.

What's special about the EnvironmentVariable object is that it will not embed the value from the environment directly into the wundergraph.config.json file. Instead, it will generate a dynamic variable, like a reference, that will pick up the required value from the environment when you run wunderctl start.

This means, you can safely publish the generated wundergraph.config.json file to a git repository without leaking any secrets. Additionally, the secret doesn't have to be present in the environment when generating the configuration. As a result, the configuration generation process is fully independent of the environment.

Let's have a look at an example using this pattern:

// wundergraph.config.ts
import {
EnvironmentVariable,
} from "@wundergraph/sdk";
configureWunderGraphApplication({
...
authentication: {
cookieBased: {
providers: [
authProviders.openIdConnect({
id: "keycloak",
clientId: "integration-demo",
clientSecret: new EnvironmentVariable("KEYCLOAK_CLIENT_SECRET"),
issuer: "https://lemur-9.cloud-iam.com/auth/realms/wundergraph-staging",
}),
],
authorizedRedirectUris: [
"http://localhost:3000"
]
},
},
});

In this case, the wundergraph.config.json will only contain a placeholder for the secret. It's safe to commit this file to a git repository.

When you run wunderctl start, the placeholder will be filled from the environment.

Using EnvironmentVariables in wundergraph.server.ts#

As we've described above, the wundergraph.server.ts file will be used at runtime to implement the middleware. It has also some influence on the configuration, e.g. what hooks are configured, but it will not be used to configure secrets etc...

This means two things essentially. For one, you should use process.env in your wundergraph.server.ts file. Second, you should NOT use new EnvironmentVariable() in your wundergraph.server.ts file. Using EnvironmentVariable objects in your wundergraph.server.ts file will not work at all.

Using .env files to override Environment Variables#

By default, environment variables will be picked up from the environment when you run wunderctl start. Additionally, you can override the environment variables by using a .env file. By default, the .env file will be loaded from the current working directory.

It's also possible to override this, using the --env flag.

Example:

wunderctl start --env ./production.env

Conclusion#

Here's the tldr version of the above. I hope it helps you to make the right choices when using environment variables with WunderGraph.

  1. Use EnvironmentVariable in your wundergraph.config.ts file to load environment variables dynamically when running wunderctl start.
  2. Don't use Strings for secrets in your wundergraph.config.ts file.
  3. Don't use process.env in your wundergraph.config.ts file.
  4. Use process.env in your wundergraph.server.ts file.
  5. Don't use new EnvironmentVariable() in your wundergraph.server.ts file.
  6. Use .env files to override environment variables.

Product

Comparisons

Subscribe to our newsletter!

Stay informed when great things happen! Get the latest news about APIs, GraphQL and more straight into your mailbox.

© 2022 WunderGraph