Authentik Basic Configuration

Disclaimer

I am new to Authentik, follow these steps at your own risk, this is simply a guide based on how I configured it, there may be misleading steps in here that I am unaware of being a problem.

Intro

I recently went through the process of setting up Authentik, and I found that there wasn't a clear, step-by-step guide available. While the official documentation is comprehensive, it can be overwhelming for someone new to Authentik. In this post, I'll share my experience and provide a concise guide on how to set up Authentik.

Initially, I searched for videos that covered the basic setup process of Authentik, but most resources focused on integrating it with Traefik. This led me down a rabbit hole of learning about Traefik, which wasn't necessary for my use case. After digging through articles and documentation, I realized that there's a lack of resources that cover just the basics.

It appears that integration with Traefik might actually make things easier in the long run, as it allows you to leverage labels on each container to configure Authentik. This could potentially simplify the setup process and reduce the need for manual configuration within Authentik itself.

Terms to know

Outposts

To my understanding, Authentik outposts are used to route traffic and add the authentication portal in between.

Setting Up an Outpost

  1. Click on outposts in Authentik
  2. Click Create a new Outpost
  3. Set up a Docker container to point to that Outpost
  4. Verify the connection: In Authentik once it shows last connected with a time and date within the last 30 minutes, you know you've set it up correctly. ## Initial Setup I recommend following the official authentik documentation for setting it up, but here is how I configured it in my docker stack
  5. Add the Authentik Container
    1. Add the Authentik container to your stack: Start by adding the official Authentik container to your Docker setup.
services:
  authentik-postgres:
    image: docker.io/library/postgres:16.4 #It is never a good idea to use the :latest tag for your image, select a version and manually update it
    container_name: authentik-postgres
    environment:
      - POSTGRES_USER=${AUTHENTIK_POSTGRES_USER}
      - POSTGRES_PASSWORD=${AUTHENTIK_POSTGRES_PASSWORD}
      - POSTGRES_DB=${AUTHENTIK_POSTGRES_DB}
      - TZ=${TZ}
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U "${AUTHENTIK_POSTGRES_USER}"']
      start_period: 30s
      interval: 10s
      timeout: 10s
      retries: 5
    volumes:
      - authentik_postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      vpcbr:
        ipv4_address: 172.20.0.10 #Set an IP in your docker network, I am not a fan of using hostnames, you will use this IP to point your cloudflare zero trust DNS records

  authentik-redis:
    image: docker.io/library/redis:7.4.0 #It is never a good idea to use the :latest tag for your image, select a version and manually update it
    container_name: authentik-redis
    command: --save 60 1 --loglevel warning
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    volumes:
      - authentik_redis_data:/data
    restart: unless-stopped
    environment:
      - TZ=${TZ}
    networks:
      vpcbr:
        ipv4_address: 172.20.0.11 #Set an IP in your docker network

  authentik-server:
    image: ghcr.io/goauthentik/server:2024.8.0 #It is never a good idea to use the :latest tag for your image, select a version and manually update it
    container_name: authentik-server
    command: server
    environment:
      - AUTHENTIK_REDIS__HOST=authentik-redis #If logs show issues communicating with redis replace this with the IP for that container, IE: 172.20.0.11
      - AUTHENTIK_POSTGRESQL__HOST=authentik-postgres #If logs show issues communicating with the database replace this with the IP for that container, IE: 172.20.0.10
      - AUTHENTIK_POSTGRESQL__USER=${POSTGRES_USER}
      - AUTHENTIK_POSTGRESQL__NAME=${POSTGRES_DB}
      - AUTHENTIK_POSTGRESQL__PASSWORD=${POSTGRES_PASSWORD}
      # (Required)  To generate a secret key run the following command:
      #             echo $(openssl rand -base64 32)
      - AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
      # (Optional)  Enable Error Reporting
      - AUTHENTIK_ERROR_REPORTING__ENABLED=${AUTHENTIK_ERROR_REPORTING:-false}
      # (Optional)  Enable Email Sending
      - AUTHENTIK_EMAIL__HOST=${AUTHENTIK_EMAIL_HOST}
      - AUTHENTIK_EMAIL__PORT=${AUTHENTIK_EMAIL_PORT}
      - AUTHENTIK_EMAIL__USERNAME=${AUTHENTIK_EMAIL_USERNAME}
      - AUTHENTIK_EMAIL__PASSWORD=${AUTHENTIK_EMAIL_PASSWORD}
      - AUTHENTIK_EMAIL__USE_TLS=${AUTHENTIK_EMAIL_USE_TLS}
      - AUTHENTIK_EMAIL__USE_SSL=${AUTHENTIK_EMAIL_USE_SSL}
      - AUTHENTIK_EMAIL__TIMEOUT=${AUTHENTIK_EMAIL_TIMEOUT}
      - AUTHENTIK_EMAIL__FROM=${AUTHENTIK_EMAIL_FROM}
    volumes:
      - /home/user/docker/authentik/media:/media #Persistent storage for media, replace /home/user/docker with a valid local path IE: /home/johndoe/docker
      - /some/path/custom-templates:/templates #Persistent storage for authentik templates, replace /home/user/docker with a valid local path IE: /home/johndoe/docker
    depends_on:
      - authentik-postgres # Match this to the postgres container
      - authentik-redis # Match this to the redis container
    restart: unless-stopped
    networks:
      vpcbr:
        ipv4_address: 172.20.0.12 #Set an IP in your docker network

  authentik-authentik_proxy:2024.8.0 #Match version to authentik-server version
    image: ghcr.io/goauthentik/proxy:2024.6.3
    environment:
      - AUTHENTIK_HOST=${AUTHENTIK_HOST}
      - AUTHENTIK_INSECURE=${AUTHENTIK_INSECURE}
      - AUTHENTIK_TOKEN=${AUTHENTIK_TOKEN}
      - AUTHENTIK_DEBUG=${AUTHENTIK_DEBUG}
    network_mode: host

  authentik-worker:
    image: ghcr.io/goauthentik/server:2024.8.0 #Match version to authentik-server version
    container_name: authentik-worker
    command: worker
    environment:
      - AUTHENTIK_REDIS__HOST=authentik-redis
      - AUTHENTIK_POSTGRESQL__HOST=authentik-db
      - AUTHENTIK_POSTGRESQL__USER=${POSTGRES_USER}
      - AUTHENTIK_POSTGRESQL__NAME=${POSTGRES_DB}
      - AUTHENTIK_POSTGRESQL__PASSWORD=${POSTGRES_PASSWORD}
      # (Required)  To generate a secret key run the following command:
      #             echo $(openssl rand -base64 32)
      - AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
      # (Optional)  Enable Error Reporting
      - AUTHENTIK_ERROR_REPORTING__ENABLED=${AUTHENTIK_ERROR_REPORTING:-false}
      # (Optional)  Enable Email Sending
      # DO NOT REMOVE THE DOUBLE UNDERSCORES BELOW THEY ARE INTENTIONAL
      - AUTHENTIK_EMAIL__HOST=${AUTHENTIK_EMAIL_HOST}
      - AUTHENTIK_EMAIL__PORT=${AUTHENTIK_EMAIL_PORT}
      - AUTHENTIK_EMAIL__USERNAME=${AUTHENTIK_EMAIL_USERNAME}
      - AUTHENTIK_EMAIL__PASSWORD=${AUTHENTIK_EMAIL_PASSWORD}
      - AUTHENTIK_EMAIL__USE_TLS=${AUTHENTIK_EMAIL_USE_TLS}
      - AUTHENTIK_EMAIL__USE_SSL=${AUTHENTIK_EMAIL_USE_SSL}
      - AUTHENTIK_EMAIL__TIMEOUT=${AUTHENTIK_EMAIL_TIMEOUT}
      - AUTHENTIK_EMAIL__FROM=${AUTHENTIK_EMAIL_FROM}
    # DO NOT REMOVE THE DOUBLE UNDERSCORES ABOVE THEY ARE INTENTIONAL
    # (Optional)  When using the docker socket integration
    #             See more for the docker socket integration here:
    #             https://goauthentik.io/docs/outposts/integrations/docker
    user: root
    volumes:
      # (Optional)  When using the docker socket integration uncomment the next line by removing the # at the beginning of the line
      # - /var/run/docker.sock:/run/docker.sock
      - /home/user/docker/authentik/media:/media #Persistent storafe for media, replace /home/user/docker with a valid local path IE: /home/johndoe/docker
      - /home/user/docker/authentik/certs:/certs #Persistent storage for certs used for SSL replace /home/user/docker with a valid local path IE: /home/johndoe/docker
      - /home/user/docker/authentik/custom-templates:/templates #Persistent storage for authentik templates, replace /home/user/docker with a valid local path IE: /home/johndoe/docker
    depends_on:
      - postgres
      - redis
    restart: unless-stopped
    networks:
      vpcbr:
        ipv4_address: 172.20.0.13 #Set an IP in your docker network

# Define docker volumes for information that needs to be persistent but shouldnt need to be accessed
volumes:
  authentik_postgres_data:
    driver: local
  authentik_redis_data:
    driver: local

# Define a docker network
# REMOVE BELOW if you already have a network and are using IP addresses in an existing network
networks:
  vpcbr:
    driver: bridge
    ipam:
     config:
       - subnet: 172.20.0.0/24
         gateway: 172.20.0.1
# REMOVE ABOVE if you already have a network and are using IP addresses in an existing network
2. Set up environment variables

TZ: Find your correct timezone IE: America/New_York AUTHENTIK_POSTGRES_USER: enter a username AUTHENTIK_POSTGRES_PASSWORD: enter a secure password or generate a password with echo $(openssl rand -base64 32) AUTHENTIK_POSTGRES_DB: select a database name AUTHENTIK_SECRET_KEY: enter a secret key or generate one with echo $(openssl rand -base64 32) AUTHENTIK_ERROR_REPORTING: select if logs are enabled AUTHENTIK_EMAIL_HOST: email server domain, check with your email provider AUTHENTIK_EMAIL_PORT: email server port,check with your email provider AUTHENTIK_EMAIL_USERNAME: email for logging in, check with your email provider AUTHENTIK_EMAIL_PASSWORD: password for email, check with your email provider AUTHENTIK_EMAIL_USE_TLS: select if TLS is enabled, check with your email provider AUTHENTIK_EMAIL_USE_SSL: select if SSL is enabled, check with your email provider AUTHENTIK_EMAIL_TIMEOUT: select email timeout period, check with your email provider AUTHENTIK_EMAIL_FROM: select the email that authentik will send from, this can be blank if it is the same as the username

Example .env file env TZ: America/New_York AUTHENTIK_POSTGRES_USER: authentik_db_user AUTHENTIK_POSTGRES_PASSWORD: pMdh6ta2uiRWMEjYO6I/efX9Ex9k843/pI5EEyGw9Z4= AUTHENTIK_POSTGRES_DB: authentik_db AUTHENTIK_SECRET_KEY: Vd5CrkGSFC3nYnkRGHTlwqk3XGcW6K9v4hrMEKwPYUs= AUTHENTIK_ERROR_REPORTING: true AUTHENTIK_EMAIL_HOST: smtp.some.website AUTHENTIK_EMAIL_PORT: 465 AUTHENTIK_EMAIL_USERNAME: [email protected] AUTHENTIK_EMAIL_PASSWORD: CH4nFvshAuFgYLN1mbye40RdM3TKtmO3sWG3werOYZ8= AUTHENTIK_EMAIL_USE_TLS: true AUTHENTIK_EMAIL_USE_SSL: false AUTHENTIK_EMAIL_TIMEOUT: 30 AUTHENTIK_EMAIL_FROM: [email protected] 1. Configure Services 1. Configure each service one at a time: Look up the specific service you want to protect with Authentik(e.g., somearr authentik) 2. Follow the directions on the Authentik Official Website search result for integration.

My Setup

Cloudflare Zero Trust Tunnel Setup

Turn off Internal SSL Verification: I could not get it working with this enabled even with my cloudflare SSL cert added and selected in Authentik for that Application

Create a Docker container for a Cloudflare Zero Trust Tunnel in the same Docker stack and network.

On the cloudflare website, point the Cloudflare Tunnel with HTTPS to the Authentik Outposts local Docker network IP port 9443 in the same Docker stack and network. (e.g., https://172.20.0.22:9443)

Disable TLS verification for the Cloudflare sub-domains.

Authentik Configuration

Create an Application and Provider in Authentik using the wizard (Applications > Applications > Create with Wizard).

Choose between Implicit Authentication Flow (once logged into Authentik, don't require logging in for each service) or Explicit Authentication Flow (require logging into Authentik for each service individually).

Follow steps from the Authentik Website for the specific service or continue with Transparent Reverse Proxy

Additional Steps

Basic HTML Authentication

While setting up the application 1. In Authentik Navigate to Authentication Settings 2. Toggle Send HTTP-Basic Authentication 3. Enter variables that you will use in a later step. User: somearr_user Password: somearr_password 4. Follow Create or Update Group

Create or Update Group:

  1. In Authentik Navigate to Directory>Groups
  2. Create a new group or select an existing group
  3. For the group select Edit
  4. In the Attributes field add your variables from Basic HTML Authentikation Step 1, replacing [user] with a username and [password] with a password that works for logging into the Application with basic HTML credentials. Make sure the variables you enter here match the variables from Basic HTML Authentikation Step 1 and following the colon is a space and the username and password from your application somearr_user: [user] somearr_password: [password]
  5. Update
  6. Follow Add yourself to the Group

Add yourself to the group:

  1. In Authentik Navigate to Directory>Groups>[Your Group]>Edit, replacing [Your Group] with your actual group created in Create or Update Group
  2. Users>Add Existing User
  3. Select + icon
  4. Select the checkmark next to your user
  5. Add

Transparent Reverse Proxy

Create the Application and Provider

  1. In Authentik Navigate to Applications>Applications>Create with Wizard
  2. Enter a name, make sure the slug autopopulated
  3. Next>Transparent Reverse Proxy>Next
  4. Authorization Flow
    1. Select Implicit for: Only log into Authentik once, all Applications will automatically log in while your token is active
    2. Select Explicit for: Log into each Application independently
  5. External Host: the domain where you will be accessing this application, should match the zero trust tunnel created in cloudflare IE: https://somearr.somewebsite.com
  6. Internal Host: the IP address of the service accessible from the proxy outpost docker container, the docker container created in the Setting Up an Outpost step of this guide should be in the same network as the service, you can create multiple outposts if you have multiple docker stacks. IE: http://172.20.0.5:8989
  7. Internal host SSL Validation: I have this disabled, I am unable to load the page with this enabled
  8. Open the Authentication settings by clicking on >
  9. Follow Basic HTML Authentication
  10. Follow Create or Update Group
  11. Follow Add yourself to the group
  12. Follow Assign the application to an Outpost

Assign the application to an Outpost:

  1. Navigate to Applications > Outposts > Your outpost (Docker container that has access to your service at its local Docker IP address) > Edit
  2. On the left side under Available Applications Double click your application so it shows up on the right side under Selected Applications