# The configuration model

> helix.config.ts holds the name, project and workspace IDs, region, and auth aliases. One file per deploy target, selected with --config.

A Helix project's config lives in `helix.config.ts` at the project root. It holds the project's name, its project and workspace IDs, the Helix region 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 region set` write to it for you.

A config file describes exactly one deploy target. Most projects have just the one file, but a project with more than one target, such as a separate production deployment, keeps [one config file per target](#one-config-file-per-target) and picks one per command with `--config`.

## 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',
  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. |
| `region` | The Helix region the CLI talks to: `us1`, `eu1`, `ap1`, or `ap2`. Written by `helix region set`. |
| `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 region set <region>` | Writes the region 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/).

## One config file per target

A config file names one target: one workspace, one project, one set of auth aliases. There is no environment map inside the file and no persisted "current target" state in the CLI. When you want a separate production target (typically its own workspace and its own credentials), you create one config file per target and name the one you mean. The convention is `helix.<target>.config.ts`:

```
helix.config.ts               ← default; the target you develop against
helix.production.config.ts
```

Every command that reads or writes project config (`dev`, `deploy`, the `deployment` commands, the `auth` commands, `project set`, `region set`, the `workspace` commands, and `mcp`) accepts `--config <path>`:

```bash
helix dev                                          # uses ./helix.config.ts
helix deploy                                       # deploys the default target
helix deploy --config helix.production.config.ts   # deploys production
```

The `HELIX_CONFIG` environment variable has the same effect, which is useful in CI where every step should hit the same target. Precedence, highest first: the `--config` flag, then `HELIX_CONFIG`, then `./helix.config.ts`.

Commands that write config write to the selected file: `helix project set <id> --config helix.production.config.ts` updates the production file and leaves the default alone, and a first deploy with `--config` records the provisioned project ID in that file.

Keeping the target you develop against in `helix.config.ts` gives you a useful safety property: a bare `helix dev` or `helix deploy` only ever touches your development target. Reaching production always means naming the file, so there's no environment switch to forget to reset.

Config files are ordinary TypeScript modules, so values shared between targets live in a module each target file imports and spreads. Each file stays complete and self-describing: open `helix.production.config.ts` and you see exactly what production is, with no mental merge of a base plus overrides. A sharing example is in the [configuration reference](/documentation/reference/configuration/#per-target-config-files).

## Regions

Helix runs as four separate regional deployments: `us1` (the default), `eu1`, `ap1`, and `ap2`, each with its own dashboard and API backend. A region is not your own development/production split, which is [one config file per target](#one-config-file-per-target); it's which of the four backends the CLI talks to.

Your workspace lives in one region, set when it's provisioned, and every project in it uses that same region. `region` in `helix.config.ts` tells the CLI which backend to call; it doesn't move your workspace or choose one for it.

`helix region set` writes the region into `helix.config.ts` when you want to persist a choice for later commands:

```bash
helix region set <region>
```

`login`, `logout`, and `whoami` also accept an optional `--region <region>` flag for a single session command. It does not read the config file. Run `helix region set --help` to see which region names your CLI version accepts.

The dashboard is region-scoped too: sign in at `https://app.helix.tray.ai` for `us1`, or `https://app.helix.<region>.tray.ai` (for example `https://app.helix.eu1.tray.ai`) for `eu1`, `ap1`, or `ap2`. Your Tray contact tells you which region your workspace is in.

## 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.
- **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/).

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