Envelope Help

Documentation

How to use Envelope in the UI and via the API, including Terraform remote state. The same content lives in the repo as docs/usage.md.

What Envelope does

Envelope stores bundles of environment variables (like a .env file). Secret values are encrypted at rest with Fernet using ENVELOPE_MASTER_KEY. You manage data in the web UI and automate with API keys (scoped read/write/admin).

Web UI

  1. Sign in with an admin API key (verified on the server only).
  2. Projects — Group bundles; each project has a slug used in URLs and Terraform state paths.
  3. Bundles — Create bundles under a project; each holds key/value entries.
  4. Variables — Edit entries on a bundle’s page; choose secret vs plaintext storage where offered.
  5. Secret env URL — Opaque links to GET /env/<token> without putting project or bundle names in the URL. Treat links like passwords.
  6. API keys — Create keys with scopes for CI (read, per-bundle, per-project, or admin).

Exporting bundles (API)

With a key that can read the bundle:

GET /api/v1/bundles/{name}/export?format=dotenv
Authorization: Bearer <api-key>

Use format=json for JSON.

For jobs that must not use a Bearer token on download, create a secret env URL once and call curl with only that URL (see README).

Terraform HTTP remote state

Envelope can serve a Terraform HTTP backend API under /tfstate/… (GET/POST/DELETE and optional LOCK/UNLOCK), so Terraform stores state in the same SQLite database as the app.

How state is stored

  • State file bytes live in table pulumi_state_blobs (name is historical): a string key and raw binary body.
  • Locks use pulumi_state_locks, one row per state key, with JSON lock data in lock_body.
  • Unlike bundle secrets, Terraform state is not Fernet-encrypted with ENVELOPE_MASTER_KEY — it is stored as raw bytes. Protect database backups and disk accordingly.

Per-project URLs (recommended)

/tfstate/projects/<project_slug>/<path-to-statefile>

Example: /tfstate/projects/my-proj/default.tfstate. Authenticate with Authorization: Bearer … or HTTP Basic (password = API key).

  • GET needs read:project:… for that project (or read:project:*), or admin.
  • POST, DELETE, LOCK, UNLOCK need write:project:… for that project, or admin.

Legacy /tfstate/blobs/…

Flat keys under /tfstate/blobs/<key> require scope terraform:http_state or pulumi:state, or admin. Prefer per-project URLs for new setups.

Enable / prefix

  • Endpoints are mounted when ENVELOPE_PULUMI_STATE_ENABLED=true (default on). Set false to disable /tfstate.
  • Behind a reverse proxy with a path prefix, set ENVELOPE_ROOT_PATH and use the same prefix in Terraform backend URLs.

Terraform example

Do not put the Envelope API key in .tf files — Terraform can copy backend secrets into .terraform/ and plans. Set TF_HTTP_PASSWORD (and optionally TF_HTTP_USERNAME) in the environment instead.

terraform {
  backend "http" {
    address        = "https://envelope.example.com/tfstate/projects/my-proj/default.tfstate"
    lock_address   = "https://envelope.example.com/tfstate/projects/my-proj/default.tfstate"
    unlock_address = "https://envelope.example.com/tfstate/projects/my-proj/default.tfstate"
    username       = "terraform"
  }
}
export TF_HTTP_USERNAME=terraform
export TF_HTTP_PASSWORD="$ENVELOPE_TF_WRITE_KEY"

Set these for terraform init as well as plan/apply. In CI, inject TF_HTTP_PASSWORD from your secret store (never commit it).

More detail

OpenAPI: /docs on this server. Repo: README (deploy, TLS, CI), docs/terraform-http-remote-state.md (HTTP backend contract).