---
question: When does a running process pick up a new secret?
kind: task
via_web: available
via_cli: available
via_python: available
via_api: available
via_config: available
ref_web: System › Data › Secrets
ref_cli: abi secrets naas
ref_python: secret.set
ref_api: PUT /api/admin/system/resources/secret/entry
ref_config: .env
prereq: The new value, issued by the provider. Keep the old one valid until the engine runs with the new one.
next:
  - /capabilities/build/secrets/use-a-secret-in-config
  - /capabilities/build/secrets/overview
---

# Rotate a secret

Rotating replaces a secret's value in every adapter. Config is rendered once, when the engine starts: whatever already read `{{ secret.NAME }}` keeps the old value until a restart.

## Check the environment first

`{{ secret.NAME }}` takes a process environment variable before any adapter. Every tab below writes the adapters only. If the deployment sets the variable in the engine's environment (a Compose `environment:` entry, a platform setting), change it there too, or the engine renders the old value after the restart. Revoke the old value only once the engine runs with the new one.

## Web UI

Super admins only. The new value is written to every secret adapter, `.env` included.

### Open the secret

In Nexus, open **System** in the sidebar, then the **Data** tab, then **Secrets**, and select the name. **Reveal** shows the current value for 30 seconds; each reveal is audited.

![System app, Data tab, on Secrets, filtered to one key](/abi/Screenshot_System_Secrets.png)

*System › Data › Secrets, filtered to one key. Values stay masked; revealing one is audited.*

### Replace the value

Choose **Edit**, enter the new value, type the name to confirm, and save. Every change is audited.

### Restart the engine

Restart it so config renders with the new value. If the variable is also set in the engine's environment, change it there first (see [Check the environment first](#check-the-environment-first)). Then revoke the old value at the provider.

## CLI

For a project that keeps its secrets in Naas (the `naas` and `base64` adapters). A project on `.env` alone has no command for this: use the Config steps on this page.

### Check what is stored

```bash
abi secrets naas get-base64-env --naas-secret-name abi_secrets > .env.prod
```

It prints the stored file, decoded, values included. Write it to a file rather than the terminal, and never run it where the output is logged, as in CI.

Only values that span several lines come back quoted. A value that contains ` #`, or starts or ends with a space, changes on the way through: check those lines, and quote them, before you push.

### Edit and push it back

Change the line in `.env.prod`, then:

```bash
abi secrets naas push-env-as-base64 --env-file .env.prod --naas-secret-name abi_secrets
```

It replaces the whole stored file, and prints it, values included. `--naas-api-key` defaults to `$NAAS_API_KEY`. Delete `.env.prod`, restart the engine, check the environment (see [Check the environment first](#check-the-environment-first)), then revoke the old value. See [`abi secrets naas`](/user-guide/reference/cli#abi-secrets-naas).

## Python

### Write the new value

```python
self.engine.services.secret.set("PARTNER_API_TOKEN", new_token)
```

The module lists `Secret` in its dependencies: see [Add a secret](/user-guide/build/secrets/add-a-secret?via=python). `set` writes every adapter and publishes `SecretSet` with the name only. Later `secret.get` calls in this process return the new value.

### Restart what read the old one

Config rendered at start, and any other process, keep the old value until they restart. If the variable is also set in the engine's environment, change it there too (see [Check the environment first](#check-the-environment-first)), then revoke the old value.

## REST API

The System routes of the Nexus API. Auth: a Nexus session of a super admin (`POST /api/auth/login` returns the access token). Every change is audited.

### Replace the value

Replacing needs `confirm` set to the name; without it the call answers 409:

```bash
curl -X PUT "http://localhost:9879/api/admin/system/resources/secret/entry?id=PARTNER_API_TOKEN&confirm=PARTNER_API_TOKEN" \
  -H "Authorization: Bearer $NEXUS_TOKEN" \
  --data-binary 'the-new-value'
```

With `abi dev up`, use the `api` port that `abi dev ports` prints.

### Restart the engine

If the variable is also set in the engine's environment, change it there too (see [Check the environment first](#check-the-environment-first)). Then revoke the old value at the provider.

## Config

### Replace the line in `.env`

```bash title=".env"
PARTNER_API_TOKEN=the-new-value
```

### Check the environment

If the deployment sets `PARTNER_API_TOKEN` in the engine's environment, change it there too: it wins over `.env`. See [Check the environment first](#check-the-environment-first).

### Restart

The engine reads `.env` and renders config when it starts. A running engine does not see an edit to the file, even through `secret.get`. Restart it, then revoke the old value at the provider.

## Workspace secrets

Settings › Secrets has no edit control: delete the row and add it again with the new value. The API can replace a value in place, for workspace admins and owners: `PUT /api/secrets/{secret_id}` with `{"value": "..."}`. Neither changes an engine secret.
