# Secrets

**A project's secrets are the credentials its code needs to run — the values a task's setup command, test suite and application read from the environment.** You either give them to hlix directly or point hlix at the secret manager you already use, and hlix resolves them fresh every time a task starts.

They are configuration for *your* code. They are separate from the [provider keys](/coders/models-and-keys/) hlix uses to call models, which belong to the Workspace.

## Prerequisites

- A project in your Workspace.
- `manage` access on the project.
- For a connected secret manager, a machine identity with read access to the right project and environment.

## Two ways to supply them

| Provider | Config it takes | Use it when |
| --- | --- | --- |
| `manual` | `{ "secrets": [{ "key": …, "value": … }] }` | hlix holds the values, encrypted at rest. The simplest option |
| `infisical` | `{ "clientId": …, "clientSecret": …, "projectId": …, "environment": … }` | Your Infisical project stays the source of truth, and hlix reads from it when a task starts |

A project can hold more than one configuration — for example, a manual set for a few overrides beside a connected manager for the rest.

### Give the values to hlix

```bash
curl -sS -X POST "$HLIX_BASE_URL/v1/api/secrets/project/$PROJECT_ID" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
  -H 'content-type: application/json' \
  -d '{
    "provider": "manual",
    "label": "Test credentials",
    "config": { "secrets": [{ "key": "DATABASE_URL", "value": "…" }] }
  }'
```

Expected result: `201` and the stored configuration. The response carries the **key names and a count**, never a value. No read endpoint for secrets returns a value.

### Point hlix at your secret manager

```bash
curl -sS -X POST "$HLIX_BASE_URL/v1/api/secrets/project/$PROJECT_ID" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
  -H 'content-type: application/json' \
  -d '{
    "provider": "infisical",
    "label": "Staging",
    "config": { "clientId": "…", "clientSecret": "…", "projectId": "…", "environment": "staging" },
    "envFilter": "staging"
  }'
```

Expected result: `201`, with the client secret rendered as `••••••••` in the echo.

`envFilter` narrows which of the resolved keys the project actually receives.

`PATCH /v1/api/secrets/project/{projectId}/{configId}` updates a configuration; `DELETE` on the same path removes it. `GET /v1/api/secrets/project/{projectId}` lists them, values redacted.

## Check what will resolve

Run this check before a task, rather than after one fails.

```bash
curl -sS -X POST "$HLIX_BASE_URL/v1/api/secrets/project/$PROJECT_ID/test" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID"
```

Expected result:

```json
{"count": 7, "keys": ["DATABASE_URL", "STRIPE_KEY", "…"]}
```

Key names and a count, never values. The check is recorded in the [audit log](/security/audit-log/) as `secret.accessed`.

`GET /v1/api/secrets/project/{projectId}/sync-logs` shows the history of reads from a connected manager, so an intermittent credential problem shows up as a pattern.

## How a secret reaches a task

When a task starts, hlix resolves every configuration for the project and merges the results over the active [Environment](/configure/environments/)'s variables; a secret always wins over an Environment variable of the same name. The merged set is written into the task's checkout as a root `.env` file, which the coder's commands read like any other environment file.

**Every coder receives them:** The `.env` is written for every coder, Hlix Code and every external coder alike. The [provider keys](/coders/models-and-keys/) hlix uses to call models never travel this path.

**A missing secret stops the task before it starts:** If a configuration cannot resolve, the task fails **before** its sandbox starts. Running with only some of its credentials could let an agent act on real systems with the wrong identity, so hlix refuses instead.

The `.env` hlix writes is never committed. It is excluded from Git in the checkout, removed from every commit hlix makes, and hlix refuses to overwrite a `.env` your repository already tracks. [Secrets & protected files](/security/secrets-and-protected-files/) covers the whole data path, including what the import scanner does and does not collect.

## If a secret does not reach a task

- **`{"error":"Config not found"}` with `404`.** The configuration id does not belong to that project.
- **`{"error":"Failed to create secrets config"}` with `500`.** The write did not persist. Check the `config` shape against the table above — a `manual` provider needs a `secrets` array, not a flat object.
- **A `400` from the test endpoint carrying the provider's own message.** The connected manager rejected the credentials or could not find the project or environment named in `config`. The message is passed through unchanged so you see what the manager said.
- **The test lists fewer keys than you expect.** `envFilter` is narrowing them. Clear it to see everything the configuration resolves.
- **A task fails before the coder starts, naming secrets.** A configuration failed to resolve when the task started. Run the test endpoint; it fails the same way without spending a task.
- **A value is present but wrong.** Two configurations may both define the key. Later configurations override earlier ones, and project secrets override Environment variables. List the configurations and check for a duplicate key.
- **The coder cannot see a value your local shell has.** Nothing is inherited from your machine. If the task needs a value, make it a project secret or an Environment variable.
- **A `403` on any of these routes.** They need `manage` access on the project. A client collaborator is refused, including one with steer access.

## Where to go next

| If you want to… | Read |
| --- | --- |
| Understand the whole secret data path | [Secrets & protected files](/security/secrets-and-protected-files/) |
| Set non-secret configuration | [Environments](/configure/environments/) |
| Give hlix keys to call models | [Models & provider keys](/coders/models-and-keys/) |
| See what an import scan collects | [Environment discovery](/cli/environment-discovery/) |

## Next steps

[Secrets & protected files](/security/secrets-and-protected-files/)
  [Environments](/configure/environments/)
  [Audit log](/security/audit-log/)
  [Repositories](/configure/repositories/)