Skip to main content
Secrets provide a dictionary of environment variables for images. They are a secure way to add credentials and other sensitive information to the containers your functions run in.

Creating secrets

From a dictionary

Create a secret directly from a dictionary of key-value pairs:
import modal
import os

app = modal.App()

@app.function(secrets=[modal.Secret.from_dict({"FOO": "bar"})])
def run():
    print(os.environ["FOO"])  # prints "bar"

From local environment variables

Automatically pull values from your local environment:
@app.function(secrets=[modal.Secret.from_local_environ(["API_KEY", "SECRET_TOKEN"])])
def run():
    # API_KEY and SECRET_TOKEN from your local environment are now available
    print(os.environ["API_KEY"])

From a .env file

Load secrets from a .env file in your project:
@app.function(secrets=[modal.Secret.from_dotenv(__file__)])
def run():
    print(os.environ["USERNAME"])  # Assumes USERNAME is defined in your .env file
By default, Modal looks for a file named .env. You can specify a different filename:
@app.function(secrets=[modal.Secret.from_dotenv(filename=".env-dev")])
def run():
    pass

From the dashboard

Reference a named secret created on the Modal dashboard:
secret = modal.Secret.from_name("my-secret")

@app.function(secrets=[secret])
def run():
    pass
You can optionally specify required keys that will be validated server-side:
secret = modal.Secret.from_name("my-secret", required_keys=["API_KEY", "SECRET_TOKEN"])

Managing named secrets

Modal provides a Secret.objects manager for creating, listing, and deleting named secrets programmatically.

Create a named secret

contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
modal.Secret.objects.create("my-secret", contents)
Secrets are created in the active environment by default. You can specify a different environment:
modal.Secret.objects.create("my-secret", contents, environment_name="dev")
By default, an error is raised if the secret already exists. Use allow_existing=True to make this a no-op:
modal.Secret.objects.create("my-secret", contents, allow_existing=True)
Secret.objects.create() does not return a local instance. Use Secret.from_name() to perform a lookup after creation.

List secrets

Retrieve all named secrets in the current environment:
secrets = modal.Secret.objects.list()
print([s.name for s in secrets])
Filter secrets by environment:
dev_secrets = modal.Secret.objects.list(environment_name="dev")
Limit results and filter by creation date:
secrets = modal.Secret.objects.list(max_objects=10, created_before="2025-01-01")

Delete a secret

Deletion is irreversible and will affect any apps currently using the secret.
await modal.Secret.objects.delete("my-secret")
Delete from a specific environment:
await modal.Secret.objects.delete("my-secret", environment_name="dev")
Use allow_missing=True to avoid errors if the secret doesn’t exist:
await modal.Secret.objects.delete("my-secret", allow_missing=True)

Working with secret instances

Get secret information

secret = modal.Secret.from_name("my-secret")
info = await secret.info()
print(f"Created at: {info.created_at}")
print(f"Created by: {info.created_by}")

Update a secret

Update or add key-value pairs to an existing secret:
secret = modal.Secret.from_name("my-secret")
await secret.update({"NEW_KEY": "new-value", "UPDATED_KEY": "updated-value"})
Like dict.update(), this merges the new values into the existing secret. Keys not mentioned are left unchanged.

API reference

Secret.from_dict()

env_dict
dict[str, Optional[str]]
default:"{}"
Dictionary of entries to insert as environment variables. Values can be None, which are ignored.

Secret.from_local_environ()

env_keys
list[str]
required
List of local environment variables to include for remote execution.

Secret.from_dotenv()

path
str
default:"None"
Starting point for finding the .env file. If not provided, uses the current working directory.
filename
str
default:".env"
Name of the environment file to load.

Secret.from_name()

name
str
required
Name of the secret to reference.
environment_name
str
default:"None"
Environment containing the secret. Uses the active environment if not specified.
required_keys
list[str]
default:"[]"
List of required environment variables that will be validated server-side.

Secret.objects.create()

name
str
required
Name to use for the new secret.
env_dict
dict[str, str]
required
Key-value pairs to set in the secret.
allow_existing
bool
default:"False"
If True, no-op when the secret already exists.
environment_name
str
default:"None"
Environment to create the secret in. Uses the active environment if not specified.

Secret.objects.list()

max_objects
int
default:"None"
Limit the number of results returned.
created_before
datetime | str
default:"None"
Only return secrets created before this date.
environment_name
str
default:""
Environment to list secrets from. Uses the active environment if not specified.

Secret.objects.delete()

name
str
required
Name of the secret to delete.
allow_missing
bool
default:"False"
If True, don’t raise an error if the secret doesn’t exist.
environment_name
str
default:"None"
Environment containing the secret. Uses the active environment if not specified.

Build docs developers (and LLMs) love