Security AWS

Authentik on AWS User Guide

| Product: Authentik

Overview

Authentik is an open source identity provider: single sign-on, multi-factor authentication, user management and access control for the applications your team already runs. It speaks SAML, OAuth2 and OpenID Connect, can act as an LDAP provider for older software, and lets you build custom login, enrolment and recovery journeys in a visual flow editor. Because it is self-hosted, your directory, your credentials and your audit trail stay inside your own AWS account.

This cloudimg image ships the official Authentik production container stack - the server, the background worker and a PostgreSQL 16 database - installed, wired together and managed by systemd. There is no compose file to write and no database to provision by hand.

The appliance is secure by default. On the first boot of every instance, first boot generates a fresh database password, application secret key, admin password and bootstrap API token, so no shared or default credential is ever baked into the image. PostgreSQL publishes no host ports and is reachable only on the internal container network; only SSH and the Authentik web ports are exposed. The whole stateful tier lives on its own EBS volume, resizable independently of the OS disk.

What is included:

  • Authentik 2026.5.3 (ghcr.io/goauthentik/server) - the server container serving the web UI, flows and REST API on host port 80 (and 443)
  • The Authentik background worker container, for scheduled tasks, outpost sync and notifications
  • PostgreSQL 16 (postgres:16-alpine) on the internal container network only, with no published host ports
  • authentik.service - a systemd unit that brings the whole stack up and down
  • authentik-firstboot.service - rotates every per-instance secret before the stack serves
  • A dedicated 40 GiB EBS volume at /var/lib/authentik holding the Compose project, the database, media and certificates
  • Ubuntu 24.04 LTS base, latest patches, unattended security upgrades enabled

Prerequisites

An active AWS account, an EC2 key pair, and a VPC with a subnet. Recommended instance type: m5.large. Scale up if you expect many concurrent authentication flows or plan to run outposts.

Step 1: Launch from the AWS Marketplace

Find Authentik on the AWS Marketplace, subscribe, and launch an instance. In the launch wizard, attach a security group that allows inbound TCP 22 (SSH) and TCP 80 (the Authentik web interface) from your client networks only. Add TCP 443 if you plan to terminate TLS on the instance.

Step 2: Launch from the AWS CLI

AMI_ID="<marketplace-ami-id>"        # from the Marketplace listing, in your region
KEY_NAME="my-key"
SUBNET_ID="subnet-xxxxxxxx"
SG_ID="sg-xxxxxxxx"                  # allows 22 + 80 from your networks only

aws ec2 run-instances \
  --image-id "$AMI_ID" \
  --instance-type m5.large \
  --key-name "$KEY_NAME" \
  --subnet-id "$SUBNET_ID" \
  --security-group-ids "$SG_ID" \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=authentik}]'

Connecting to your instance

Connect over SSH as the login user for your image's operating system. docker.service, authentik-firstboot.service and authentik.service all start automatically on first boot.

Operating system SSH login user Connect
Ubuntu 24.04 LTS ubuntu ssh -i my-key.pem ubuntu@<instance-public-ip>

First boot pulls the container images and runs the initial database migrations, so allow two to three minutes after launch before the web interface answers.

Step 3: Retrieve the Per-Instance Credentials

First boot generates a random admin password and API token for this instance alone and writes them to a root-only file:

sudo cat /root/authentik-credentials.txt

The file records the URL, the admin username and the generated password:

# Authentik self-host - generated on first boot by authentik-firstboot.service
# These credentials are unique to this VM. Store them somewhere safe.

authentik.url=http://<instance-public-ip>/
authentik.admin.username=akadmin
authentik.admin.email=admin@cloudimg.local
AUTHENTIK_ADMIN_PASSWORD=<AUTHENTIK_ADMIN_PASSWORD>

It also carries an authentik.bootstrap.token value - a Bearer token for the REST API, used in Step 7.

Step 4: Verify the Services

Both host units should report active:

systemctl is-active docker authentik
active
active

The container stack should show three services, all running:

sudo docker compose -f /var/lib/authentik/docker-compose.yml ps --format '{{.Service}}\t{{.State}}' | sort
postgresql  running
server  running
worker  running

Confirm the exact images that shipped in this build:

sudo docker ps --format '{{.Names}}\t{{.Image}}'
authentik-worker-1  ghcr.io/goauthentik/server:2026.5.3
authentik-server-1  ghcr.io/goauthentik/server:2026.5.3
authentik-postgresql-1  postgres:16-alpine

Step 5: Check the Health Endpoints

Authentik exposes a readiness endpoint and serves the login flow:

curl -s -o /dev/null -w "health ready: HTTP %{http_code}\n" http://127.0.0.1/-/health/ready/
curl -s -o /dev/null -w "login flow:   HTTP %{http_code}\n" http://127.0.0.1/if/flow/default-authentication-flow/
health ready: HTTP 200
login flow:   HTTP 200

The readiness endpoint is a good target for a load balancer or Auto Scaling health check.

Step 6: Confirm the Database Is Not Network Reachable

This is the security posture of the appliance. PostgreSQL runs on the internal container network and publishes no host ports, so it cannot be reached from outside the instance at all:

sudo ss -tlnp | grep -E ':5432|:6379' || echo "nothing on 5432 - internal container network only"
nothing on 5432 - internal container network only

Only the Authentik web ports are bound to the host:

sudo ss -tlnp | grep -E ':80 |:443 ' | sed 's/users:.*//'
LISTEN 0      4096         0.0.0.0:80        0.0.0.0:*
LISTEN 0      4096         0.0.0.0:443       0.0.0.0:*

Step 7: Prove the API Round-Trip

The credentials file carries a Bearer token for the REST API. This asserts the good token is accepted and a wrong one is rejected - a real authentication round-trip, not just a liveness ping:

TOKEN=$(sudo grep '^authentik.bootstrap.token=' /root/authentik-credentials.txt | cut -d= -f2-)
echo "good token -> $(curl -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer ${TOKEN}" http://127.0.0.1/api/v3/core/users/me/)"
echo "wrong token -> $(curl -s -o /dev/null -w '%{http_code}' -H 'Authorization: Bearer wrong-token-xyz' http://127.0.0.1/api/v3/core/users/me/)"
good token -> 200
wrong token -> 403

Step 8: Confirm the Dedicated Data Volume

The Compose project, the database, media and certificates all live on their own EBS volume, mounted by filesystem UUID so the layout survives reboots and re-launches:

df -h /var/lib/authentik
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1     40G   83M   37G   1% /var/lib/authentik

The volume can be grown in the EC2 console and extended with resize2fs without touching the OS disk.

Step 9: Sign In

Open http://<instance-public-ip>/ in your browser. Sign in as akadmin with the password from Step 3.

Authentik sign in page

Step 10: Explore the Flow Engine

Authentik models every user journey - authentication, authorisation, enrolment, recovery - as a flow: an ordered chain of stages. Go to Flows and Stages > Flows in the admin interface to see the defaults that ship with the image, and to build your own.

The Authentik flow list showing the default authentication, authorisation and enrolment flows

Step 11: Check the Background Worker

The worker container runs scheduled and long-running jobs. Dashboards > System Tasks shows their status, which is the quickest way to confirm the worker is healthy.

System Tasks showing successful background tasks and no errors

Step 12: Add Your First Application

To put SSO in front of an application you create a provider (the protocol side) and an application (what users see):

  1. In the admin interface go to Applications > Providers and create a provider - OAuth2/OpenID for modern apps, SAML for enterprise software, or LDAP for tools that only speak LDAP.
  2. Note the endpoints Authentik generates for that provider.
  3. Go to Applications > Applications, create an application and bind it to the provider.
  4. Configure your application to use those endpoints as its identity provider.
  5. Optionally bind a policy to the application to restrict which users or groups may access it.

Step 13: Enforce Multi-Factor Authentication

Add an MFA stage to the authentication flow and users will be prompted to enrol:

  1. Go to Flows and Stages > Stages and add an Authenticator Validation stage.
  2. Choose the device classes you want to accept, such as TOTP applications or WebAuthn security keys.
  3. Bind that stage into default-authentication-flow at the position you want it enforced.
  4. Add an Authenticator TOTP Setup or WebAuthn Setup stage to an enrolment flow so users can register a device.

Step 14: Managing the Stack

The whole stack is wrapped in one systemd unit:

sudo systemctl status authentik --no-pager
sudo systemctl restart authentik

Container logs are reached through Docker Compose:

sudo docker compose -f /var/lib/authentik/docker-compose.yml logs --tail 30 server

Step 15: Back Up and Restore

The database is the thing to protect. Take a logical dump straight from the container:

sudo docker compose -f /var/lib/authentik/docker-compose.yml exec -T postgresql pg_dump -U authentik authentik > /root/authentik-backup.sql

Because all state lives on the dedicated volume, an EBS snapshot of /var/lib/authentik is also a complete point-in-time backup. Take snapshots on a schedule that matches your recovery objectives.

Step 16: Add TLS (Optional)

Authentik serves plain HTTP on port 80 by default. For production, put your own domain and a TLS certificate in front of it. Either terminate TLS at an AWS Application Load Balancer and forward to port 80, or supply your own certificate to Authentik and use port 443. Whichever you choose, set the external URL in System > Brands so generated links and redirects are correct.

Step 17: Security Recommendations

  • Restrict TCP 80, 443 and 22 in your security group to known client networks only; never leave them open to the whole internet
  • Change the generated akadmin password to one your team manages, and create individual named admin accounts rather than sharing akadmin
  • Enforce MFA on the authentication flow (Step 13) before exposing the instance beyond a trusted network
  • Put TLS in front of the UI before any production use (Step 16)
  • Rotate the bootstrap API token once you have created your own service accounts and tokens
  • Keep the OS patched; unattended security upgrades are enabled by default
  • Snapshot the Authentik data volume on a schedule

Step 18: Support and Licensing

authentik is a trademark of Authentik Security, Inc. The Authentik core is distributed under the MIT License. PostgreSQL is distributed under the PostgreSQL License. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on AWS

Find Authentik on the AWS Marketplace to launch this image in your own account.

Need Help?

cloudimg provides 24/7 technical support for this image, covering deployment, upgrades, provider and application configuration, LDAP and SAML integration, MFA policies, and fronting the UI with your own domain and TLS. Email support@cloudimg.co.uk with your instance ID and a description of the issue.