# Secrets and environment variables
Two kinds of values stay out of your code: **secrets** (passwords and API keys) and **environment variables** (plain settings such as a public URL). Kept in the project, a key never lands in your repository or an AI chat, and you change a value without changing code.
Secrets are encrypted with a managed key service. Once saved, a value is hidden: nobody can read it back in the app or API, but your apps can still use it.
## Before you start [#before-you-start]
- Adding and changing them needs the **Owner** or **Admin** role on the project.
- The app asks you to confirm it is you first: select **Verify to view**, then **Continue** on "Verify it's you".
## Where to find them [#where-to-find-them]
- **Keys** in the sidebar, under **Ship**, covers every project. Pick one; the page says whether you can change or only view.
- In a project, open **Settings** and go to **Keys**.
## Secret or variable? [#secret-or-variable]
| Use a | For | After saving |
| --- | --- | --- |
| Secret | Passwords, tokens and API keys. | Hidden. You can replace it, turn it off or delete it, never read it. |
| Variable | Plain settings your apps can read. | Visible to people who can open the Keys section. |
## Add a secret [#add-a-secret]
### Open Secrets [#open-secrets]
In the project's **Keys** section, select **Verify to view** if asked, then go to **Secrets** and open **Add a secret**.
### Name it [#name-it]
Type a **Name**, for example `GITHUB_TOKEN`.
### Choose how it is used [#choose-how-it-is-used]
Under **How it is used**, choose one:
- **Added to requests to one website**: type the **Website** (for example `api.github.com`). Klarety adds the secret to every request there, so your code never holds the value. Optionally set the **Header** (for example `Authorization`) and a **Prefix** (for example `Bearer `).
- **A variable in your deployed apps**: your deployed app reads it as an environment variable of this name.
### Paste the value and choose where it reaches [#paste-the-value-and-choose-where-it-reaches]
Paste the **Value**. Under **Reaches**, choose **Studio**, **Preview** or **Production**.
### Save [#save]
Select **Add secret**.
Secrets are write-only through the SDK too: `projects.secrets` returns names, hosts, versions and last use, never a value.
```python title="secrets.py"
from klarety import Nexus
nx = Nexus.connect()
project_id = "YOUR_PROJECT_ID"
nx.projects.set_secret(
project_id,
"GITHUB_TOKEN",
"ghp_your_token",
host="api.github.com",
use="host",
environments=["studio", "production"],
)
nx.projects.set_secret(project_id, "STRIPE_KEY", "sk_live_your_key", use="env")
for secret in nx.projects.secrets(project_id)["secrets"]:
print(secret["name"], secret["host"], secret["version"])
nx.projects.disable_secret(project_id, "STRIPE_KEY")
nx.projects.delete_secret(project_id, "STRIPE_KEY")
```
`use="host"` adds the secret to requests to `host`, with `inject_header` (default `Authorization`) and `inject_prefix` (default `Bearer `). `use="env"` sets it as a variable named after the secret. `environments` takes `studio`, `preview` and `production`. To move a dotenv file in, `nx.projects.import_secrets(project_id, entries, host=...)` adds one secret per key.
## Change or remove a secret [#change-or-remove-a-secret]
Each secret shows where it reaches, its version and its last use.
- **Replace**: overwrites the value for good. The new one is used from the next request.
- **Turn it off**: pauses the secret without deleting it.
- **Delete**: it stops being sent at once and cannot be recovered.
## Add a variable [#add-a-variable]
### Open Environment [#open-environment]
In the project's **Keys** section, go to **Environment** and select **Add variable**.
### Fill it in [#fill-it-in]
Type the name and **Value**, and choose where it **Reaches** (Studio, Preview or Production). Mark it **Build** if your app needs it at build time, or **Public** if it is meant to be seen, for example in a web page.
### Save [#save-1]
Select **Save**. If you removed or renamed a variable, the app asks you to confirm first.
`set_env` replaces the whole set, and only over the version you read, so two people never silently overwrite each other. A stale `version` gets a 409 conflict.
```python title="environment.py"
from klarety import Nexus
nx = Nexus.connect()
project_id = "YOUR_PROJECT_ID"
current = nx.projects.env(project_id)
entries = {**current["entries"], "APP_TITLE": "Sales dashboard"}
nx.projects.set_env(
project_id,
entries,
version=current["version"],
scopes={
**current["scopes"],
"APP_TITLE": {"environments": ["production", "preview"], "public": True},
},
)
```
## When a change takes effect [#when-a-change-takes-effect]
- New Studios and new deploys get a changed variable.
- Code that reads a removed or renamed variable stops finding it.
- A replaced secret is used from the next request. A deleted one stops at once.
A running app keeps its old values until it is deployed again. See [Deploy an app](/docs/deploy/deploy-an-app).
## If something goes wrong [#if-something-goes-wrong]
You have not confirmed it is you recently. Select **Verify to view**.
Only the project's Owner and Admins can add or change secrets. Ask one of them.
Replace it with a new value at its source first, then **Replace** it here. If you think the project's own credentials leaked, use **Cut the project's access** in the Danger zone. See [Project settings](/docs/projects/settings).
## Next steps [#next-steps]
- [Project settings](/docs/projects/settings)
- [Deploy an app](/docs/deploy/deploy-an-app)
- [Security](/docs/get-started/security)