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
- Sign in with an admin API key (verified on the server only).
- Projects — Group bundles; each project has a slug used in URLs and Terraform state paths.
- Bundles — Create bundles under a project; each holds key/value entries.
- Variables — Edit entries on a bundle’s page; choose secret vs plaintext storage where offered.
- Secret env URL — Opaque links to
GET /env/<token>without putting project or bundle names in the URL. Treat links like passwords. - API keys — Create keys with scopes for CI (
read, per-bundle, per-project, oradmin).
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 inlock_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).
GETneedsread:project:…for that project (orread:project:*), or admin.POST,DELETE,LOCK,UNLOCKneedwrite: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). Setfalseto disable/tfstate. - Behind a reverse proxy with a path prefix, set
ENVELOPE_ROOT_PATHand 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).