> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/cli/guides/secrets/replace-env-files.md).

# Take the passwords out of a .env file

Replace the passwords in your .env files with devo:// references, commit the file, and run your app with devo secret run --env-file.

A `.env` file is convenient, but it's also the file most likely to leak a password: copied to a ticket, pushed by mistake, or shared with a new teammate. With Devolutions CLI, the file keeps its shape and its variable names, but each secret becomes a `devo://` reference. The file is then safe to commit, and the values reach your app only when it starts.

## Replace the values with references

1. Open your `.env` file.
2. For each secret, find its reference. See [Find the reference to a secret](/cli/guides/secrets/find-a-reference.md).
3. Replace the value with the reference. Leave the other values as they are.

```bash
# Database
DB_HOST=db.internal.example
DB_USER=devo://ws/<workspace-id>/vault/<vault-id>/entry/<entry-id>/field/username
DB_PASSWORD=devo://ws/<workspace-id>/vault/<vault-id>/entry/<entry-id>/field/password

# A reference can also sit inside a longer value
DATABASE_URL="postgres://app:{{ devo://ws/<workspace-id>/vault/<vault-id>/entry/<entry-id>/field/password }}@db.internal.example/app"
```

{% hint style="info" %}
Prefer canonical references (`devo://ws/…`) in files you commit. They keep working when an entry is renamed, and they resolve against the workspace that owns them, whatever context is current.
{% endhint %}

## Run your app with the file

```bash
devo secret run --env-file .env -- npm start
```

Devolutions CLI reads the file, resolves every reference it contains, and starts your app with all the variables of the file in its environment: the resolved secrets and the plain values. Resolved values are hidden in what the app prints, as with any `devo secret run`. See [Run a command with its secrets](/cli/guides/secrets/run-with-secrets.md).

You can combine `--env-file` with `--env-ref`. If a variable of the file has the same name as a variable of your shell that already holds a reference, the file wins. The variable of your shell is still resolved first, though: if its reference is broken, the launch fails anyway. Unset it or fix it.

## How Devolutions CLI reads the file

<table><thead><tr><th width="240">IN THE FILE</th><th>WHAT HAPPENS</th></tr></thead><tbody><tr><td><code>KEY=value</code></td><td>One variable per line. Spaces around the name and the value are removed.</td></tr><tr><td>Empty lines and lines that start with <code>#</code></td><td>Ignored.</td></tr><tr><td><code>KEY="value"</code> or <code>KEY='value'</code></td><td>One pair of matching quotes around the whole value is removed.</td></tr><tr><td>A reference inside a value</td><td>Replaced by the secret. Wrap it in <code>{{ }}</code> when other text touches it, so Devolutions CLI knows where it ends.</td></tr><tr><td><code>$NAME</code>, <code>${NAME}</code>, or <code>${NAME:-default}</code> inside a reference</td><td>Replaced by the value of an environment variable, for example to pick the workspace ID per environment. Without a default, the variable must be set and not empty.</td></tr></tbody></table>

A few things that work in some `.env` loaders don't work here:

* Variable names use letters, digits, and underscores only, and can't start with a digit. A line that starts with `export` is refused.
* A `#` after a value isn't a comment: it becomes part of the value.
* A value can't span several lines.
* The same variable name can't appear twice, or in both the file and `--env-ref`.

## What to commit

<table><thead><tr><th width="240">FILE</th><th>COMMIT IT?</th></tr></thead><tbody><tr><td>A <code>.env</code> file with references only</td><td>Yes. A reference contains names or IDs, never a value. Without access to the vault, it opens nothing.</td></tr><tr><td>A file produced by <code>devo secret inject</code></td><td>No. It contains the values in plain text. Add it to <code>.gitignore</code>.</td></tr><tr><td>A <code>.env</code> file that still holds a password</td><td>No. Replace the value with a reference first.</td></tr></tbody></table>

{% hint style="warning" %}
If a password was ever committed, removing it from the file doesn't remove it from the history of the repository. Change the password in your vault, for example with [devo secret set](/cli/guides/secrets/update-a-secret.md).
{% endhint %}

## If it doesn't work

* "Environment file lines must use KEY=value syntax.": a line has no `=`, or starts with one. Fix that line, or turn it into a comment with `#`.
* A reference doesn't resolve: see [A secret reference doesn't resolve](/cli/help/troubleshooting/reference-does-not-resolve.md).
* Your tool only reads a configuration file, not environment variables: see [Fill a configuration file from a template](/cli/guides/secrets/fill-a-template.md).

## Next

* [Run a command with its secrets](/cli/guides/secrets/run-with-secrets.md)
* [Give an agent a credential without exposing it](/cli/guides/ai-agents/run-an-agent.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.devolutions.net/cli/guides/secrets/replace-env-files.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
