Authelia (OIDC)
This guide walks through running Carbon Panel with Authelia as an OIDC identity provider using a ready-made Docker Compose stack. Authelia provides a file-based user store, so no external database is needed.
Prerequisites
Section titled “Prerequisites”- Docker and Docker Compose
Docker Compose
Section titled “Docker Compose”Clone the repo and navigate to the oidc/authelia/ directory, then start the stack:
cd oidc/autheliadocker compose up -d# SPDX-License-Identifier: MIT AND MPL-2.0# This file includes DiscoPanel material under the MIT License,# Copyright (c) 2025 Nicholas W. Heyer. The MIT license text is in LICENSE# and still applies to that inherited material.# Maintainer changes are licensed under the Mozilla Public License, v. 2.0.# If a copy of the MPL was not distributed with this file, You can obtain# one at https://mozilla.org/MPL/2.0/.
# Carbon Panel + Authelia (OIDC)## This is a complete docker-compose with OIDC authentication pre-configured using Authelia.## NOTE #1: Default users should be changed (SEE oidc/authelia/config/users_database.yml).# Passwords are stored as hash, see instructions. Use same hash cmd for secret below (when setting in oidc/authelia/config/configuration.yaml) if needed.## NOTE #2: Authelia is generally intended to be used with a proxy like traefik. Plenty of guides online for that.# Feel free to throw away the example configuration.yml and users_database.yml !!!! Just make sure groups are included in claims.
services: carbon-panel: image: athNdev/carbon-panel:dev container_name: carbon-panel restart: unless-stopped network_mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock - /tmp/carbon-panel:/app/data environment: - TZ=UTC
# ------------------------------------ AUTH CONFIG STARTS HERE FOR CARBON PANEL + AUTHELIA ------------------------------------ - CARBONPANEL_AUTH_LOCAL_ENABLED=true - CARBONPANEL_AUTH_OIDC_ENABLED=true
# MUST MATCH oidc/authelia/config/configuration.yaml - CARBONPANEL_AUTH_OIDC_ISSUER_URI=https://authelia.traefik.me:9091
# ONLY CHANGE THIS IF YOUR CLIENT NAME IS DIFFERENT - CARBONPANEL_AUTH_OIDC_CLIENT_ID=CARBONPANEL
# YOU SHOULD CHANGE THIS HERE AS WELL AS THE HASHED ONE IN oidc/authelia/config/configuration.yaml (inside the identity_providers.client) - CARBONPANEL_AUTH_OIDC_CLIENT_SECRET=CARBONPANEL-dev-secret
# YOU SHOULD CHANGE "localhost:8080" TO WHATEVER YOUR PUBLIC DOMAIN IS FOR CARBON PANEL (ie: https://mypanel.com/api/v1/auth/oidc/callback) - CARBONPANEL_AUTH_OIDC_REDIRECT_URL=http://localhost:8080/api/v1/auth/oidc/callback
- CARBONPANEL_AUTH_OIDC_ROLE_CLAIM=groups
# SKIPPING TLS VERIFY HERE BECAUSE TLS CERTS ARE SELF SIGNED. IF USING YOUR OWN CERTS (in authelia mounts), REMOVE THIS. - CARBONPANEL_AUTH_OIDC_SKIP_TLS_VERIFY=true
depends_on: authelia: condition: service_healthy
authelia: image: authelia/authelia:latest container_name: authelia volumes: - ./config/configuration.yml:/config/configuration.yml:ro - ./config/users_database.yml:/config/users_database.yml:ro - ./config/tls.crt:/config/tls.crt:ro # self-signed; run ./gen-dev-tls.sh first (the key is not committed) - ./config/tls.key:/config/tls.key:ro ports: - "9091:9091" healthcheck: test: ["CMD", "wget", "--no-check-certificate", "--spider", "https://localhost:9091/api/health"] interval: 5s timeout: 3s retries: 10 start_period: 10s environment: - TZ=UTCKey environment variables
Section titled “Key environment variables”| Variable | Purpose |
|---|---|
CARBONPANEL_AUTH_OIDC_ENABLED |
Enables OIDC authentication |
CARBONPANEL_AUTH_OIDC_ISSUER_URI |
Authelia’s OIDC issuer URL — must match the session.cookies domain in configuration.yml |
CARBONPANEL_AUTH_OIDC_CLIENT_ID |
Must match the client_id in configuration.yml |
CARBONPANEL_AUTH_OIDC_CLIENT_SECRET |
The plaintext secret — the hashed version is stored in configuration.yml |
CARBONPANEL_AUTH_OIDC_REDIRECT_URL |
The callback URL — update localhost:8080 to your public domain |
CARBONPANEL_AUTH_OIDC_ROLE_CLAIM |
Set to groups to read Authelia group membership as Carbon Panel roles |
CARBONPANEL_AUTH_OIDC_SKIP_TLS_VERIFY |
Set to true because the included TLS certs are self-signed — remove this when using real certs |
Authelia configuration
Section titled “Authelia configuration”# SPDX-License-Identifier: MIT AND MPL-2.0# This file includes DiscoPanel material under the MIT License,# Copyright (c) 2025 Nicholas W. Heyer. The MIT license text is in LICENSE# and still applies to that inherited material.# Maintainer changes are licensed under the Mozilla Public License, v. 2.0.# If a copy of the MPL was not distributed with this file, You can obtain# one at https://mozilla.org/MPL/2.0/.
---# Carbon Panel - Authelia Configuration## This config is ready to use for development/testing.# For production, change ALL secrets and generate new keys.
server: address: 'tcp://:9091' tls: certificate: '/config/tls.crt' key: '/config/tls.key'
log: level: 'info'
totp: issuer: 'CARBONPANEL'
identity_validation: reset_password: jwt_secret: "REDACTED"
# User accounts are stored in ./users_database.ymlauthentication_backend: file: path: '/config/users_database.yml' password: algorithm: 'argon2' argon2: variant: 'argon2id' iterations: 3 memory: 65536 parallelism: 4 key_length: 32 salt_length: 16
# Authelia needs a cookie domain for its login portal. ../docker-compose.yaml for instructionsession: secret: "REDACTED" cookies: - name: 'authelia_session' domain: 'traefik.me' authelia_url: 'https://authelia.traefik.me:9091' expiration: '1 hour' inactivity: '5 minutes'
storage: encryption_key: "REDACTED" local: path: '/config/db.sqlite3'
notifier: filesystem: filename: '/config/notification.txt'
access_control: default_policy: 'one_factor'
regulation: max_retries: 5 find_time: '2 minutes' ban_time: '5 minutes'
identity_providers: oidc: hmac_secret: "REDACTED" enable_client_debug_messages: true minimum_parameter_entropy: 8 enforce_pkce: 'public_clients_only'
jwks: - key_id: 'CARBONPANEL-dev' algorithm: 'RS256' use: 'sig' key: "" certificate_chain: | -----BEGIN CERTIFICATE----- MIIDMTCCAhmgAwIBAgIUCQjLyj/HNDk2e4KdiOgmBH5dtOswDQYJKoZIhvcNAQEL BQAwKDERMA8GA1UEAwwIYXV0aGVsaWExEzARBgNVBAoMCkRpc2NvUGFuZWwwHhcN MjYwMjE2MjIxMjE1WhcNMzYwMjE0MjIxMjE1WjAoMREwDwYDVQQDDAhhdXRoZWxp YTETMBEGA1UECgwKRGlzY29QYW5lbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALC9gH4pGZ+RqJUo3/BE1096QuXhde7wBPGHF6uDYo4TfWVRyuXJ7Mf8 4sQ6Z3RVOg+cxcFQqAgwNY9sx2wCR5evAB3Ng5kz4uzpsXL2WvvQMPhJTjJz//q8 1B+oFtDmhHcgBRFLq70C271cX7zhFT93jpJzcGFPtntTdUUMS3cxUukU0uDr9iFH KC4JAPbhkITmisjC2aRIamTx3FwzYGmP3L3B2QUsR4JZIjajCkIYQQ2V1XT2g8r5 rxerPn1cG8mSLgDHcHE4CG4QqHmp7t3jSW1CfeXVrwYzqCYo3C0oriM2j8aXk/T7 j/DCgV3FPnnDUYeKMdbU6dOsPBgRvXkCAwEAAaNTMFEwHQYDVR0OBBYEFNMzG9im j+WQsYBQnEk5SbXRzhozMB8GA1UdIwQYMBaAFNMzG9imj+WQsYBQnEk5SbXRzhoz MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHy1bE1X/J4jiTSd dzzV+7imfRKWjXA3l1R7ztfXil5KgQxoG9KyCGIsS5yRD94BH6k9n15wxFwa3xbw aPzr6jAt+I/S4WLoAtWZkRDdnOMpCslydStvBJso9Sf3yP0omcfRab7B49JYg+4g SaHFt0W5ncgaHNJat2uwtNa3XeMo3uyatZw99y16X2XlOzkhPWl0PHb2Wet6JGbW rwfjJuT9gmr5LpIHXXIpoz8COQ/tWqDwcwxOh7Vhz4h8ohMaBF7DwtwEUU0HFe1L KhlYOOn3iEYMCHoRCwqfuCty3kXbUigqOdC+3GD3sPJHsetZpju6mzgRUK6HwzB7 ry2+WVw= -----END CERTIFICATE-----
lifespans: access_token: '1h' authorize_code: '1m' id_token: '1h' refresh_token: '90m'
# This policy puts "groups" directly in the ID token. Without it, groups only show up in the UserInfo endpoint, and Carbon Panel wouldn't read roles. claims_policies: carbon-panel: id_token: - 'groups' - 'email' - 'email_verified' - 'preferred_username' - 'name'
cors: endpoints: - 'authorization' - 'token' - 'revocation' - 'introspection' - 'userinfo' allowed_origins_from_client_redirect_uris: true
clients: - client_id: 'CARBONPANEL' client_name: 'CARBONPANEL' # Plaintext secret: REDACTED client_secret: "REDACTED" public: false authorization_policy: 'one_factor' claims_policy: 'CARBONPANEL' redirect_uris: - 'http://localhost:8080/api/v1/auth/oidc/callback' - 'http://localhost:5173/api/v1/auth/oidc/callback' scopes: - 'openid' - 'profile' - 'email' - 'groups' - 'offline_access' grant_types: - 'authorization_code' - 'refresh_token' response_types: - 'code' response_modes: - 'query' - 'form_post' token_endpoint_auth_method: 'client_secret_basic'Notable sections
Section titled “Notable sections”identity_providers.oidc.clients: the Carbon Panel OIDC client —client_secretis a PBKDF2-SHA512 hash of the plaintext secretclaims_policies.carbon-panel: putsgroupsdirectly in the ID token so Carbon Panel can read roles without a separate UserInfo callidentity_providers.oidc.jwks: an RSA key pair used for signing tokens — generate your own for productionsession.cookies.domain: set totraefik.mefor development — change to your actual domain
User database
Section titled “User database”Authelia stores users in a YAML file. The default config includes a single admin user.
# SPDX-License-Identifier: MIT AND MPL-2.0# This file includes DiscoPanel material under the MIT License,# Copyright (c) 2025 Nicholas W. Heyer. The MIT license text is in LICENSE# and still applies to that inherited material.# Maintainer changes are licensed under the Mozilla Public License, v. 2.0.# If a copy of the MPL was not distributed with this file, You can obtain# one at https://mozilla.org/MPL/2.0/.
---# Carbon Panel - Authelia Users## Do NOT use default admin in production.# Default login is "admin" / "admin"## To generate a new password hash:## docker run --rm authelia/authelia:latest \# authelia crypto hash generate argon2 \# --password 'your-password-here'
users: admin: # username disabled: false displayname: 'Carbon Panel Admin' password: "REDACTED" groups: - 'admin'Generating password hashes
Section titled “Generating password hashes”To add or change users, generate an Argon2id hash:
docker run --rm authelia/authelia:latest \ authelia crypto hash generate argon2 \ --password 'your-password-here'Default credentials
Section titled “Default credentials”| Service | URL | Username | Password |
|---|---|---|---|
| Carbon Panel | http://localhost:8080 | — | Log in via OIDC |
| Authelia login portal | https://authelia.traefik.me:9091 | admin |
admin |
Production notes
Section titled “Production notes”- Use real TLS certificates: replace
tls.crtandtls.key, then removeCARBONPANEL_AUTH_OIDC_SKIP_TLS_VERIFY - Change all secrets: the HMAC secret, session secret, storage encryption key, JWT reset secret, and the OIDC client secret (both the hash in
configuration.ymland the plaintext in the compose file) - Generate new JWKS keys: replace the RSA key pair in
configuration.yml - Update the session domain: change
traefik.meto your actual domain - Update redirect URIs: change
localhostentries to your actual domain - Disable local auth (optional): set
CARBONPANEL_AUTH_LOCAL_ENABLED=falseif you want OIDC-only login