Deployment Guide

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
Pangolin mascot waving hello

๐Ÿ” 0.6.0 is a security release โ€” upgrade from anything earlier

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.

Read the advisory โ†’

โš ๏ธ Alpha Software Notice

Pangolin is alpha, pre-1.0 software under active hardening. This means:

  • Breaking changes may land in a minor release โ€” 0.6.0 itself contains several
  • Backup, restore and disaster recovery are undocumented and untested; there is no published RPO or RTO
  • There is no rate limiting on authentication endpoints
  • Warehouse cloud credentials are stored unencrypted in the catalog database
  • Not all of the Iceberg REST spec is implemented, and MongoDB is beta

Read the full production readiness status before deploying anything you care about. We encourage you to test, provide feedback, and contribute.

๐Ÿ”‘ Required Configuration in 0.6.0

0.6.0 removed every insecure default. The server will not start without real values โ€” which is the point.

Minimum viable environment

# 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://...

Upgrading from 0.5.x

  1. Generate a signing secret with openssl rand -base64 48 and set PANGOLIN_JWT_SECRET. Existing sessions end.
  2. If you use OAuth, set 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.
  3. If you seed an admin, set PANGOLIN_ADMIN_PASSWORD.
  4. Rotate service-user API keys to the new pgl_<key-id>_<secret> format, or set PANGOLIN_ALLOW_LEGACY_API_KEYS=true temporarily.
  5. Repoint Kubernetes probes at /health/live and /health/ready. /health still works and is equivalent to readiness.
  6. Roll one replica first. Schema migrations are additive and applied under an advisory lock, so a brief mixed-version window is safe.
  7. Review your audit log for tenant_impersonation, login_failed and api_key_rejected events, which are recorded from 0.6.0 onward.

One behavioural change worth planning for

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.

๐Ÿ“ˆ Observability

New in 0.6.0. Before this release /health returned 200 whether or not the database was reachable, and RUST_LOG was silently ignored.

Health Probes

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-trip

Prometheus Metrics

RED 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.

Structured Logging

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.

Graceful Shutdown

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.

Do not expose /metrics publicly

It is unauthenticated by design so Prometheus can scrape it. Restrict it at the network layer, or set PANGOLIN_METRICS_ENABLED=false if you cannot.

๐Ÿš€ Quick Start

Choose your deployment method:

๐Ÿ“ฆ Pre-compiled Binaries

Download ready-to-run binaries for your platform:

๐Ÿ“ Binary Locations

Binaries are automatically built for all platforms via GitHub Actions and attached to each release.

๐Ÿง Linux (x86_64)

Ready to use! Includes API server and CLI tools.

Download from Releases

๐ŸŽ macOS (Intel & ARM)

Native binaries for both Intel and Apple Silicon Macs.

Download from Releases

๐ŸชŸ Windows (x86_64)

Windows executables with .exe extensions.

Download from Releases

What's Included

Documentation: Binary Usage Guide

๐ŸŽฏ Demo Setups (Docker Compose)

Get started in minutes with pre-configured Docker Compose environments

Pangolin using laptop

Single Tenant (No Auth)

Perfect for quick evaluation and testing. Includes Jupyter notebook for PyIceberg testing.

  • No authentication required
  • Memory-based storage
  • MinIO for S3-compatible storage
  • Jupyter notebook on port 8888
View Setup

Multi-Tenant (Authenticated)

Full-featured setup with authentication and persistent storage.

  • JWT authentication enabled
  • SQLite for persistent metadata
  • MinIO for S3-compatible storage
  • Jupyter notebook on port 8888
View Setup

Quick Start Command

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

๐Ÿณ Docker Images

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.

API Server

alexmerced/pangolin-api:0.6.0

View on Docker Hub

CLI Tools

alexmerced/pangolin-cli:0.6.0

View on Docker Hub

Management UI

alexmerced/pangolin-ui:0.6.0

View on Docker Hub

The container was hardened in 0.6.0

  • Runs as a non-root user (UID 10001) under tini, not as root
  • --locked builds with dependency-caching layers and OCI labels
  • Ships libssl3 rather than the libssl-dev development package
  • A base image matching the Rust version the project requires
  • A real HEALTHCHECK, via a --healthcheck mode on the binary
  • Test fixtures no longer ship in the release binary

CI asserts on every build that the image does not run as root.

Pangolin holding database

๐Ÿญ Production Deployments

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.

Docker Compose (Production)

AWS S3 + PostgreSQL

Production setup for AWS with RDS PostgreSQL.

View Config

AWS S3 + MongoDB

Production setup for AWS with MongoDB Atlas.

View Config

Azure Blob + PostgreSQL

Production setup for Azure with PostgreSQL.

View Config

Azure Blob + MongoDB

Production setup for Azure with MongoDB.

View Config

GCP GCS + PostgreSQL

Production setup for Google Cloud with Cloud SQL.

View Config

GCP GCS + MongoDB

Production setup for Google Cloud with MongoDB.

View Config

Kubernetes (Helm Charts)

Deploy to Kubernetes using our Helm charts:

Pangolin Helm Chart โ€” v0.6.0

The chart version jumped from 0.1.0 to 0.6.0 to match everything else, and was substantially repaired in this release.

  • Supports PostgreSQL and MongoDB backends
  • Example values for AWS, Azure, and GCP
  • Ingress, TLS and autoscaling โ€” all three of these templates were referenced by 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 created
  • Adds a PodDisruptionBudget and a ServiceMonitor
  • Hardened pod defaults: runAsNonRoot, readOnlyRootFilesystem, all capabilities dropped, RuntimeDefault seccomp
  • Real resource requests and limits โ€” resources: {} previously put pods in the BestEffort QoS class, first to be evicted under node pressure
  • image.tag pinned to the release instead of latest
  • helm lint and helm template now run in CI
View Helm Charts

The chart will not install without a real signing secret

It 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.

Before you scale past one replica

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.

Infrastructure as Code (Terraform)

Provision cloud infrastructure with Terraform:

AWS Module

Provisions S3 bucket and RDS PostgreSQL.

View Module

Azure Module

Provisions Blob Storage and Azure Database for PostgreSQL.

View Module

GCP Module

Provisions GCS bucket and Cloud SQL PostgreSQL.

View Module

๐Ÿ“š Documentation

Getting Started

Installation, configuration, and first steps.

Read Docs

CLI Tools

Admin and user CLI tools, including Docker usage.

Read Docs

PyIceberg Integration

Connect PyIceberg to Pangolin with examples.

Read Docs

Management UI Guide

Visual guide to the administration portal.

Read Docs

Production Runbook

Health, metrics, incident response, upgrades and backup โ€” including where the gaps are.

Read Docs

Backend Parity Matrix

Which features work on Memory, SQLite, PostgreSQL and MongoDB.

Read Docs

OAuth / SSO

Configuration, the 0.6.0 client change, and the OIDC features that are not implemented.

Read Docs

Security Policy

The 0.6.0 advisory, the hardening checklist, and the known gaps.

Read Docs

๐Ÿค Join the Community

Pangolin is open source and we welcome contributions!

How to Contribute:

Resources: