Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions design/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,50 @@ attributes:
keyData: ${{ vault.get(aws, machineKeyData) }}
```

## Environment Variables

All process environment variables are available in CEL expressions via the `env`
namespace as `env.VAR_NAME`.

### Basic Usage

```yaml
attributes:
homeDir: ${{ env.HOME }}
configValue: ${{ env.MY_CONFIG_VALUE }}
```

### Security Warning

> **Warning:** Values accessed via `env` are **not redacted or filtered**. If
> you use an environment variable as a model attribute, its value will be
> **stored on disk** in `.swamp/data/` as part of the model output data and
> will be visible in the output of `swamp data get`. This includes any
> sensitive environment variables present at runtime (e.g.
> `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, database passwords).

### Use `vault.get()` for Sensitive Values

For API keys, tokens, passwords, and other secrets, always use
`vault.get()` instead of `env`. Vault values are fetched at runtime and are
**never persisted** in model output data.

**Wrong — secret will be stored in `.swamp/data/` on disk:**

```yaml
attributes:
apiKey: ${{ env.API_KEY }}
```

**Right — secret is fetched at runtime and never persisted:**

```yaml
attributes:
apiKey: ${{ vault.get('my-vault', 'API_KEY') }}
```

See the [Sensitive Data](#sensitive-data) section for more on vault usage.

## Extensibility

Users should be able to extend the functions available to the CEL expressions by
Expand Down
19 changes: 18 additions & 1 deletion src/domain/expressions/model_resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ import { VaultService } from "../vaults/vault_service.ts";

/**
* Builds env context from Deno environment variables.
*
* Returns the **entire** process environment as a flat string map. Values are
* not filtered or redacted in any way.
*
* **Security note:** Any environment variable accessed via `env.VAR_NAME` in a
* CEL expression will be embedded in model output data and **persisted to disk**
* in `.swamp/data/`. This includes sensitive runtime values such as
* `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, database passwords, etc.
*
* Prefer `vault.get(vaultName, secretKey)` for sensitive values — vault secrets
* are fetched at runtime and are never written to model output data.
*/
export function buildEnvContext(): Record<string, string> {
return { ...Deno.env.toObject() };
Expand Down Expand Up @@ -188,7 +199,13 @@ export interface ExpressionContext {
vault?: {
get(vaultName: string, secretKey: string): string;
};
/** Environment variables */
/**
* Full process environment, available as `env.VAR_NAME` in CEL expressions.
*
* **Security note:** Values accessed via `env` are not redacted. If used as
* model attributes they will be stored in `.swamp/data/` on disk and visible
* in `swamp data get` output. Use `vault.get()` for sensitive values instead.
*/
env: Record<string, string>;
/** Data namespace for versioned data access */
data?: DataNamespace;
Expand Down