Skip to main content
Secrets provide secure storage for environment variables and credentials that can be injected into Modal Images, Functions, and Sandboxes.

Access the Secrets API

import { ModalClient } from "modal";

const modal = new ModalClient();
const secret = await modal.secrets.fromName("my-secret");

Methods

Reference a Secret by name.
name
string
required
Name of the Secret.
params
SecretFromNameParams
Optional parameters
return
Promise<Secret>
The Secret object.
const secret = await modal.secrets.fromName("api-keys");

// Ensure specific keys exist
const secret = await modal.secrets.fromName("database-creds", {
  requiredKeys: ["DB_HOST", "DB_PASSWORD"],
});
Throws NotFoundError if the secret doesn’t exist or if any required keys are missing.
Create an ephemeral Secret from a plain object of key-value pairs.
entries
Record<string, string>
required
Object mapping string keys to string values.
params
SecretFromObjectParams
Optional parameters
return
Promise<Secret>
An ephemeral Secret object.
const secret = await modal.secrets.fromObject({
  API_KEY: "sk-...",
  API_ENDPOINT: "https://api.example.com",
});
All values must be strings. Throws InvalidError if any value is not a string.
Delete a named Secret.
name
string
required
Name of the Secret to delete.
params
SecretDeleteParams
Optional parameters
await modal.secrets.delete("old-credentials");
Deletion is irreversible and will affect any Apps currently using the Secret.

Secret object

The Secret object represents stored credentials or environment variables.

Properties

secretId
string
Unique identifier for the Secret.
name
string | undefined
Name of the Secret, if it was looked up by name.

Example: Use secrets in a Sandbox

import { ModalClient } from "modal";

const modal = new ModalClient();

const app = await modal.apps.fromName("api-client", {
  createIfMissing: true,
});

// Reference an existing secret
const apiSecret = await modal.secrets.fromName("api-keys");

// Or create an ephemeral secret
const dbSecret = await modal.secrets.fromObject({
  DB_HOST: "postgres.example.com",
  DB_USER: "admin",
  DB_PASSWORD: "secret123",
});

const image = modal.images
  .fromRegistry("python:3.13")
  .dockerfileCommands(["RUN pip install requests psycopg2"]);

const sandbox = await modal.sandboxes.create(app, image, {
  secrets: [apiSecret, dbSecret],
});

// Environment variables from secrets are now available
const proc = await sandbox.exec([
  "python",
  "-c",
  "import os; print(os.environ.get('DB_HOST'))",
]);

const output = await proc.stdout.readText();
console.log(output); // "postgres.example.com"

await sandbox.terminate();

Example: Build an image with secrets

import { ModalClient } from "modal";

const modal = new ModalClient();

const app = await modal.apps.fromName("private-deps", {
  createIfMissing: true,
});

// Secret for accessing private Git repo
const gitSecret = await modal.secrets.fromName("github-token");

const image = modal.images
  .fromRegistry("python:3.13")
  .dockerfileCommands(
    [
      "RUN git clone https://${GITHUB_TOKEN}@github.com/myorg/private-repo.git",
      "RUN cd private-repo && pip install -e .",
    ],
    { secrets: [gitSecret] } // Secret available during build
  );

const builtImage = await image.build(app);

Example: Combine environment variables and secrets

import { ModalClient } from "modal";

const modal = new ModalClient();

const app = await modal.apps.fromName("web-app", {
  createIfMissing: true,
});

// Reference a named secret
const awsSecret = await modal.secrets.fromName("aws-credentials");

// Create ephemeral secret for environment-specific config
const configSecret = await modal.secrets.fromObject({
  ENVIRONMENT: "production",
  LOG_LEVEL: "info",
});

const image = modal.images.fromRegistry("node:20");

const sandbox = await modal.sandboxes.create(app, image, {
  secrets: [awsSecret, configSecret],
  // Additional env vars (will be merged into a secret automatically)
  env: {
    PORT: "8080",
    NODE_ENV: "production",
  },
});

Security best practices

Never hardcode secrets in your code or commit them to version control. Always use Modal Secrets or environment variables.
// ❌ Don't do this
const sandbox = await modal.sandboxes.create(app, image, {
  env: {
    API_KEY: "sk-1234567890", // Don't hardcode!
  },
});

// ✅ Do this instead
const secret = await modal.secrets.fromName("api-keys");
const sandbox = await modal.sandboxes.create(app, image, {
  secrets: [secret],
});

Build docs developers (and LLMs) love