Skip to content

Latest commit

 

History

356 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Procella

A self-hosted Pulumi backend for tested core CLI workflows, including login, stack management, updates, and state import/export — on your own infrastructure and without a Pulumi Cloud account.

Features

  • Tested Pulumi CLI workflows — login, stack management, updates, previews, refreshes, destroys, and state import/export across documented support tiers
  • Web dashboard — React SPA with stack/update/event views, API token management, and admin settings
  • Admin settings panel — invite users, manage roles, view audit log, edit tenant profile (Descope mode)
  • API token management — create and revoke Descope access keys from the browser dashboard
  • Browser CLI loginpulumi login opens a browser flow; token is stored automatically
  • Multi-tenant authentication — dev mode with static tokens or Descope with tenant RBAC
  • Role-based access control — viewer / member / admin roles enforced per-organization
  • AES-256-GCM encryption — per-stack key derivation via HKDF for secrets at rest
  • Horizontal scaling — serverless functions on Vercel with Neon database, stateless and zero-ops
  • S3-compatible blob storage — local filesystem or any S3-compatible backend (AWS S3, MinIO, R2)
  • Single process — CLI API + tRPC dashboard share one Hono server
  • Production deployment — Deploy to Vercel with a single git push
  • Stack search — full-text search with tag filtering and cursor-based pagination
  • Webhooks — outbound HTTP event delivery with HMAC-SHA256 signing and retries
  • Audit logs — automatic audit trail via Descope management API
  • GitHub ActionsProcella-defaulted Pulumi and ESC actions, plus tenant-bound GitHub App setup and repository-scoped OIDC authentication

Performance

Benchmarked from Iowa (USA) against Procella deployed in us-east-1 (N. Virginia), N=10 resources, journal mode:

Backend up preview destroy
Procella (AWS) 1,412ms 677ms 1,087ms
Pulumi Cloud 1,647ms 749ms 1,158ms

Procella is faster than Pulumi Cloud. Server-side processing is ~55ms p50 per request on both — the difference comes from infrastructure choices (CloudFront edge termination, direct Lambda invocation). See the benchmarking docs for methodology and how to run your own comparison.

Tech Stack

Component Technology
Runtime Bun 1.2
HTTP Router Hono v4
Dashboard API tRPC v11 + Drizzle ORM
Dashboard UI React 19, Vite 7, Tailwind CSS v4
Database Neon Serverless PostgreSQL
Auth Descope / static tokens
Encryption AES-256-GCM + HKDF
Blob Storage Local filesystem / S3
Hosting Vercel (serverless functions + static sites)
Quality Biome + TypeScript strict

Quick Start

# Clone and start the dev environment
git clone https://github.com/tektum/procella.git
cd procella
bun run dev

This starts PostgreSQL, MinIO, the Bun server (with hot-reload), and the Vite UI dev server locally.

# Dev mode — set token directly
export PULUMI_ACCESS_TOKEN=devtoken123
pulumi login http://localhost:9090

# Descope mode — browser login flow (PULUMI_CONSOLE_DOMAIN is set in mise.toml)
pulumi login http://localhost:9090
# The CLI opens your browser to /cli-login, you sign in via Descope,
# and the token is stored automatically in ~/.pulumi/credentials.json

# Create and deploy a stack
mkdir my-project && cd my-project
pulumi new typescript
pulumi up

Deploy

Deploy to Render Deploy on Railway Deploy with Vercel

Platform Method Config file
Render One-click Blueprint render.yaml
Railway One-click from repo railway.toml
Vercel One-click clone vercel.json
Fly.io fly launch && fly deploy fly.toml
Coolify Docker Compose in Coolify UI docker-compose.coolify.yml
Docker Compose docker compose --profile dev up docker-compose.yml

All platforms need PostgreSQL and the PROCELLA_* environment variables. See the full configuration reference.

Configuration

All configuration is via PROCELLA_* environment variables. Set these as Vercel environment variables for production deployment. See .env.example for a complete reference.

Variable Default Description
PROCELLA_LISTEN_ADDR :9090 Server listen address
PROCELLA_DATABASE_URL (required) PostgreSQL connection string (Neon on Vercel, any PostgreSQL locally)
PROCELLA_SUBSCRIPTION_MAX_CONCURRENT 500 Per-replica ceiling on concurrent dashboard subscriptions
PROCELLA_AUTH_MODE (required) dev (static tokens) or descope (Descope access keys)
PROCELLA_DEV_AUTH_TOKEN (required if dev) Static auth token for dev mode
PROCELLA_DEV_USER_LOGIN dev-user Dev user login name
PROCELLA_DEV_ORG_LOGIN dev-org Dev org login name
PROCELLA_DEV_USERS JSON array of additional dev users
PROCELLA_DESCOPE_PROJECT_ID (required if descope) Descope project ID
PROCELLA_DESCOPE_MANAGEMENT_KEY Descope management key — enables pulumi login browser flow and API token creation
PROCELLA_BLOB_BACKEND local local (filesystem) or s3 (S3-compatible)
PROCELLA_BLOB_LOCAL_PATH ./data/blobs Local blob storage path
PROCELLA_BLOB_S3_BUCKET (required if s3) S3 bucket name
PROCELLA_BLOB_S3_ENDPOINT Custom S3 endpoint (MinIO, R2, etc.)
PROCELLA_BLOB_S3_REGION us-east-1 S3 region
PROCELLA_ENCRYPTION_KEY (required) 64 hex chars (32 bytes) for AES-256-GCM
PROCELLA_LEGACY_DECRYPTION_ENABLED true Keep v1 reads enabled until the documented per-stack v2 rewrite is complete
PROCELLA_LEGACY_ORG_MAPPINGS {} Unique JSON tenant-ID → original org-slug mappings required for Descope v1 reads
PROCELLA_DELTA_CHECKPOINTS_ENABLED false Advertise delta-checkpoint-uploads-v2; disable and restart to return clients to full checkpoints
PROCELLA_CRON_SECRET (required when /cron/gc is enabled) Bearer token used to authorize the GC cron endpoint
PROCELLA_CORS_ORIGINS (optional) Comma-separated allowed CORS origins; omit for strict same-origin
PROCELLA_GITHUB_APP_ID (optional as a group) Positive canonical-decimal GitHub App ID within the safe integer range
PROCELLA_GITHUB_APP_PRIVATE_KEY (optional as a group) Valid RSA GitHub App private key (PEM format)
PROCELLA_GITHUB_APP_WEBHOOK_SECRET (optional as a group) Non-whitespace GitHub App webhook secret; bytes are preserved
PROCELLA_GITHUB_OUTBOUND_APP_ID procella-github Descope Outbound Application that vaults each admin's GitHub user token
PROCELLA_APP_ORIGIN (required for GitHub setup) Absolute https dashboard origin the Descope outbound callback returns to

| PROCELLA_TRUST_PROXY | (optional) | Set to true only behind a trusted reverse proxy so Procella honors X-Forwarded-For / X-Real-IP |

For the optional GitHub App integration, use a dedicated App and configure all three PROCELLA_GITHUB_APP_* credential variables; omit all three to disable it. GitHub user authorization runs through a Descope Outbound Application (procella-github), so the App's OAuth callback is https://api.descope.com/v1/outbound/oauth/callback and the GitHub OAuth client ID and secret are deploy-time inputs to scripts/provision-descope-outbound-app.ts only, never runtime configuration. Grant read-only organization Members permission. During setup a Procella administrator enters the exact GitHub account login; Procella mints a one-time connect transaction bound to the tenant, that administrator, the requested account, and a __Host- browser nonce, carries it inside the Descope redirect URL, and consumes it in the initiating browser before issuing browser-bound installation state. Vaulted tokens are tenant scoped, and account administration is proven server-side against GitHub before the tenant binding is saved. Tenant setup also needs PROCELLA_DESCOPE_PROJECT_ID, PROCELLA_DESCOPE_MANAGEMENT_KEY, and PROCELLA_APP_ORIGIN; without them webhooks and PR publication still work while setup fails closed. SST deployments additionally require PROCELLA_GITHUB_APP_ENABLED=true; unset or false keeps the integration disabled and removes retained SST secrets.

Encryption keys must be set explicitly in every environment. Generate one with openssl rand -hex 32.

CORS

By default Procella does not mount CORS middleware. Set PROCELLA_CORS_ORIGINS explicitly when you need browser cross-origin access.

Using PROCELLA_CORS_ORIGINS=* is allowed for local experiments, but it enables any origin and should never be used in production.

Reverse proxy and TLS termination

  • Set PROCELLA_TRUST_PROXY=true only when Procella is behind a trusted reverse proxy (for example Caddy or CloudFront) that sanitizes and re-emits client IP headers.
  • When Procella is reached directly, leave PROCELLA_TRUST_PROXY unset so audit logging and rate limiting use the socket peer IP instead of user-supplied forwarded headers.
  • apps/ui/Caddyfile keeps auto_https off because it assumes TLS is terminated upstream. For self-hosted deployments without an upstream TLS terminator, remove auto_https off (or set auto_https on) and configure Caddy for Let's Encrypt.

Quality Gates

bun run check          # biome lint + typecheck + 320 unit tests
bun run e2e            # E2E acceptance tests (89 tests)
bun run check:all      # check + e2e

Documentation

Full documentation is available in the apps/docs/ directory, built with Starlight:

bun run docs:dev       # Start docs dev server
bun run docs:build     # Build static docs site

Project Structure

packages/
  types/              Pulumi protocol types + domain types + errors
  config/             Zod-validated env config (PROCELLA_*)
  db/                 Drizzle schema + dual-driver connection factory (Neon / node-postgres)
  crypto/             AES-256-GCM with HKDF per-stack key derivation
  storage/            Blob storage (local filesystem + S3)
  auth/               Dev mode (static token) + Descope (JWT)
  stacks/             Stack CRUD, rename, tags (PostgreSQL)
  updates/            Update lifecycle, checkpoints, events, GC worker
  api/                @procella/api — tRPC router (stacks, updates, events)
apps/
  server/             @procella/server — Hono HTTP server (CLI + tRPC + middleware)
  ui/                 @procella/ui — React SPA (Vite + Tailwind + tRPC client)
                      Pages: StackList, StackDetail, UpdateDetail, Tokens, Settings, CliLogin
examples/             Pulumi YAML example programs (7 examples)
e2e/                  E2E acceptance tests (89 tests, 9 files)
  docs/               @procella/docs — Starlight documentation site

License

See LICENSE for details.

About

Self hosted Pulumi

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages