dotnet / dotnet/dev-proxy

Support environment variable placeholders in configuration files

Open
#1,667 1 comment 0 reactions 0 assignees View on GitHub
needs peer review
Dominant language
C#
Stars
832
Forks
89
Avg merge
12h 1m
Merged PRs (30d)
23

Description

## Summary

Dev Proxy config files (devproxyrc.json and plugin config files like CrudApiPlugin API files) don't support environment variable placeholders. This means values that vary per environment — like Entra app client IDs or tenant IDs — must be hardcoded in config files, or users need to write scripts to patch them before running Dev Proxy.

## Example: the workaround today

In the [da-ristorante-api-devproxy-entra](https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/da-ristorante-api-devproxy-entra) sample, we need to inject `ENTRA_APP_CLIENT_ID` and `ENTRA_APP_TENANT_ID` into the CrudApiPlugin API files. Because Dev Proxy doesn't support this, the sample includes a [Node.js script](https://github.com/pnp/copilot-pro-dev-samples/blob/main/samples/da-ristorante-api-devproxy-entra/scripts/update-devproxy-config.js) that reads `.env.local` and rewrites the JSON config files before each run.

The config file looks like this:

```json
{
"entraAuthConfig": {
"audience": "",
"issuer": "https://login.microsoftonline.com//v2.0"
}
}
```

And the script manually replaces those placeholders with values from env files. This works but adds friction — extra tooling, an extra build step, and mutated config files that can accidentally get committed.

## What I'd like to see

Support for environment variable references in config files, for example:

```json
{
"entraAuthConfig": {
"audience": "${ENTRA_APP_CLIENT_ID}",
"issuer": "https://login.microsoftonline.com/${ENTRA_APP_TENANT_ID}/v2.0"
}
}
```

When Dev Proxy loads a config file, it would resolve `${VAR_NAME}` placeholders against environment variables (or the `env` config section).

## Why this seems feasible

Dev Proxy already has closely related infrastructure:

- **Path tokens**: `~appFolder` and `~dataFolder` are resolved via `ProxyUtils.ReplacePathTokens` when loading config/plugin paths
- **`@dynamic` tokens**: used in mock responses and rate limiting headers, resolved at runtime
- **`ProxyUtils.ReplaceVariables`**: a general-purpose string replacement utility that replaces variable references in a string given a dictionary of values
- **`IProxyConfiguration.Env`**: the proxy configuration already exposes a `Dictionary Env` property
- **`MinimalPermissionsPlugin`** already uses `ProxyUtils.ReplaceVariables(fileContents, ProxyConfiguration.Env, v => $"{{{v}}}")` to resolve `{VAR}` placeholders in OpenAPI spec files

The pattern is already proven in plugins — it just needs to be applied when loading configuration files too.

## Benefits

- No more wrapper scripts to inject environment-specific values
- Config files stay clean and committable (no secrets, no environment-specific values)
- Consistent with how other tools handle this (Docker Compose, Azure Pipelines, GitHub Actions, etc.)
- Works naturally with `.env` files and CI/CD environments

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.