# SecretSpec

[SecretSpec](https://secretspec.dev) separates secret declaration from secret provisioning. You define the secrets that your application needs in a `secretspec.toml` file and each developer, CI system, and production environment can provide those secrets from their preferred secure provider.

## Quick Start

Follow the [SecretSpec quickstart guide](https://secretspec.dev/quick-start/).

## Runtime Loading (Best Practice)

While you can enable SecretSpec in devenv to load secrets into the `secretspec.secrets` option, we recommend that you:

a) [Use the Rust SDK](https://secretspec.dev/sdk/rust/) to load secrets in your application code

b) Load secrets at runtime and expose them only to the processes that need them

```bash
$ devenv shell
$ secretspec run -- npm start
```

The `secretspec` command is included with devenv, so no separate installation is needed. When the integration is enabled, devenv also exports the resolved profile as `SECRETSPEC_PROFILE`. If you explicitly select a provider through devenv, it also exports that override as `SECRETSPEC_PROVIDER`. Consequently, `secretspec run` uses the same explicit overrides that devenv used while evaluating `devenv.nix`. When no provider override is selected, SecretSpec commands remain free to use the per-secret provider routes from `secretspec.toml`.

**Changed in version 2.2.2**

devenv no longer infers `SECRETSPEC_PROVIDER` from the provider that happened to resolve secrets during evaluation. It only exports an explicitly selected provider override, preserving per-secret provider and fallback chains.

This approach:

* Keeps secrets out of your shell environment
* Reduces exposure of sensitive data
* Makes secret rotation easier
* Follows the principle of least privilege

## Configuration (Optional)

If you do need secrets in your devenv environment, you can configure via `devenv.yaml` or CLI flags.

### Via CLI flags (devenv 2.0+)

Override the provider and profile directly from the command line:

```bash
$ devenv --secretspec-provider dotenv --secretspec-profile dev shell
```

This automatically enables secretspec. You can also use environment variables:

```bash
$ SECRETSPEC_PROVIDER=dotenv SECRETSPEC_PROFILE=dev devenv shell
```

### Via devenv.yaml

**devenv.yaml**

```yaml
secretspec:
  enable: true
  provider: keyring  # keyring, dotenv, env, 1password, lastpass
  profile: default   # profile from secretspec.toml
```

CLI flags take precedence over `devenv.yaml` values.

The resolved profile applies both while evaluating `devenv.nix` and to `secretspec` commands run inside the development shell. An explicitly selected provider does too. If you omit the provider, SecretSpec uses the provider configuration in `secretspec.toml` for both. You can access the resolved secrets in `devenv.nix`:

**devenv.nix**

```nix
{ config, ... }:


{
  env.DATABASE_URL = config.secretspec.secrets.DATABASE_URL or "";
}
```

### Cachix auth token

**New in version 2.2**

To make the Cachix auth token a built-in required secret, without declaring it in `secretspec.toml`, set `secretspec.cachix_auth_token` to `true`:

**devenv.yaml**

```yaml
secretspec:
  enable: true
  provider: keyring
  cachix_auth_token: true
```

This uses the secret name `CACHIX_AUTH_TOKEN`. If your provider’s policy (e.g. an OpenBao/Vault policy) only grants access to a secret under a different name, set the option to that name:

**devenv.yaml**

```yaml
secretspec:
  enable: true
  provider: openbao
  cachix_auth_token: MY_TEAM_CACHIX_TOKEN
```

The string is the secret name, not the token itself. Set the option to `false` or omit it to disable the built-in requirement. Only the SecretSpec lookup is renamed: the environment variable and the Cachix push daemon still use `CACHIX_AUTH_TOKEN`, which is what the Cachix CLI reads.

## Learn More

* [SecretSpec](https://secretspec.dev)
* [Providers](https://secretspec.dev/providers/keyring/) - Keyring, 1Password, dotenv, and more
* [Profiles](https://secretspec.dev/concepts/profiles/) - Environment-specific configurations
* [Rust SDK](https://secretspec.dev/sdk/rust/) - Type-safe