Get Pangolin 0.6.0 running with Docker, binaries, or a Helm chart โ and set the four environment variables this release now requires.
โ ๏ธ ALPHA โ v0.6.0
Earlier versions contained a remotely exploitable OAuth account-takeover path, a working default JWT signing secret published in the repository, an authentication bypass, an unauthenticated denial-of-service primitive, and an Iceberg commit path that could silently fork snapshot lineage under concurrent writers. If you are running 0.5.x or earlier, upgrade and rotate credentials.
Pangolin is alpha, pre-1.0 software under active hardening. This means:
Read the full production readiness status before deploying anything you care about. We encourage you to test, provide feedback, and contribute.
0.6.0 removed every insecure default. The server will not start without real values โ which is the point.
# Required. The server refuses to start without it and rejects known # placeholders. Setting it invalidates every existing session. PANGOLIN_JWT_SECRET=$(openssl rand -base64 48) # Required if you seed an admin user. There is no default. PANGOLIN_ADMIN_PASSWORD=... # Required if you use OAuth. Redirect targets are allowlisted by exact # match; FRONTEND_URL is always permitted. PANGOLIN_OAUTH_REDIRECT_URIS=https://catalog.example.com/auth/callback # Recommended. The default allows any origin, which is only safe behind # a trusted gateway. PANGOLIN_CORS_ALLOWED_ORIGINS=https://catalog.example.com # Pick your metadata backend. PANGOLIN_STORAGE_TYPE is honoured from # 0.6.0 โ before this release it was read and never used. PANGOLIN_STORAGE_TYPE=postgres DATABASE_URL=postgres://...
openssl rand -base64 48 and set PANGOLIN_JWT_SECRET. Existing sessions end.PANGOLIN_OAUTH_REDIRECT_URIS and update clients to the code-exchange flow โ the callback now carries code, not token, redeemed at POST /api/v1/oauth/exchange.PANGOLIN_ADMIN_PASSWORD.pgl_<key-id>_<secret> format, or set PANGOLIN_ALLOW_LEGACY_API_KEYS=true temporarily./health/live and /health/ready. /health still works and is equivalent to readiness.tenant_impersonation, login_failed and api_key_rejected events, which are recorded from 0.6.0 onward.Unsupported Iceberg commit operations now return 501 where they previously returned 200 OK and silently did nothing. A client that appeared to work against 0.5.x may now surface a real error โ that error was always true, it just was not reported.
New in 0.6.0. Before this release /health returned 200 whether or not the database was reachable, and RUST_LOG was silently ignored.
Two distinct endpoints, so a pod with a dead database leaves the Service instead of staying in it.
/health/live โ process only/health/ready โ store round-tripRED metrics per route, commit success/conflict/retry counters, authentication outcomes, audit-write failures, cache hit rates and a readiness gauge at /metrics. A ServiceMonitor template ships with the chart.
RUST_LOG works, LOG_FORMAT=json emits structured logs, and request correlation IDs โ honoured from a trusted gateway's x-request-id โ are attached to every log line and echoed on the response.
SIGTERM and SIGINT stop readiness immediately and drain in-flight requests. Request body-size, per-request timeout and global concurrency limits are all enforced; before 0.6.0 there were none of any kind.
/metrics publiclyIt is unauthenticated by design so Prometheus can scrape it. Restrict it at the network layer, or set PANGOLIN_METRICS_ENABLED=false if you cannot.
Choose your deployment method:
Download ready-to-run binaries for your platform:
Binaries are automatically built for all platforms via GitHub Actions and attached to each release.
Native binaries for both Intel and Apple Silicon Macs.
Download from Releasespangolin_api - REST API server (~60MB)pangolin-admin - Admin CLI tool (~10MB)pangolin-user - User CLI tool (~10MB)Documentation: Binary Usage Guide
Get started in minutes with pre-configured Docker Compose environments
Perfect for quick evaluation and testing. Includes Jupyter notebook for PyIceberg testing.
Full-featured setup with authentication and persistent storage.
cd deployment_assets/demo/evaluate_single_tenant docker compose up -d # Access: # - UI: http://localhost:3000 # - API: http://localhost:8080 # - Jupyter: http://localhost:8888 # - MinIO: http://localhost:9001
Official Docker images published to Docker Hub. From 0.6.0 the server, both CLIs, the Python SDK, the UI and the Helm chart all carry the same version number.
tini, not as root--locked builds with dependency-caching layers and OCI labelslibssl3 rather than the libssl-dev development packageHEALTHCHECK, via a --healthcheck mode on the binaryCI asserts on every build that the image does not run as root.
Reference configurations for various cloud providers and databases. Read the readiness status first โ these show you how to wire Pangolin up, not that Pangolin is production-proven.
Deploy to Kubernetes using our Helm charts:
The chart version jumped from 0.1.0 to 0.6.0 to match everything else, and was substantially repaired in this release.
values.yaml but did not exist before 0.6.0, so enabling autoscaling removed the replica count and created no autoscaler, and pods referenced a ServiceAccount that was never createdPodDisruptionBudget and a ServiceMonitorrunAsNonRoot, readOnlyRootFilesystem, all capabilities dropped, RuntimeDefault seccompresources: {} previously put pods in the BestEffort QoS class, first to be evicted under node pressureimage.tag pinned to the release instead of latesthelm lint and helm template now run in CIIt previously shipped change-me-please and password as working defaults. It now refuses to render without a real PANGOLIN_JWT_SECRET. Prefer existingSecret over putting the value in values.yaml.
Multiple replicas work but are unproven. The background token-cleanup job runs in every replica with no coordination, and the OAuth nonce store is in-process โ so OAuth requires session affinity. The warehouse cache is also node-local with a 5-second default TTL, so a rotated credential can briefly be served by a peer.
Provision cloud infrastructure with Terraform:
Pangolin is open source and we welcome contributions!