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

# Secrets

> Name the credentials a workload needs in code, keep their values in the workspace, and receive them as environment variables.

## Declare a credential dependency

Save this as `service.py`:

```python theme={null}
import os
import urllib.request

from lazycloud import App, Secret

app = App("service_client")
api_key = Secret("SERVICE_API_KEY")


@app.function(secrets=[api_key.name], retries=0)
def fetch_status(url: str) -> str:
    request = urllib.request.Request(
        url,
        headers={"Authorization": f"Bearer {os.environ[api_key.name]}"},
    )
    with urllib.request.urlopen(request, timeout=30) as response:
        return response.read().decode("utf-8")
```

`Secret("SERVICE_API_KEY")` only names the secret, and only workloads that list
it receive the value, as an environment variable. The name lives in code, the
value never does.

## Provision the value from Python

Save this as `configure_secrets.py` beside `service.py`:

```python theme={null}
from getpass import getpass

from service import api_key


if __name__ == "__main__":
    api_key.set(getpass("Service API key: "))
```

Run it once to store the key:

```bash theme={null}
uv run python configure_secrets.py
```

`set()` creates or replaces the value. In CI, the same script can call
`api_key.set(os.environ["SERVICE_API_KEY"])` with the value from the CI secret
store. With `SERVICE_URL` set to your API's URL, the function runs:

```bash theme={null}
uv run lazycloud run service:fetch_status "$SERVICE_URL"
```

Secrets are encrypted at rest and scoped to the workspace. Code can still leak
one by printing it, and the record `set()` returns contains the value.

## Rotate or remove a secret

Rotation is the setup script with a new value, then a redeploy so new
containers get it. `create(value)` refuses to overwrite, `update()`, `get()`,
and `delete()` do the rest, and a secret stays stored until deleted.
`Image.with_secrets([...])` covers build-time credentials.

## From the CLI or dashboard

The [secret commands](/cli/storage#lazycloud-secret) and the dashboard's Storage
page manage secrets too.
