Skip to main content

🛡️ Dagster AuthKit

Python Version Build Status License Coverage PyPI Version GitHub Repo stars Downloads Downloads

Community authentication wrapper for self-hosted Dagster OSS.

Authentication, RBAC, and Audit logs for Dagster without touching internal code.


🎯 What is this?

Dagster OSS has no auth. If you run it in a VPC or locally, anyone with the URL has full admin access.

AuthKit solves this by wrapping the dagster-webserver command to add:

  • ✅ Login Interface: Simple username/password flow.
  • ✅ RBAC (4 Levels): Granular control over who can do what.
  • ✅ Audit Logs: JSON logs for monitoring who is doing what.
  • ✅ Multi-Backend: Works with SQLite, Postgres, MySQL (via Peewee ORM) and Redis.

No code changes required. You don't touch your repository.py or dagster.yaml.


✨ What's New in v1.0.0

☸️ Helm Chart

  • Production-ready Kubernetes chart under helm/dagster-authkit/, synced with the application's config (env vars, secrets, image tag) and versioned automatically on each release.

🔄 Automated CHANGELOG

  • CHANGELOG.md is now auto-generated on each release, alongside the version bump.
  • RBAC deny-by-default — unknown GraphQL mutations require ADMIN by default.

🔐 Hardening & Fixes

  • Rebuild of the fix backlog from v0.4.2 across CSRF (per-client double-submit), fail-closed GraphQL batches, token-gated /auth/metrics, Redis 6-compatible atomic rate limiting, LDAP connection cleanup, session revoked-token caps, and detection-layer Starlette Middleware.cls compatibility.
  • Test coverage boosted 44% → 52% (+98 tests: detection layer, rate limiter, metrics gate, CookieBackend, CLI, LDAP, middleware).

⚠️ Upgrading from v0.3.x

  1. Set DAGSTER_AUTH_SECRET_KEY in your environment. Generate one with:
    python -c 'import secrets; print(secrets.token_urlsafe(32))'
    
  2. If using proxy mode, set DAGSTER_AUTH_PROXY_TRUSTED_IPS to your proxy's IP address.
  3. Database migration happens automatically on first boot — no manual steps needed for SQLite/Postgres/MySQL. A session_version column is added to the users table.
  4. Role serialization changed from string ("ADMIN") to int (40) in session cookies. Existing sessions continue to work (backward-compatible from_dict).

📂 Ready-to-Run Examples

We provide ready-to-use stacks for different scenarios in the examples/ directory:

examples
├── authelia              # NEW! Authelia + Caddy + LDAP SSO (Docker)
│   ├── Makefile
│   ├── docker-compose.yml
│   ├── Caddyfile
│   └── authelia/
├── kubernetes            # NEW! Minikube deployment
│   ├── Makefile
│   └── k8s/
├── ldap                  # Active Directory integration (**Experimental**)
│   ├── Makefile
│   ├── docker-compose.yml
│   └── ldap-bootstrap.ldif
├── postgresql_redis      # Recommended production setup
│   ├── Makefile
│   └── docker-compose.yml
└── quickstart-sqlite     # Simple local testing
    ├── Makefile
    └── docker-compose.yml

How to run

Pick a scenario, go into the folder, and check the Makefile.

1. Authelia SSO (Docker) Complete SSO with Authelia, Caddy, and OpenLDAP:

cd examples/authelia
make up
# Access: https://auth.company.com (admin/password123)
# Then:   https://dagster.company.com

2. Kubernetes (Minikube) Same stack running on Kubernetes:

cd examples/kubernetes
make build  # Build the Docker image inside Minikube
make up     # Deploy everything
# In another terminal: make connect (runs minikube tunnel)
# Add to /etc/hosts: $(minikube ip) auth.company.com dagster.company.com

3. Standard Setup (Postgres + Redis)

cd examples/postgresql_redis
make up

4. Local Quickstart (SQLite)

cd examples/quickstart-sqlite
make up

5. LDAP/AD Testing ⚠️ EXPERIMENTAL

cd examples/ldap
make up

🚀 Manual Installation (Python)

If you aren't using Docker, you can install via pip.

# For local testing (SQLite)
pip install dagster-authkit[sqlite]

# For server usage (Postgres + Redis recommended)
pip install dagster-authkit[postgresql,redis]

# For LDAP/Active Directory integration (**Experimental**)
pip install dagster-authkit[ldap]

Usage:

# Initialize the database and create the first admin
dagster-authkit init-db --with-admin

# Run Dagster (replaces the standard 'dagster-webserver' command)
dagster-authkit -f your_pipeline.py -h 0.0.0.0 -p 3000

# For proxy mode (Authelia/OAuth2 Proxy)
export DAGSTER_AUTH_BACKEND=proxy
export DAGSTER_AUTH_PROXY_LOGIN_URL=https://auth.yourcompany.com
dagster-authkit -f your_pipeline.py -h 0.0.0.0 -p 3000

☸️ Helm (Kubernetes)

The chart is published as an OCI artifact on GHCR, together with the container image:

helm upgrade --install dagster-authkit oci://ghcr.io/maltzsama/charts/dagster-authkit \
  --set authkit.secretKey="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" \
  --set authkit.adminPassword="your-admin-password"

See the chart README for configuration and examples.


🔐 Roles (RBAC)

We provide 4 levels of access. Permissions are enforced via GraphQL query analysis.

Role Description
Admin Full access. Can manage users, settings, and all pipelines.
Editor Can modify assets and codebase (if allowed) and manage runs.
Launcher Can launch runs and re-execute jobs, but cannot modify code/assets.
Viewer Read-only. Can view runs and assets. GraphQL mutations are blocked.

How it works: AuthKit analyzes GraphQL queries using the official GraphQL parser to accurately identify mutations and block unauthorized actions.


📦 Backends

Backend Implementation Status Use Case
SQLite Peewee ORM Stable Local / Simple. Single instance only.
PostgreSQL Peewee + psycopg2 Stable Production. Recommended for Docker/K8s.
MySQL/MariaDB Peewee + mysql-connector Stable Production.
Redis Native redis Stable Session Storage + Distributed Rate Limiting.
LDAP ldap3 library Experimental Active Directory / OpenLDAP. Community maintained.
Proxy Header-based Stable Authelia, OAuth2 Proxy, Traefik, Caddy.
OpenID Connect Header-based Experimental AuthKit supports OIDC providers (Google, GitHub, Okta, Keycloak) via Authelia

🤖 Service Token (API clients)

Non-interactive clients that poll /graphql (Prometheus exporters, CI scripts) cannot go through the login form. Set a static service token to let them authenticate with a header instead:

export DAGSTER_AUTH_SERVICE_TOKEN=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')
Env var Default Purpose
DAGSTER_AUTH_SERVICE_TOKEN unset Shared secret (min 32 chars). Feature is off when unset.
DAGSTER_AUTH_SERVICE_TOKEN_HEADER Dagster-Cloud-Api-Token Header carrying the token.
DAGSTER_AUTH_SERVICE_TOKEN_ROLE VIEWER Role granted to the token.
DAGSTER_AUTH_SERVICE_TOKEN_USER service-token Username shown in audit logs.
curl -H "Dagster-Cloud-Api-Token: $DAGSTER_AUTH_SERVICE_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"query": "{ version }"}' https://dagster.yourcompany.com/graphql

The token goes through the same RBAC as any user, so a VIEWER token can run queries but every mutation is denied and audit-logged. It is a static, non-expiring credential: keep it at VIEWER unless the client really needs more. Session backends only (ignored in proxy mode); WebSocket subscriptions remain cookie-only.


🛠️ CLI Management

Manage users directly from the shell. Useful for CI/CD or admin tasks.

# Create a new launcher
dagster-authkit add-user bob --launcher

# Reset password
dagster-authkit change-password bob

# List everyone
dagster-authkit list-users

# View RBAC permissions matrix
dagster-authkit list-permissions

🔮 Roadmap

Current (v1.0.0)

  • ✅ Username/password auth (bcrypt)
  • ✅ 4-level RBAC (ADMIN/EDITOR/LAUNCHER/VIEWER)
  • ✅ SQLite, PostgreSQL, MySQL, Redis support
  • ✅ GraphQL mutation blocking with official AST parser
  • ✅ LDAP backend (experimental)
  • ✅ Proxy authentication (Authelia, Caddy, Traefik)
  • ✅ Kubernetes example with full SSO stack
  • ✅ Helm chart for Kubernetes deployments
  • ✅ Redis session revocation and rate limiting
  • ✅ Centralized UI templates
  • ✅ CSRF protection
  • ✅ Cross-pod session revocation (DB-backed session_version)
  • ✅ WebSocket authentication (GraphQL subscriptions)
  • ✅ Dual rate-limiting (username + IP)
  • ✅ Proxy trusted IP allowlist
  • ✅ Token-protected /auth/metrics
  • ✅ Service token for non-interactive API clients
  • ✅ Automated CHANGELOG.md generation

Next

  • 🔄 OIDC backend (beyond proxy mode)

What we will NOT do:

  • ❌ Inject React code into Dagster UI (too brittle)
  • ❌ Complex enterprise features (that's what Dagster+ is for)

🤝 Contributing

Found a bug? Want to add a feature? Open a PR. If it works and keeps things simple, we'll merge it.

Especially needed:

  • People with Active Directory experience to validate the LDAP backend
  • Testing on different Dagster versions
  • Helm chart contributions

📄 License

Apache 2.0 - see LICENSE


🙏 Credits

Built by Demetrius Albuquerque because self-hosting Dagster shouldn't mean no auth.

Inspired by the community's need for a middle ground between "no auth" and "pay for Dagster+".

Metadata

Release files for dagster-authkit 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dagster-authkit 1.2.0
File Size Uploaded
dagster_authkit-1.2.0.tar.gz 121.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dagster-authkit 1.2.0
File Interpreter ABI Platform
dagster_authkit-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 205.6 kB

Release files / dagster_authkit-1.2.0.tar.gz

Download URL dagster_authkit-1.2.0.tar.gz
Size 121.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3bea577a536330da9c19e145d13cf834e0c2a3595143ddd73f6b896b63a2e19e
BLAKE2b-256 checksum
How to use checksums
09ded408f2cfeb00b9a79840cf1098d564dfe2e73da13b4742a72aeda22dff98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / dagster_authkit-1.2.0-py3-none-any.whl

Download URL dagster_authkit-1.2.0-py3-none-any.whl
Size 84.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e07a0e9e9b9838a080e42b11f467b66a7e65059e60cac86c6aabbf9aab28e2a7
BLAKE2b-256 checksum
How to use checksums
f965d3c9e4f15cc5e953983d8688693b2cef018911e77e397130ca3b50d9d97b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page