From SaaS to Self-Hosted: Unlocking On-Prem Power with Authentik

Hi there! I'm Shrijith Venkatrama, founder of Hexmos. Right now, I’m building LiveAPI, a first of its kind tool for helping you automatically index API endpoints across all your repositories. LiveAPI helps you discover, understand and use APIs in large tech infrastructures with ease. Authentik is an open-source identity provider that’s flexible, developer-friendly, and perfect for taking your SaaS application and making it available as an on-premises solution. If you’re looking to give your users the option to host your app themselves—complete with secure authentication—this post will walk you through the process. We’ll dive into why you’d want to go on-prem, how Authentik fits in, and step-by-step examples to make it happen. This guide assumes you’re comfortable with Docker, basic networking, and have a SaaS app that needs authentication. Let’s get started. Why Move Your SaaS to On-Prem? Offering an on-prem version of your SaaS can open new doors. Enterprises love on-prem because it gives them control over their data, compliance, and security. It’s also a way to differentiate your product in a crowded market. But going on-prem isn’t just about slapping your app on a server—it requires rethinking authentication to be secure and self-contained. Authentik shines here. It’s a single sign-on (SSO) solution that supports protocols like OAuth2, SAML, and LDAP, making it ideal for self-hosted setups. Unlike SaaS-only auth providers (think Auth0 or Okta), Authentik runs locally, keeping everything in your users’ control. Key benefits: Full data sovereignty for your users. Support for multiple auth protocols. Easy integration with existing SaaS codebases. What Makes Authentik a Good Fit? Authentik is built for developers who need flexibility. It’s open-source, so you can tweak it to your needs. It’s also containerized, making it a breeze to deploy alongside your app. Whether your SaaS uses Python, Node.js, or Go, Authentik’s API-first design and extensive protocol support make integration straightforward. Here’s a quick comparison of Authentik vs. other auth solutions for on-prem: Feature Authentik Keycloak Okta (On-Prem) Open Source Yes Yes No Containerized Yes Yes No Protocol Support OAuth2, SAML, LDAP OAuth2, SAML, OIDC OAuth2, SAML SaaS-to-On-Prem Fit High Medium Low Community Support Active Active Limited Authentik’s edge is its modern UI and developer-first setup. It’s less clunky than Keycloak and doesn’t lock you into a vendor like Okta. Resource: Check out Authentik’s official docs for a deeper dive into its features. Setting Up Authentik for On-Prem Let’s get Authentik running. We’ll use Docker Compose to spin up Authentik and a PostgreSQL database (its default storage). This setup is production-ready but simple enough for a demo. Step 1: Create a Docker Compose File Here’s a complete docker-compose.yml to get Authentik up and running. This includes Authentik’s server, worker, and a PostgreSQL database. version: '3.8' services: postgresql: image: postgres:12 environment: - POSTGRES_DB=authentik - POSTGRES_USER=authentik - POSTGRES_PASSWORD=your-secure-password volumes: - db:/var/lib/postgresql/data networks: - authentik-net authentik-server: image: ghcr.io/goauthentik/server:latest environment: - AUTHENTIK_SECRET_KEY=your-secret-key - AUTHENTIK_POSTGRESQL__HOST=postgresql - AUTHENTIK_POSTGRESQL__NAME=authentik - AUTHENTIK_POSTGRESQL__USER=authentik - AUTHENTIK_POSTGRESQL__PASSWORD=your-secure-password ports: - "9000:9000" - "9443:9443" depends_on: - postgresql networks: - authentik-net authentik-worker: image: ghcr.io/goauthentik/server:latest command: worker environment: - AUTHENTIK_SECRET_KEY=your-secret-key - AUTHENTIK_POSTGRESQL__HOST=postgresql - AUTHENTIK_POSTGRESQL__NAME=authentik - AUTHENTIK_POSTGRESQL__USER=authentik - AUTHENTIK_POSTGRESQL__PASSWORD=your-secure-password depends_on: - postgresql networks: - authentik-net volumes: db: networks: authentik-net: driver: bridge Output: Run docker-compose up -d to start the services. Authentik will be available at http://localhost:9000. Tips: Replace your-secure-password and your-secret-key with strong values. Use a reverse proxy (e.g., Nginx) for HTTPS in production. Integrating Authentik with Your SaaS App Now that Authentik is running, let’s integrate it with a sample SaaS app. We’ll use a Node.js app with Express and OAuth2 for this example, but the concepts apply to any stack. Step 2: Configure Authentik for OAuth2 Log into Authentik at http://localhost:9000. Create a new Provider (OAuth2) and an Application. Note the Client ID, Client Secret, and Redirect URI (e.g., http://localhost:3000/auth/callback). Step 3: Build a Node.js

May 17, 2025 - 19:18
 0
From SaaS to Self-Hosted: Unlocking On-Prem Power with Authentik

Hi there! I'm Shrijith Venkatrama, founder of Hexmos. Right now, I’m building LiveAPI, a first of its kind tool for helping you automatically index API endpoints across all your repositories. LiveAPI helps you discover, understand and use APIs in large tech infrastructures with ease.

Authentic Dashboard

Authentik is an open-source identity provider that’s flexible, developer-friendly, and perfect for taking your SaaS application and making it available as an on-premises solution. If you’re looking to give your users the option to host your app themselves—complete with secure authentication—this post will walk you through the process. We’ll dive into why you’d want to go on-prem, how Authentik fits in, and step-by-step examples to make it happen.

This guide assumes you’re comfortable with Docker, basic networking, and have a SaaS app that needs authentication. Let’s get started.

Why Move Your SaaS to On-Prem?

Offering an on-prem version of your SaaS can open new doors. Enterprises love on-prem because it gives them control over their data, compliance, and security. It’s also a way to differentiate your product in a crowded market. But going on-prem isn’t just about slapping your app on a server—it requires rethinking authentication to be secure and self-contained.

Authentik shines here. It’s a single sign-on (SSO) solution that supports protocols like OAuth2, SAML, and LDAP, making it ideal for self-hosted setups. Unlike SaaS-only auth providers (think Auth0 or Okta), Authentik runs locally, keeping everything in your users’ control.

Key benefits:

  • Full data sovereignty for your users.
  • Support for multiple auth protocols.
  • Easy integration with existing SaaS codebases.

What Makes Authentik a Good Fit?

Authentik is built for developers who need flexibility. It’s open-source, so you can tweak it to your needs. It’s also containerized, making it a breeze to deploy alongside your app. Whether your SaaS uses Python, Node.js, or Go, Authentik’s API-first design and extensive protocol support make integration straightforward.

Here’s a quick comparison of Authentik vs. other auth solutions for on-prem:

Feature Authentik Keycloak Okta (On-Prem)
Open Source Yes Yes No
Containerized Yes Yes No
Protocol Support OAuth2, SAML, LDAP OAuth2, SAML, OIDC OAuth2, SAML
SaaS-to-On-Prem Fit High Medium Low
Community Support Active Active Limited

Authentik’s edge is its modern UI and developer-first setup. It’s less clunky than Keycloak and doesn’t lock you into a vendor like Okta.

Resource: Check out Authentik’s official docs for a deeper dive into its features.

Setting Up Authentik for On-Prem

Let’s get Authentik running. We’ll use Docker Compose to spin up Authentik and a PostgreSQL database (its default storage). This setup is production-ready but simple enough for a demo.

Step 1: Create a Docker Compose File

Here’s a complete docker-compose.yml to get Authentik up and running. This includes Authentik’s server, worker, and a PostgreSQL database.

version: '3.8'
services:
  postgresql:
    image: postgres:12
    environment:
      - POSTGRES_DB=authentik
      - POSTGRES_USER=authentik
      - POSTGRES_PASSWORD=your-secure-password
    volumes:
      - db:/var/lib/postgresql/data
    networks:
      - authentik-net

  authentik-server:
    image: ghcr.io/goauthentik/server:latest
    environment:
      - AUTHENTIK_SECRET_KEY=your-secret-key
      - AUTHENTIK_POSTGRESQL__HOST=postgresql
      - AUTHENTIK_POSTGRESQL__NAME=authentik
      - AUTHENTIK_POSTGRESQL__USER=authentik
      - AUTHENTIK_POSTGRESQL__PASSWORD=your-secure-password
    ports:
      - "9000:9000"
      - "9443:9443"
    depends_on:
      - postgresql
    networks:
      - authentik-net

  authentik-worker:
    image: ghcr.io/goauthentik/server:latest
    command: worker
    environment:
      - AUTHENTIK_SECRET_KEY=your-secret-key
      - AUTHENTIK_POSTGRESQL__HOST=postgresql
      - AUTHENTIK_POSTGRESQL__NAME=authentik
      - AUTHENTIK_POSTGRESQL__USER=authentik
      - AUTHENTIK_POSTGRESQL__PASSWORD=your-secure-password
    depends_on:
      - postgresql
    networks:
      - authentik-net

volumes:
  db:

networks:
  authentik-net:
    driver: bridge

Output: Run docker-compose up -d to start the services. Authentik will be available at http://localhost:9000.

Tips:

  • Replace your-secure-password and your-secret-key with strong values.
  • Use a reverse proxy (e.g., Nginx) for HTTPS in production.

Integrating Authentik with Your SaaS App

Now that Authentik is running, let’s integrate it with a sample SaaS app. We’ll use a Node.js app with Express and OAuth2 for this example, but the concepts apply to any stack.

Step 2: Configure Authentik for OAuth2

  1. Log into Authentik at http://localhost:9000.
  2. Create a new Provider (OAuth2) and an Application.
  3. Note the Client ID, Client Secret, and Redirect URI (e.g., http://localhost:3000/auth/callback).

Step 3: Build a Node.js App with OAuth2

Here’s a complete Node.js app that uses Authentik for login. It uses the passport library with the passport-oauth2 strategy.

const express = require('express');
const passport = require('passport');
const OAuth2Strategy = require('passport-oauth2').Strategy;
const session = require('express-session');
const app = express();

// Configure session
app.use(session({
  secret: 'your-session-secret',
  resave: false,
  saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

// Passport setup
passport.use(new OAuth2Strategy({
  authorizationURL: 'http://localhost:9000/application/o/authorize/',
  tokenURL: 'http://localhost:9000/application/o/token/',
  clientID: 'your-client-id',
  clientSecret: 'your-client-secret',
  callbackURL: 'http://localhost:3000/auth/callback'
},
(accessToken, refreshToken, profile, done) => {
  // In a real app, fetch user profile from Authentik
  return done(null, { id: 'user1', accessToken });
}));

passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));

// Routes
app.get('/', (req, res) => {
  if (req.user) {
    res.send(`Hello, user ${req.user.id}!`);
  } else {
    res.send('Login with Authentik');
  }
});

app.get('/auth/login', passport.authenticate('oauth2'));

app.get('/auth/callback',
  passport.authenticate('oauth2', { failureRedirect: '/' }),
  (req, res) => res.redirect('/')
);

app.listen(3000, () => console.log('App running on http://localhost:3000'));
// Output: App running on http://localhost:3000

Dependencies: Install with npm install express passport passport-oauth2 express-session.

Output: Visit http://localhost:3000, click “Login with Authentik,” and authenticate. After login, you’ll see a greeting with the user ID.

Resource: See Passport’s OAuth2 docs for more configuration options.

Handling User Management in On-Prem

On-prem users expect to manage their own users without relying on your SaaS’s cloud. Authentik’s admin interface lets users create, edit, and delete accounts locally. You can also integrate with existing LDAP or Active Directory setups for enterprise clients.

Example tasks:

  • Create users via Authentik’s UI (http://localhost:9000/admin).
  • Sync with LDAP using Authentik’s LDAP provider.

For programmatic user management, use Authentik’s API. Here’s an example of creating a user via the API:

#!/bin/bash
curl -X POST http://localhost:9000/api/v3/users/ \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "newuser",
    "name": "New User",
    "email": "newuser@example.com",
    "password": "securepassword123"
  }'
# Output: {"pk": 1, "username": "newuser", "name": "New User", "email": "newuser@example.com"}

Note: Replace your-api-token with a token generated from Authentik’s admin panel.

Securing Your On-Prem Deployment

Security is critical for on-prem setups. Authentik handles auth securely, but you need to lock down the deployment. Here’s a checklist:

Task Why It Matters How to Do It
Enable HTTPS Protects data in transit Use a reverse proxy like Nginx
Restrict Admin Access Prevents unauthorized changes Use network rules or Authentik’s RBAC
Rotate Secrets Reduces risk of leaks Update AUTHENTIK_SECRET_KEY regularly
Backup Database Ensures data recovery Schedule PostgreSQL backups

Example: To enable HTTPS, add Nginx as a reverse proxy. Here’s a basic config:

server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

location / {
proxy_pass http://localhost:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Output: Run nginx -t to test the config, then nginx -s reload to apply.

Testing Your On-Prem Setup

Before shipping your on-prem solution, test it thoroughly. Simulate a customer’s environment by deploying on a clean VM or Docker host. Key tests:

  • Auth flow: Ensure login, logout, and token refresh work.
  • User management: Test user creation and deletion.
  • Performance: Check response times under load (use tools like ab or locust).

Example test script (using curl to verify login):

#!/bin/bash
curl -X POST http://localhost:9000/application/o/token/ \
  -d "grant_type=password" \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret" \
  -d "username=testuser" \
  -d "password=testpassword"
# Output: {"access_token": "...", "token_type": "Bearer", "expires_in": 3600}

Note: Create a test user in Authentik first.

Scaling Authentik for Enterprise Needs

For larger on-prem deployments, you’ll need to scale Authentik. Horizontal scaling is supported by running multiple Authentik server and worker instances. Use a load balancer to distribute traffic.

Scaling tips:

  • Increase PostgreSQL connection limits.
  • Use Redis for caching (optional, see Authentik docs).
  • Monitor with Prometheus (Authentik exposes metrics).

Here’s how Authentik’s architecture supports scaling:

Component Scaling Method Notes
Server Multiple instances Stateless, load-balanced
Worker Multiple instances Handles background tasks
Database Vertical or replication PostgreSQL is the bottleneck

Resource: Read Authentik’s deployment guide for scaling details.

Next Steps for Your On-Prem Journey

You’ve got Authentik running, integrated with your app, and secured for on-prem use. Now what? Focus on packaging your solution for easy customer deployment. Tools like Helm (for Kubernetes) or Ansible can simplify installation. Also, document everything—your users will need clear instructions for setup, user management, and troubleshooting.

Action items:

  • Create a README.md with step-by-step install instructions.
  • Offer a demo VM or Docker image for trials.
  • Set up a support channel (e.g., Discord or email) for on-prem users.

By combining Authentik’s flexibility with a solid deployment strategy, you’re giving your users the best of both worlds: the power of your SaaS, hosted on their terms.