Skip to main content
UpNext provides an encrypted key-value store for managing secrets like API keys, database passwords, and connection strings. Secrets are encrypted at rest and injected as environment variables when your services start.

Request secrets

Declare which secrets your worker or API needs:
worker = upnext.Worker("my-worker", secrets=["db_password", "stripe_key"])
api = upnext.Api("my-api", port=8001, secrets=["db_password"])
When the service starts, UpNext fetches these secrets from the server and injects them as environment variables. You can then access them with os.environ:
import os

@worker.task
async def charge_customer(customer_id: str):
    stripe_key = os.environ["stripe_key"]
    ...

Manage secrets

Via the dashboard

The dashboard has a Secrets page where you can create, update, and delete secrets. Navigate to it from the sidebar.

Via the REST API

You can also manage secrets programmatically through the server’s API:
# Create or update a secret
curl -X PUT http://localhost:8080/api/v1/secrets/db_password \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-api-key" \
  -d '{"value": "my-secret-password"}'

# List all secrets (values are hidden)
curl http://localhost:8080/api/v1/secrets \
  -H "Authorization: Bearer your-api-key"

# Delete a secret
curl -X DELETE http://localhost:8080/api/v1/secrets/db_password \
  -H "Authorization: Bearer your-api-key"

How it works

  1. You create secrets in the dashboard or via the API
  2. Secrets are encrypted and stored in the server’s database
  3. When a worker or API starts, it fetches declared secrets from the server
  4. Secrets are injected as environment variables before your code runs
  5. Your code accesses them via os.environ

Best practices

  • Use descriptive names like stripe_api_key rather than generic names like key1
  • Only declare the secrets each service actually needs
  • Rotate secrets by updating their value in the dashboard — services pick up the new value on next restart