Authelia 4.39.28 on AWS User Guide
Overview
This guide covers launching and using the Authelia 4.39.28 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg identity, secrets and PKI listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Authelia is an open source authentication and authorisation server. It sits beside a reverse proxy and answers one question for every request to the applications behind it: is this person signed in, and are they allowed here? People sign in once at the Authelia portal, with a password and optionally a second factor (one-time codes from an authenticator app, security keys or passkeys), and that single sign-on session then opens every application you put behind the proxy. Access rules decide, per domain and path, whether a resource is open, needs one factor, needs two factors or is denied.
The cloudimg image is a working forward-authentication gateway out of the box:
- nginx in front, Authelia behind it. nginx is the only public listener (ports 80 and 443). Authelia listens on
127.0.0.1:9091only. A demo protected application shows the whole flow: open it, you are sent to the portal, sign in, and you are returned to it. - HTTPS from the first boot. nginx serves the portal and the demo application with a certificate generated on your instance's first boot (an end-entity certificate, not a certificate authority), and port 80 redirects to HTTPS.
- No default login, nothing shared. The administrator password, the session secret and the storage encryption key are generated on the first boot of each instance. The image contains no user database, no secret and no certificate, and Authelia and nginx refuse to start until first boot has created them.
- Closed by default. Self-service password reset is switched off, the access policy for anything you have not listed is deny, failed sign-ins are rate limited (a user is banned for 5 minutes after 4 failures in 2 minutes), and no mail server, LDAP directory or OpenID Connect client is configured until you add one.
- Fixed host names. Authelia is handed the configured portal name, never the name a client sends; requests for any other host name are dropped, and the client address Authelia records is the real TCP peer, never a forwarded header.
- Locked down serving. TLS 1.2 and 1.3 only; the session-state endpoints of the portal refuse cross-site requests; nginx, Authelia and the first-boot service are blocked from the instance metadata service and the AMI requires IMDSv2.
- Your state on its own disk. The user database, the encrypted storage (second-factor devices, consent) and the secrets live on a separate 10 GiB EBS volume mounted at
/var/lib/authelia. - The official release, verified, and fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: Authelia 4.39.28 (the official authelia-v4.39.28-linux-amd64 release binary, sha256 verified, in /usr/local/bin/authelia), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH) from your own networks only, and TCP 443 (the portal and your applications) and TCP 80 (redirects to HTTPS) from the networks your users sign in from.
- For production, a DNS domain you control (for example
example.com), so the portal can beauth.example.com. Authelia's session cookie must belong to a domain: it cannot use an IP address or an EC2 public DNS name (those are public suffixes). Until you set your own, the image uses the demo domainauthelia.local.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Authelia 4.39.28 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair, and a security group as above. The AMI already carries the 10 GiB state volume; you can make it larger on the launch page.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --image-id <ami-id-from-the-listing> --instance-type m5.large \
--key-name <your-key-pair> --security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=authelia}]'
First boot takes a few seconds after the instance is running.
Step 2: Connect to your instance
| Operating system | SSH user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
systemctl is-active authelia-firstboot authelia nginx
active
active
active
Only SSH, HTTP and HTTPS are public. Authelia itself listens on the loopback address:
sudo ss -tln | grep -E ':(22|80|443|9091) '
LISTEN 0 4096 127.0.0.1:9091 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
LISTEN 0 4096 [::]:22 [::]:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 511 [::]:443 [::]:*
The portal answers its health check through nginx:
curl -sk --resolve auth.authelia.local:443:127.0.0.1 https://auth.authelia.local/api/health; echo
{"status":"OK"}
Step 4: Get your password and the certificate fingerprint
sudo cat /root/authelia-credentials.txt
The file (root only, mode 0600) gives the portal and demo application addresses, the administrator user admin, its per-instance password (shown here as <redacted>) and the SHA-256 fingerprint of this instance's certificate:
authelia.portal_URL=https://auth.authelia.local/
authelia.demo_app_URL=https://secure.authelia.local/
authelia.admin.user=admin
authelia.admin.pass=<redacted>
authelia.tls.sha256_fingerprint=E1:9C:1F:51:AE:9E:BC:5A:38:A1:48:0C:DD:07:90:34:6B:14:48:DC:8C:E4:79:FF:47:B8:7D:06:06:89:1D:53
The password is stored in Authelia's user database only as an argon2id hash. Every instance gets its own.
Step 5: Reach the portal from your workstation
Authelia serves two names: the portal auth.<domain> and the demo application secure.<domain>. With the demo domain, tell your workstation where they are by adding one line to its hosts file (/etc/hosts on Linux and macOS, C:\Windows\System32\drivers\etc\hosts on Windows), using your instance's public IP address:
<public-ip> auth.authelia.local secure.authelia.local
Requests that use any other name, including the bare IP address, are dropped by design. Skip this step once you have set your own domain (Step 9).
The certificate is self-signed and unique to your instance, so your browser warns about it. Open the certificate details in the browser, check that its SHA-256 fingerprint matches authelia.tls.sha256_fingerprint from Step 4, and only then continue. Do not add the certificate to your operating system's trust store; for production, replace it with a certificate from a certificate authority (Step 9).
Step 6: Sign in
Browse to https://secure.authelia.local/. The demo application is protected, so nginx asks Authelia, and Authelia sends you to the portal to sign in:

Sign in as admin with the password from Step 4:

Authelia returns you to the page you asked for, now served because the session is authorised:

The same session opens every application you protect under the same domain. Your own settings, including second-factor devices, are at https://auth.authelia.local/settings:

Step 7: Check the sign-in flow from the command line
The image includes a check that runs the whole flow through nginx on the instance: an anonymous request is sent to the portal, the administrator signs in, the session opens the demo application, and a wrong password is refused. The password is passed to curl in a root-only temporary file, never on a command line:
sudo /usr/local/sbin/authelia-cred-roundtrip.sh
AUTHELIA_ROUNDTRIP_OK anon=302 admin=200 app=200 wrong=401
An anonymous request to the demo application is redirected to the portal, with the page you wanted as the return address:
curl -sk -o /dev/null -w '%{http_code} %{redirect_url}\n' --resolve secure.authelia.local:443:127.0.0.1 https://secure.authelia.local/
302 https://auth.authelia.local/?rd=https%3A%2F%2Fsecure.authelia.local%2F&rm=GET
Step 8: Check the security posture
Authelia's version, the closed features and the default policy:
authelia --version
sudo grep -E 'default_policy|disable:|authelia_url' /etc/authelia/configuration.yml
authelia version v4.39.28
disable: true
default_policy: 'deny'
authelia_url: 'https://auth.authelia.local'
disable: true is authentication_backend.password_reset.disable: nobody can reset a password from the internet-facing portal; an administrator sets passwords on the instance (Step 11).
The certificate is an end-entity certificate for the two names, which cannot sign other certificates:
openssl x509 -in /etc/ssl/authelia/authelia.crt -noout -subject -ext basicConstraints,keyUsage,extendedKeyUsage,subjectAltName
subject=CN = auth.authelia.local, O = cloudimg
X509v3 Subject Alternative Name:
DNS:auth.authelia.local, DNS:secure.authelia.local
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
TLS 1.0 and 1.1 are refused by the server, and a request for a name the instance does not serve gets no answer:
echo | openssl s_client -tls1_1 -cipher 'DEFAULT@SECLEVEL=0' -connect 127.0.0.1:443 -servername auth.authelia.local 2>&1 | grep -o 'alert protocol version' | head -1
code=$(curl -sk -o /dev/null -w '%{http_code}' --resolve evil.example:443:127.0.0.1 https://evil.example/ || true); echo "$code"; [ "$code" = 000 ]
alert protocol version
000
The services are blocked from the instance metadata service. The first command shows the systemd rule on each service; the second makes a metadata request from inside Authelia's own service, as its user, and gets no connection (000):
systemctl show -p IPAddressDeny authelia nginx authelia-firstboot
sudo bash -c 'cg=$(systemctl show -p ControlGroup --value authelia.service); echo $$ > /sys/fs/cgroup$cg/cgroup.procs; setpriv --reuid=authelia --regid=authelia --init-groups curl -s -m 5 -o /dev/null -w "imds from authelia: %{http_code}\n" -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 60" http://169.254.169.254/latest/api/token; true' | grep -x 'imds from authelia: 000'
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32 ::ffff:169.254.169.254/128
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32 ::ffff:169.254.169.254/128
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32 ::ffff:169.254.169.254/128
imds from authelia: 000
SSH accepts keys only:
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|x11forwarding|permitemptypasswords) '
permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no
x11forwarding no
permitemptypasswords no
Step 9: Use your own domain and certificate
Choose a domain you control, for example example.com, and create DNS records for auth.example.com (the portal) and secure.example.com (the demo application) pointing at the instance's public IP (or an Elastic IP). Then run:
sudo authelia-set-domain example.com
The helper sets the session cookie domain to example.com, the portal to https://auth.example.com/ and the demo application to https://secure.example.com/. It re-renders /etc/authelia/configuration.yml from the cloudimg template (your previous file is kept as configuration.yml.prev, so run it before you customise the configuration, or copy your changes back afterwards), updates the nginx site and the cross-site guard, issues a new self-signed certificate for the new names, and restarts Authelia. Check the result with:
authelia-set-domain --show
domain: authelia.local
portal: https://auth.authelia.local/
demo app: https://secure.authelia.local/
(Shown for the demo domain; after the change it names yours.)
To use a certificate from a certificate authority, for example from AWS Certificate Manager on a load balancer in front of the instance, or Let's Encrypt with certbot on the instance, put the full chain and key at /etc/ssl/authelia/authelia.crt and /etc/ssl/authelia/authelia.key (key mode 0600, owner root) and reload nginx with sudo systemctl reload nginx. authelia-set-domain never replaces a certificate that is not cloudimg's own.
Step 10: Turn on two-factor authentication
The demo rule asks for one factor so you can try the flow straight away. To require two factors, change the rule in /etc/authelia/configuration.yml:
access_control:
default_policy: 'deny'
rules:
- domain: 'secure.authelia.local'
policy: 'two_factor'
then restart Authelia with sudo systemctl restart authelia. At the next sign-in Authelia offers to register a second factor (a one-time password app such as Google Authenticator or Microsoft Authenticator, a security key or a passkey). Registering a device is confirmed with a one-time code that Authelia "sends" through its notifier. The image uses the filesystem notifier (there is no mail server until you configure one), so read the code on the instance:
sudo cat /var/lib/authelia/notification.txt 2>/dev/null || echo 'no notification has been sent yet'
To send these messages by e-mail instead, replace the notifier: section with an smtp: block for your mail service (Amazon SES works well) as described in the Authelia notifier documentation, and restart Authelia.
Step 11: Add users and change passwords
Users live in /var/lib/authelia/users_database.yml (file backend, argon2id hashes). To create a password hash, run the generator and type the password at its prompt, so it never appears on a command line or in your shell history:
sudo -u authelia authelia crypto hash generate argon2
Add the user to the file as a new entry next to admin, with the Digest: value as its password, then restart Authelia:
users:
alice:
disabled: false
displayname: 'Alice'
password: '$argon2id$v=19$m=65536,t=3,p=4$...'
email: 'alice@example.com'
groups:
- 'staff'
Signed-in users can change their own password from the portal's settings. For a directory instead of a file, Authelia supports LDAP and Active Directory (authentication_backend.ldap).
Step 12: Protect your own application
Put the application behind nginx on this instance (or on another server that uses this Authelia as its forward-auth endpoint) and add an access_control rule for its name. On this instance, copy the demo server block in /etc/nginx/sites-available/authelia for the new name (for example grafana.example.com), keep the location = /internal/authelia/authz block and the auth_request lines, and replace the root/try_files lines with a proxy_pass to your application. Then add a rule such as:
- domain: 'grafana.example.com'
policy: 'two_factor'
subject: 'group:admins'
restart Authelia and reload nginx. Remember that authelia-set-domain re-renders the nginx site from its template, so keep your own server blocks in a separate file under /etc/nginx/sites-enabled/. The certificate must cover the new name too.
Step 13: Your state and backups
Everything Authelia keeps is on the state volume at /var/lib/authelia:
sudo ls -l /var/lib/authelia /var/lib/authelia/secrets
df -h /var/lib/authelia | tail -1
/var/lib/authelia:
total 328
-rw------- 1 authelia authelia 311296 Oct 28 19:52 db.sqlite3
drwx------ 2 root root 16384 Oct 28 19:22 lost+found
drwx------ 2 authelia authelia 4096 Oct 28 19:51 secrets
-rw------- 1 authelia authelia 457 Oct 28 19:51 users_database.yml
/var/lib/authelia/secrets:
total 8
-rw------- 1 authelia authelia 64 Oct 28 19:51 session
-rw------- 1 authelia authelia 64 Oct 28 19:51 storage-encryption
/dev/nvme1n1 9.8G 344K 9.3G 1% /var/lib/authelia
users_database.yml: users and their password hashes.db.sqlite3: Authelia's storage (second-factor devices, preferences, consent), encrypted with the key insecrets/storage-encryption. Keep the key with the database: without it the stored second-factor devices cannot be read.secrets/session: signs session cookies. Changing it signs everyone out.
Back the volume up with EBS snapshots (AWS Backup or Data Lifecycle Manager), or copy the files while Authelia is stopped. Treat backups as secrets.
Step 14: Server components
| Component | Where |
|---|---|
| Authelia 4.39.28 | /usr/local/bin/authelia, unit authelia.service, user authelia, 127.0.0.1:9091 |
| Configuration | /etc/authelia/configuration.yml (no secrets), /etc/authelia/authelia.env (0600, file paths of the secrets) |
| State | /var/lib/authelia (own EBS volume) |
| nginx site | /etc/nginx/sites-available/authelia, certificate /etc/ssl/authelia/ |
| Domain helper | /usr/local/sbin/authelia-set-domain |
| First boot | authelia-firstboot.service, /usr/local/sbin/authelia-firstboot.sh |
| Logs | journalctl -u authelia, /var/log/nginx/ |
Step 15: Updating Authelia
Ubuntu packages update automatically through unattended upgrades. Authelia is a single binary: to update it, download the new authelia-v<version>-linux-amd64.tar.gz from the Authelia releases page, verify its checksum, read the release notes for configuration changes, stop Authelia, back up /var/lib/authelia, replace /usr/local/bin/authelia (owner root, mode 0755) and start Authelia again. Authelia migrates its storage on start.
Step 16: Security notes
- Keep port 22 open to your own networks only.
- Set your own domain and a CA-issued certificate before real users sign in, and switch the rules you rely on to
two_factor. - Keep
default_policy: 'deny'and list each application explicitly. - Authelia logs every sign-in attempt with the client address; failed attempts trigger the ban in
regulation.
Known advisories in the shipped release. Authelia 4.39.28 (the newest release) is built with Go 1.27.1. Go fixed these standard-library advisories in Go 1.27.2 and 1.27.3, after that release: GO-2026-6599, GO-2026-6600 (html/template), GO-2026-6603, GO-2026-6605, GO-2026-6609, GO-2026-6610, GO-2026-6611, GO-2026-6613 (net/http), GO-2026-6607 (crypto/tls), GO-2026-6608 (net/textproto) and GO-2026-6809 (crypto/x509). Authelia serves HTTP through fasthttp, not Go's net/http server, so the server-side items do not apply. The rest are only reachable through outbound connections Authelia makes to services you configure: e-mail templates sent through an SMTP notifier, LDAP and SMTP TLS connections, OpenID Connect sector-identifier, WebAuthn metadata and OCSP fetches, and the authelia debug commands. None of these is configured in the image. cloudimg tracks the next Authelia release and will publish an updated version.
Support and licensing
Authelia is licensed under the Apache License 2.0. cloudimg is not affiliated with or endorsed by the Authelia project. The image is built and supported by cloudimg: contact support@cloudimg.co.uk for help with deployment, access rules, two-factor enrolment, directories, mail and certificates.
See the identity, secrets and PKI listing guide for the other versions in this listing.