# Environments & groups

Most apps share the bulk of their configuration. seekrit models this with
**groups**: reusable secret bags that application environments compose. An
application environment is then just *its own secrets + the groups it pulls in*,
resolved and layered at runtime.

## The model

- A **group** is an org-scoped secret bag with its own environments, keyed by
  slug (`dev`, `staging`, `production`, `sandbox`, …).
- An **application environment** composes one or more groups. At resolve time
  each group is matched to the environment whose slug matches the app
  environment's.
- Values **layer**, lowest precedence first:

```
group secrets  <  app-env secrets  <  .env file  <  process env      (highest wins)
```

So a shared `DATABASE_URL` in a group is overridden by the app's own value,
which is overridden by a local `.env`, which is overridden by an exported shell
variable.

## Setting it up

Say an `api` and a `worker` share ~80% of their config. Put the shared values in
a group and compose it into each app's environments.

```bash
# 1. A shared group with a per-environment value set
seekrit group create --name "Common backend" --slug common
seekrit group env create --group common --name Production --slug production
seekrit secrets set DATABASE_URL 'postgres://…' --group common --env production

# 2. Compose it into each app environment
seekrit env groups add --app api    --env production --group common
seekrit env groups add --app worker --env production --group common

# 3. App-specific secrets live on the app environment
seekrit secrets set QUEUE_NAME jobs --app worker --env production
```

Now `worker/production` resolves to `common@production` overlaid with
`worker/production`'s own keys. Composing more than one group? Precedence follows
`--position` (higher wins); pass it on `env groups add`.

## Local `.env` and process env

`seekrit run` auto-loads `.env` from the working directory and overlays it above
the managed layers, and the live shell overrides everything. This makes seekrit
the single way your app gets its environment while still letting you tweak
individual values locally.

```bash
echo 'VITE_CLIENT_BASE_URL=http://localhost:5173' > .env
SEEKRIT_TOKEN=skt_… seekrit run -- pnpm dev     # .env wins over managed secrets
```

Point at other files with `--env-file` (repeatable; later files win), and see
exactly where each value came from with `--explain`:

```bash
seekrit run --env-file .env --env-file .env.local --explain -- pnpm dev
```

## Swapping one group per boot

Group environments double as **variants**. To boot with a different slice of a
single group — say staging auth keys — while keeping everything else at `dev`,
override just that group:

```bash
seekrit run --with auth-providers=staging -- pnpm dev
```

Everything else resolves at the app environment's slug; only `auth-providers`
switches to its `staging` slice. Overrides are fail-closed: you can only pull a
slice you hold a key grant for. As a logged-in developer you hold them all; for a
service token, pre-authorize alternate slices at creation with
`token create … --allow auth-providers=staging`.

> **Note:** Committing a config file no longer pins an environment. `seekrit.json` names only org + app; the environment is selected by the service token (or `--env`).
