# The configuration model

> One helix.config.ts per project holds the name, project and workspace IDs, environment, and auth aliases. The CLI writes it for you.

A Helix project has exactly one config file: `helix.config.ts` at the project root. It holds the project's name, its project and workspace IDs, the Helix environment the CLI talks to, and the map of auth aliases to credential UUIDs. You rarely edit it by hand, because `helix init`, `helix workspace select`, `helix project set`, and `helix env set` write to it for you.

## What the file holds

```typescript
// helix.config.ts
import { defineConfig } from '@trayai/helix-sdk';

export default defineConfig({
  name: 'customer-health',
  projectId: 'a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d',
  workspaceId: 'f8e7d6c5-4b3a-2190-8765-abcdef012345',
  environment: 'us1',
  authentications: {
    salesforce: '1a0fbf5c-2c9e-4aa1-ada3-ccbba65019ab',
  },
});
```

| Key | What it names |
|---|---|
| `name` | The project name. The first deploy uses it when it provisions the project on the platform. |
| `projectId` | The provisioned project this checkout points at. Unset until a deploy provisions one, or until you set it yourself. |
| `workspaceId` | The Tray workspace the project belongs to. Auth aliases resolve against it, locally and on deploy. |
| `environment` | The Helix environment the CLI talks to, for example `us1`. |
| `authentications` | Alias to credential UUID, used as `ctx.http.authed('alias')` in function code. |

`workspaceId` is the one you need early: `ctx.http.authed('alias')` resolves against the workspace's auth service during `helix dev`, not only in production. `projectId` matters when you deploy, and for anything the platform provisions for the project. Persistent key-value storage is the clearest case: with no project ID, `helix dev` has nothing provisioned to read from and falls back to in-memory storage that resets on restart.

See [projects and workspaces](/documentation/concepts/projects-and-workspaces/) for what each UUID refers to.

## The CLI writes the file

| Command | What it writes |
|---|---|
| `helix init` | Creates the file. `--project-id` and `--workspace-id` fill in those IDs; without them the ID is prompted for or left unset. |
| `helix workspace select [name]` | Picks a workspace interactively, then writes `workspaceId`. |
| `helix workspace set <id>` | Writes `workspaceId` when you already know the ID, for scripts and CI. |
| `helix project set <id>` | Writes `projectId`, pointing this checkout at an existing provisioned project. |
| `helix env set <environment>` | Writes the environment and persists it for later commands. |

The file is ordinary TypeScript, so you can edit it directly instead. The commands exist so CI pipelines and agent sessions don't have to rewrite source to change which project they talk to. Full flags are in the [project and auth session commands](/documentation/reference/cli/project/).

## Environments

Two separate mechanisms select an environment, and they don't overlap.

`helix env set` sets the environment for the project and stores it in the config file:

```bash
helix env set us1
```

`--env` sets the environment for a single session command, and reads nothing from the config file:

```bash
helix login --env staging
helix whoami --env staging
helix logout --env staging
```

`login`, `logout`, and `whoami` accept `--env <us1|staging>` and default to `us1`. Your session is per environment, which is why authenticating against staging is a flag on the command rather than a change to the committed file. The full set of names `helix env set` accepts isn't confirmed; run `helix env set --help` to see what your version lists.

## What stays out of the file

- **Credential values.** The file maps aliases to UUIDs. The credentials themselves, and the rules for injecting them, stay on Helix's servers. See the [security model](/documentation/concepts/security-model/).
- **Your Tray session.** The token from `helix login` lives in `~/.tray.config`, outside the project and shared with `connector-cli`.
- **Function-level settings.** Handlers and input schemas live in the function files, through `defineFunction`.
- **Who can open the deployed app.** Access is a setting on the project's Access Control tab in the dashboard, not a config key. See [identity and roles](/documentation/guides/identity-and-roles/).

## Roadmap

:::roadmap{title="Per-target config files are not shipped"}
The platform design gives a project one config file per deploy target: `helix.config.ts` as the default alongside `helix.staging.config.ts` and `helix.production.config.ts`, each selected with a `--config` flag or the `HELIX_CONFIG` environment variable. The same design adds a `config` block surfaced on `ctx.config`, with secrets read from the process environment through `() => requireEnv('NAME')` thunks and values stored per project by `helix vars`.

None of that ships today. A project has one `helix.config.ts` and one environment at a time, set with `helix env set`. There is no `--config` flag, no `HELIX_CONFIG` variable, no `config` block, and no `helix vars` command. See [limits, defaults, and roadmap](/documentation/reference/limits/).
:::

For every key the config accepts, see the [configuration reference](/documentation/reference/configuration/).

---

Canonical: https://helix.tray.ai/documentation/concepts/configuration/
Any link on this page is available as markdown by appending .md to its URL.
Full corpus: https://helix.tray.ai/documentation/llms-full.txt