# 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)