> ## Documentation Index
> Fetch the complete documentation index at: https://docs.specific.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets and config

> Parameterize sensitive and environment-specific values without hardcoding them.

Secrets and config let you parameterize values that services need, instead of hardcoding them in `specific.hcl`:

* **Secrets** - sensitive information that should never be committed to version control: API keys, database passwords, signing keys.
* **Config** - non-sensitive values that may vary between environments: log levels, feature flags, URLs.

Because every value is declared in `specific.hcl`, Specific knows exactly which ones are missing and prompts you for them when needed, both when starting `specific dev` and when deploying to the cloud. There's no `.env` file to assemble by hand.

## Secrets

Declare the secrets your application needs and reference them in `env`:

```hcl specific.hcl theme={null}
secret "stripe_api_key" {}

secret "jwt_secret" {
  generated = true
}

service "api" {
  build = build.api
  command = "./api"

  endpoint {
    public = true
  }

  env = {
    STRIPE_API_KEY = secret.stripe_api_key
    JWT_SECRET = secret.jwt_secret
  }
}
```

Secret fields:

* `generated` - when `true`, auto-generates a random string if no value is set. Useful for internal secrets like JWT signing keys.
* `length` - length of generated secrets (default: 64). Only applies when `generated = true`.

Manual secrets (no `generated` flag) must be given a value: locally in `specific.local`, in production during deployment. Generated secrets are auto-created on first run, and you can still override them manually.

<Note>
  Secret and config references cannot be interpolated into strings; use them as standalone `env` values.
</Note>

## Config

```hcl specific.hcl theme={null}
config "log_level" {
  default = "info"
}

service "api" {
  build = build.api
  command = "./api"

  endpoint {
    public = true
  }

  env = {
    LOG_LEVEL = config.log_level
  }
}
```

Config fields:

* `default` - value used unless overridden by an environment or locally.

### Environment overrides

Override config values per environment with `environment` blocks:

```hcl specific.hcl theme={null}
config "log_level" {
  default = "info"
}

environment "production" {
  config = {
    log_level = "warn"
  }
}

environment "staging" {
  config = {
    log_level = "debug"
  }
}
```

## Local development: `specific.local`

Local secret and config values live in `specific.local`, a gitignored HCL file next to `specific.hcl`:

```hcl specific.local theme={null}
secrets {
  stripe_api_key = "sk_test_..."
}

config {
  log_level = "debug"
}
```

You don't have to fill it out ahead of time: `specific dev` prompts for any missing secrets and config values on startup. The file is never included in deployments.

## Production

During `specific deploy`, the CLI checks that every required value is set for the target environment and prompts you interactively for anything missing. You can enter values while builds are still running. Values can also be passed as flags: `specific deploy --secret stripe_api_key=sk_live_...`.

* Secrets are stored securely, never logged, and injected into services as environment variables at runtime.
* Secrets are scoped per environment - setting a secret for `staging` does not affect `production`.
* Update secrets and config anytime from the [dashboard](https://dashboard.specific.dev), without touching `specific.hcl`. New values take effect on the next deployment.

## Complete example

```hcl specific.hcl theme={null}
# External API key: must be set manually, sensitive
secret "stripe_api_key" {}

# Internal signing key: auto-generated, sensitive
secret "jwt_secret" {
  generated = true
}

# Log level: not sensitive, varies by environment
config "log_level" {
  default = "info"
}

service "api" {
  build = build.api
  command = "./api"

  endpoint {
    public = true
  }

  env = {
    STRIPE_API_KEY = secret.stripe_api_key
    JWT_SECRET = secret.jwt_secret
    LOG_LEVEL = config.log_level
  }
}

environment "production" {
  config = {
    log_level = "warn"
  }
}
```
