Introduction
Lumaft is a self-hosted, read-only operations console for infrastructure-as-code state that lives in your own object storage.
You run it as one container next to the infrastructure it observes. It reads Pulumi DIY state from Amazon S3 or an S3-compatible store, turns each checkpoint and update record into a bounded operational model, keeps a durable record of every operation it observed, and shows all of it in a browser console.
Lumaft does not deploy anything. It never runs pulumi, never writes to your state bucket, and
never holds a credential that could. Switch it off and your deployments are unaffected.
What Lumaft does
- Inventory. One view across backends, projects, stacks, resources, and redacted outputs.
- Operations. A cross-stack timeline of previews, updates, destroys, refreshes, and imports, each with an explicit outcome and its provenance.
- Durable history. Accepted operation evidence stays in Lumaft's own database after the backend prunes its copy.
- Locks and freshness. Active Pulumi locks and observation times for every stack.
- Reliability. Aggregate outcomes linked back to the operations behind them.
- Administration. Accounts, roles, integration tokens, retention, purge, export, licensing, and database management from the same console.
What Lumaft does not do
- Run, approve, gate, or block a deployment.
- Edit raw state or decrypt Pulumi secrets.
- Require changes to your CI/CD pipeline. Runner integration is optional.
- Reconstruct history that a backend pruned before Lumaft first observed the stack.
Supported backends
| Backend | Support |
|---|---|
| Pulumi DIY state in Amazon S3 | Supported |
| Pulumi DIY state in an S3-compatible object store | Supported |
| Terraform 1.15.9 and OpenTofu 1.12.6 state in S3 | State observation only; see the bounds below |
| Azure Blob Storage, Google Cloud Storage, local filesystem | Not supported; no adapter exists |
| Pulumi Cloud | Not supported; Lumaft reads DIY state only |
| Pulumi's PostgreSQL state backend | Not supported |
Engine support bounds. State observation is verified against Terraform 1.15.9 and OpenTofu 1.12.6; other builds are unverified.
Terraform and OpenTofu can write native S3 lock files when locking is enabled, but Lumaft does not currently observe them.
Backend-native update history remains unavailable for those engines, so lock and update-history observation are Pulumi-only and these backends answer engine-unsupported for both rather than showing empty results.
How Lumaft fits
read-only (ListObjectsV2, GetObject)
┌──────────────┐ ─────────────────────────────────────▶ ┌──────────────────────┐
│ Lumaft │ │ S3 / S3-compatible │
│ container │ ◀───────────────────────────────────── │ state bucket │
│ │ └──────────────────────┘
│ console │ ▲
│ API │ ◀── optional evidence (HTTPS, bearer token) ──┐ │ writes state
│ observer │ │ │
└──────┬───────┘ ┌────────┴────┴─────────┐
│ │ Pulumi CLI / runner │
▼ │ (your pipeline) │
┌──────────────┐ └───────────────────────┘
│ SQLite or │
│ PostgreSQL │
└──────────────┘
Pulumi keeps writing state to the backend you already operate. Lumaft connects separately with read-only credentials, observes on a fixed cadence, and stores what it learns in its own database. A deployment runner can additionally report its own runs to Lumaft's ingestion API; that path is optional and uses a separate, write-only credential.
Editions
Every edition runs the same container image. An installation without a license runs as Community. A license unlocks server-side entitlements; it never changes the image.
| Edition | Adds |
|---|---|
| Community | Backend observation, the operation timeline, resource history, operation and resource history up to 1 year, local accounts with fixed roles, integration tokens, export |
| Business | Custom roles, saved views, outbound notifications, advanced reliability segmentation, retention up to 3,650 days, customer-operated PostgreSQL on one replica |
| Enterprise | OIDC, SAML, trusted-proxy sign-in, SCIM, stack read scopes, legal holds, external audit sink, coordinated PostgreSQL replicas |
| Enterprise Advanced Security | The Enterprise capability set through an organization-wide offline license, for disconnected environments |
Downgrading never deletes data or shortens an effective retention policy.
Core concepts
The objects below appear throughout the console, the API, and these docs. Names in monospace
are the exact identifiers Lumaft uses.
Installation
One Lumaft deployment: a container (or, on Enterprise PostgreSQL, a set of coordinated replicas) sharing one database. Configuration, accounts, retention policy, and licensing are installation-wide. Each installation has a durable random installation ID that connected licensing binds to.
Backend
A named, validated definition of one storage namespace Lumaft observes. A backend has a stable
id, a displayName, a bucket, an optional prefix, a region, an engine (pulumi,
terraform, or opentofu), and for Pulumi exactly one layout. Backends are declared in a JSON
file read at startup. Backend identity is installation-scoped and never inferred from bucket
metadata.
Layout
How Pulumi arranges checkpoints beneath the backend prefix.
project-scoped—.pulumi/stacks/<project>/<stack>.jsonlegacy—.pulumi/stacks/<stack>.json
Lumaft never guesses between layouts, because guessing can hide stacks or merge unrelated state. Pulumi has deprecated the legacy layout; treat a legacy backend as something to migrate.
Project and stack
A stack is the unit of inventory and operation history. Its identity is backend plus layout plus stack name, with a project name required for project-scoped layouts. Terraform and OpenTofu workspaces appear as project-scoped stacks. Renaming a stack creates a relationship; it does not rewrite history.
Resource and output
A resource is one entry in a stack's current checkpoint, presented by URN, type, and logical name. Outputs are the stack's exported values with Pulumi-marked secrets redacted before they reach a browser-facing model. Raw checkpoints are never retained.
Observation
One immutable, timestamped read of a backend. Lumaft runs three observation schedulers: checkpoints (every 60 seconds), locks (every 60 seconds while idle, every 5 seconds while a lock is active), and update history (every 5 minutes). Each observation is a complete, revision-fenced projection; the console never shows a half-read state.
Operation
The source-neutral event a user recognizes as a preview, update, destroy, refresh, or import.
Lumaft assigns its own immutable operation ID. Every completed operation carries exactly one
displayed outcome: succeeded, failed, cancelled, conflict, in progress, or
incomplete. Empty outcomes are invalid by design.
Evidence and provenance
An evidence row is one assertion about an operation from one source. Sources are:
- Pulumi backend — read by Lumaft from the backend's own update history.
- Runner (deployment runner) or Runner (developer workflow) — submitted to the ingestion API by an integration token.
The console labels every row with its source. A wrapped deployment that produces both a backend record and a runner assertion appears as two labelled rows; Lumaft stores the trusted join but does not merge them into one.
Resource change
A normalized, planned or actual change with a closed action vocabulary (create, update,
delete, replace, import, read, refresh, same, and their replacement variants).
Aggregate counts are baseline. A Destructive badge appears when a retained count is positive
for delete, delete-replaced, or replace.
Coverage
The interval for which Lumaft has evidence for a stack: observed sources, earliest retained and latest accepted evidence, the effective retention cutoff, and known gaps. Coverage starts when Lumaft first observes a stack. It is shown, never implied.
Lock
An active Pulumi lock on a stack, with its identity and the observation time it was seen at. Lock observation is Pulumi-only.
Account, role, and permission
An account is a local user with exactly one fixed role: administrator, viewer, or
transcript-reader. Roles resolve to permissions such as observations:read or
accounts:manage; controllers check permissions, never role names. Business adds custom roles
composed from the same permission catalog. Accounts are disabled, never deleted.
Integration token
A named, stack-scoped, write-only credential (lumaft_it_…) that a deployment runner or developer
machine uses to submit evidence. It carries exactly one permission, operations:evidence:write,
which no browser role holds. It cannot read anything and cannot open the console.
Retention policy, hold, and purge
The retention policy sets two installation-wide windows: how long operation summaries are kept and how long resource-change detail is kept. Policy changes append a revision; earlier revisions are never rewritten. A legal hold (Enterprise) exempts one exact evidence record from expiry and purge. Purge and forget are explicit, previewed, confirmed deletions that write their own audit rows.
Transcript
An optional, encrypted, bounded capture of a runner's stdout and stderr. Capture is off by default
and requires three separate opt-ins. Reading a transcript body requires the distinct
operations:transcripts:read permission. Redaction is applied twice and is never claimed to be
complete.
Next steps
- Quickstart — run Lumaft on your own machine in fifteen minutes.
- Deployment and setup — prerequisites and choosing an environment.
- Connect a backend — point Lumaft at your state.
- Users and permissions — bootstrap the first administrator and add your team.
- Known limitations — what this build does not do.
- FAQ and Glossary — quick answers and every term.