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

# Secrets

> AES-256-GCM encrypted secrets - versioned, audited, and never logged.

## What are secrets?

Secrets are sensitive values - API keys, database passwords, TLS certificates - that need to be encrypted at rest and tightly access-controlled.

In Nexus, secrets are:

* Encrypted with **AES-256-GCM** at rest
* **Never returned in plaintext** via the audit log
* **Versioned** - every write creates a new version; previous versions can be promoted
* Scoped to a **service** and an **environment**
* Only available to **backend services** (secret keys); frontend services (public keys) never receive secrets

## Key names

Secret keys follow the pattern `^[a-zA-Z]([a-zA-Z0-9_.:-]*[a-zA-Z0-9])?$` - letters, digits, dots, underscores, hyphens, and colons.

Examples: `stripe.secret_key`, `db:password`, `TLS_CERT`

## Secret types

| Type   | Description                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------------------- |
| `text` | Plain string value - the default                                                                                        |
| `file` | Binary or multi-line content (PEM certs, JSON key files). The SDK writes the value to a temp file and returns the path. |

## Reading secrets

All backend SDKs provide a typed accessor. Calling `GetSecret` with a public key or on a `frontend`-kind service raises an error - secrets are never sent to frontend services.

<CodeGroup>
  ```go Go theme={null}
  value, err := client.GetSecret("stripe.key")
  // file-type:
  path, err  := client.GetSecretFilePath("TLS_CERT")
  ```

  ```typescript Node.js theme={null}
  const value = client.getSecret('stripe.key');
  const path  = client.getSecretFilePath('TLS_CERT'); // temp file path
  ```

  ```python Python theme={null}
  value = client.get_secret('stripe.key')
  path  = client.get_secret_file_path('TLS_CERT')
  ```

  ```csharp .NET theme={null}
  var value = client.GetSecret("stripe.key");
  var path  = client.GetSecretFilePath("TLS_CERT");
  ```
</CodeGroup>

<Warning>
  `GetSecret` raises `ErrPublicKeyRestricted` (Go) / `NexusPublicKeyError` (Node) if called with a public key.
  It raises `ErrServiceKindMismatch` / `NexusServiceKindMismatchError` on a `kind=frontend` service regardless of key type.
</Warning>

## Using secrets in configs

Configs can reference secrets by key using the `{{secret:KEY}}` template syntax. The value is resolved server-side at sync time and delivered as the resolved string - the secret value is never stored in plaintext in the config.

```
database.url = postgresql://user:{{secret:DB_PASSWORD}}@host:5432/mydb
```

## Versioning

Every write to a secret creates a new version. You can:

* View version history in the console
* Promote an older version to become the current value
* See the diff between versions

## Audit log

The following events are recorded for secrets:

| Event               | Trigger                                              |
| ------------------- | ---------------------------------------------------- |
| `secret.created`    | New secret added                                     |
| `secret.updated`    | Value changed (new version created)                  |
| `secret.deleted`    | Secret removed                                       |
| `secret.reveal`     | Version history viewed (plaintext revealed to admin) |
| `secret.list`       | Secret list fetched via admin API                    |
| `secret.get_by_key` | Individual secret fetched via admin API              |
