---
title: Secrets
description: "Set and rotate Tako app secrets, access typed values from JavaScript, Go, or Rust, and distinguish app secrets from provider credentials."
---

## Search

Page index: https://tako.sh/llms.txt. Docs and blog posts also have .md URLs.

This site has a search endpoint: https://context7.com/api/v2/ask?siteKey=ask_b8918f0414955bb91bfa1a89&query=<URL-encoded question>. It returns documentation that answers the question, with a source link for each part. No API key is needed. If nothing matches, it says so.


App secrets are encrypted per environment and delivered to your app through the Tako SDK. Use secrets for database URLs, API keys, and other private application values. Non-secret process variables belong in `[vars]` or `[vars.<env>]` in [tako.toml](/docs/tako-toml/#variables).

## Set a secret

From the directory containing `tako.toml`, select the environment explicitly:

```bash
tako secrets set DATABASE_URL --env development
tako secrets set DATABASE_URL --env production
tako generate
```

The CLI prompts for a masked value. Non-interactive calls read stdin; MCP setters accept `stdin` as a named argument. Pass the secret through that input rather than putting its value into a command line. Non-interactive `set` requires `--env`.

Secrets are stored encrypted in `.tako/secrets.json`. Keep that file trackable with the project; `tako init` updates `.gitignore` accordingly. Encryption keys live outside the project. Copying the encrypted file alone does not grant a new machine access.

## Read from application code

Use the SDK matching your backend:

```ts JavaScript
import { tako } from "tako.sh";

const databaseUrl = tako.secrets.DATABASE_URL;
if (!databaseUrl) throw new Error("DATABASE_URL is not configured");
```

```go Go
package main

import "tako.sh"

func databaseURL() string {
    return tako.GetSecret("DATABASE_URL")
}
```

```rust Rust
fn database_url() -> Option<String> {
    tako::secret("DATABASE_URL")
}
```

For JavaScript, `tako generate` refreshes `tako.d.ts` with known secret names. Do not edit generated declarations. Read individual values: serialization of the secrets object is redacted, and spreading it does not copy its values. An individually accessed value is an ordinary string; do not log it or return it to a browser.

Go uses `tako.GetSecret("DATABASE_URL")` or the generated `Secrets.DatabaseUrl()` accessor after `tako generate`. Rust uses `tako::secret("DATABASE_URL")`, which returns `Option<String>`. See the matching [SDK skill](https://tako.sh/skills.md) for listener and bootstrap setup.

Ordinary app code does not receive app secrets as individual process environment variables. Native processes receive SDK bootstrap on fd 3; containers and `tako run` use `TAKO_BOOTSTRAP_DATA`. Use the SDK rather than reading the envelope yourself. [Release commands](/docs/deployment/#release-commands) additionally receive decrypted secrets as process environment variables.

## Apply changes to deployed apps

Setting a secret changes the local encrypted project file. Deploy sends changed secrets, or sync them to the current deployment:

```bash
tako secrets set DATABASE_URL --env production --sync
tako secrets sync --env production
```

Sync rolls fresh app processes so they receive updated bootstrap values. If any selected-environment secret cannot decrypt, Tako refuses the partial sync. In development, attached `tako dev` sessions watch secret changes; restart a background session when needed.

Remove a secret from a specific environment with:

```bash
tako secrets rm OLD_API_KEY --env production --sync
```

## Expiry and key access

Set an optional expiry with `--expires-on YYYY-MM-DD` or `--expires-on "in 30 days"`. Deployment rejects expired secrets for its selected environment and warns when expiry is within 30 days.

For an authorized machine or team migration, key import/export commands are documented in the [CLI reference](/docs/cli/#secrets). A decryption failure is a key-access problem; see [troubleshooting](/docs/troubleshooting/#secret-or-credential-key-problems). Do not replace a working environment's keys as a debugging shortcut.

## Provider and storage credentials

These serve different consumers:

| Value                              | Set with                                           | Used by                                             |
| ---------------------------------- | -------------------------------------------------- | --------------------------------------------------- |
| App secret, such as `DATABASE_URL` | `tako secrets set`                                 | Your app through its SDK                            |
| `ssl.cloudflare`                   | `tako credentials set`                             | Tako certificate management                         |
| `postgres_url`                     | `tako credentials set`                             | Shared channel, presence, store, and workflow state |
| S3 access credentials              | `tako storages add` or `tako storages credentials` | The configured storage binding or backup resource   |

```bash
tako credentials set ssl.cloudflare --env production
tako credentials set postgres_url --env production
```

Provider credentials are for deployed environments, are encrypted in `.tako/secrets.json`, and are not exposed through app secrets. `tako secrets sync` does not sync them; deployment applies the relevant runtime bindings. Your application's own database URL remains a separate app secret even if Tako's runtime state also uses Postgres.

## Verify

Use `tako secrets list --json` and `tako credentials list --json` to inspect configured metadata. Test the app's real connection or authenticated operation in the intended environment, without printing credentials. After rotation, confirm that the new app processes can use the value and inspect finite logs for failures.
