Open agrimpelhuber opened 2 years ago
I would love to configure this via Django Templates!
@agrimpelhuber
- Make the hard-coded parts of an authentication workflow just as customizable as flows (on tenant level?): Background etc.
There isn't really much hardcoded during authentication; and while I get having a tenant-level configurable background I think most environments that do change the background just change it to a URL and then update the picture behind that (at least thats how I would do it)
- Minor thing: As far as I can see, an uploaded background picture for X multiple flows ends up as X picture URLs. Re-use the same
Yes, this is a downside of how the whole uploading thing works, there could be a UI to show already uploaded files, allthough imo there's more important things before this
- Make a type of branding possible to obscure the fact that the whole system is called "authentik" (e.g. in the above URL, button "go to authentik" is hard-coded). Even though I have no problem with this in my hobbyist use, that might be something to keep people from using Authentik in corporate environments. Therefore, this might be a paid feature (oops!)
Yeah the logout screen is currently hardcoded, this will eventually be migrated to also use flows when I finish #2346 and the followup for OIDC, but besides that I recently cleaned up some of the default links, and it only shows Powered by authentik
, which is equally hardcoded on things like Okta.
One thing I would like to eventually add for this is custom interface support, i.e. allow people to write their own frontend if they choose to do so, and host it under authentik.tld/if/<some name>/
, and with this they'd obviously have full control of what is shown
@benedikt-bartscher authentik doesn't really use django templates for much, there are very few sites that are server-side rendered as most everything of the UI is an SPA nowadays
Hi there @BeryJu thank you for the amazing project! Always nice to see polished Django in the nature.
Would you be open to accepting a PR that enables the removal of the branding Powered by authentik
via a config / env variable or is this something you would like to keep?
If you pay Okta enough they give you full white-labeling including separate servers btw - but it still is not selfhosted and outside of the EU 😇
Hey @matmair ,
If you need a quick fix, this is what I did in my docker-compose file. It's a massive hack, but it removes the powered by links and makes the css apply in more areas:
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-latest}
user: root
<<: *authentik-worker-environment
entrypoint: /bin/bash
command:
- -c
- |
DIST_DIR=web/dist
#---CUSTOM BACKGROUND
URL=https://picsum.photos/1920/1080/?blur&grayscale
curl -o $$DIST_DIR/assets/images/flow_background.jpg $$URL
#---CUSTOM_CSS_APPEND
read -r -d '' CSS << EOM
input {border-radius: 3px;border: 1px solid transparent;border-top: none;border-bottom: 1px solid #DDD;box-shadow: inset 0 1px 2px rgba(0,0,0,.39), 0 -1px 1px #FFF, 0 1px 0 #FFF;}
a[href^="https://goauthentik.io"] {display:none !important}
a[href^="https://unsplash.com"] {display:none !important}
EOM
echo "$$CSS" >> $$DIST_DIR/custom.css
#---CUSTOM_CSS_HEADER
for FILE in $$DIST_DIR/flow/*; do
sed -i "s|</header>|<link rel="stylesheet" type="text/css" href="/static/dist/custom.css"></header>|g" $$FILE
done
cp -R $$DIST_DIR/* /dist
/usr/local/bin/dumb-init -- /lifecycle/ak worker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- geoip:/geoip
- certs:/certs
- custom-templates:/templates
- media:/media
- dist:/dist
NOTE: This only works because I have my worker and server sharing a volume. The worker (running as root), modifies the files, and then copies them to the shared /dist folder on every boot. It then adds a link to the custom css where possible using sed in the template files.
Thanks @regbo, I have a similar solution. Mainly asked to get the go-ahead to address this upstream if there was interest from the maintainer but it does not seem so - which I respect.
Yes, this is a downside of how the whole uploading thing works, there could be a UI to show already uploaded files, allthough imo there's more important things before this
The easiest way would probably be to allow free text entry even if a /media
folder is mounted. Then I could upload a picture once using the upload button and local file selector and then just paste the same web path in other places, such as flow backgrounds.
BTW, an idea for other people who want to use a custom background without uploading the same file multiple times:
I worked around the image doubling issue by just not mounting /media
and instead mounting an external folder to /web/dist/extra
in the container. I can then manually upload files to that folder from the host. That folder is served to /static/dist/extra
.
As /media
isn't mounted, I get free text fields for media to enter any URL. E.g. for flow backgrounds I can then enter something like /static/dist/extra/mypicture.jpg
. Now I can reuse that link without uploading the same picture again and again.
That's a little more work and authentik doesn't detect a different picture is being used and still shows the "Background image" link to unsplash – even though that image isn't used anymore. But I can live with that.
@matmair and @Eisfunke ,
I simplified a lot of this by creating the following:
https://github.com/regbo/public-html/tree/master/authentik
It assumes that /dist is mounted on the worker, and that same volume is mounted to /web/dist on the servers. To use it, replace the entrypoint and command with this on the worker:
entrypoint: /bin/bash
command:
- -c
- |
curl -fsSL https://raw.githubusercontent.com/regbo/public-html/master/authentik/run-worker.sh | bash
The environment variable 'AUTHENTIK_FLOW_BACKGROUND_URL' can be used to set a background. Also, it auto injects .js and .css files by reading 'AUTHENTIK_INJECTURL*" environment variables. CSS files are injected into all doms, including the shadow roots. So for example, this is what I use in my docker config:
environment:
AUTHENTIK_FLOW_BACKGROUND_URL: ${AUTHENTIK_FLOW_BACKGROUND_URL:-https://raw.githubusercontent.com/regbo/public-html/master/background.png}
AUTHENTIK_INJECT_URL_0: https://rawcdn.githack.com/regbo/public-html/9dd48564ee00433ceced7177c6376731899e8147/authentik/input.css
AUTHENTIK_INJECT_URL_1: https://rawcdn.githack.com/regbo/public-html/444807d39c657ffef12ae1a8ea882ed7667eca3e/authentik/remove-branding.js
The above allows me to externalize some of the styling.
Authentik lack of white labeling / customization 🤨
nothing serious seems to be on the roadmap against that isn't it @BeryJu ?
Hi @regbo, I can't get your custumization working, my docker-compose.yml looks like this:
version: '3.4'
services:
postgresql:
image: docker.io/library/postgres:12-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- database:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${PG_PASS:?database password required}
- POSTGRES_USER=${PG_USER:-authentik}
- POSTGRES_DB=${PG_DB:-authentik}
env_file:
- .env
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.2}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./media:/media
- ./custom-templates:/templates
env_file:
- .env
ports:
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.2}
restart: unless-stopped
entrypoint: /bin/bash
command:
- -c
- |
curl -fsSL https://raw.githubusercontent.com/regbo/public-html/master/authentik/run-worker.sh | bash
environment:
AUTHENTIK_FLOW_BACKGROUND_URL: ${AUTHENTIK_FLOW_BACKGROUND_URL:-https://raw.githubusercontent.com/regbo/public-html/master/background.png}
AUTHENTIK_INJECT_URL_0: https://rawcdn.githack.com/regbo/public-html/9dd48564ee00433ceced7177c6376731899e8147/authentik/input.css
AUTHENTIK_INJECT_URL_1: https://rawcdn.githack.com/regbo/public-html/444807d39c657ffef12ae1a8ea882ed7667eca3e/authentik/remove-branding.js
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# `user: root` and the docker socket volume are optional.
# See more for the docker socket integration here:
# https://goauthentik.io/docs/outposts/integrations/docker
# Removing `user: root` also prevents the worker from fixing the permissions
# on the mounted folders, so when removing this make sure the folders have the correct UID/GID
# (1000:1000 by default)
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./media:/media
- ./certs:/certs
- ./custom-templates:/templates
env_file:
- .env
volumes:
database:
driver: local
redis:
driver: local
did I missed something or did I pasted it to the wrong place?
Thanks in advanced pupazze
for all who are also interessted in this, I still got no success with my customised docker-compose.yml file, but the solution working for me is nevertheless found in the details @regbo posted:
for FILE in /web/dist/flow/*; do
sed -i "s|</header>|<link rel="stylesheet" type="text/css" href="/static/dist/custom.css"></header>|g" $FILE
done
this bash part makes it possible for me to apply my custom css as wanted
So so so dirty hack 😮💨 I've switched back to Keycloak
Hey all,
Sorry for the delay. This is indeed a dirty nasty hack. But, FWIW, below is my compose file. The key is to make the server share the same dist directory as the worker instance. It won't work if they don't share a common volume across all instances (in my case I'm using gluster):
---
version: '3.4'
x-authentik-env: &authentik-env
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY?Variable not set}
AUTHENTIK_POSTGRESQL__HOST: ${AUTHENTIK_POSTGRESQL__HOST?Variable not set}
AUTHENTIK_POSTGRESQL__PORT: ${AUTHENTIK_POSTGRESQL__PORT:-5432}
AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRESQL__NAME?Variable not set}
AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRESQL__USER?Variable not set}
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRESQL__PASSWORD?Variable not set}
AUTHENTIK_POSTGRESQL__USE_PGBOUNCER: ${AUTHENTIK_POSTGRESQL__USE_PGBOUNCER:-False}
AUTHENTIK_EMAIL__HOST: postfix
AUTHENTIK_EMAIL__PORT: 25
AUTHENTIK_EMAIL__FROM: ${AUTHENTIK_EMAIL__FROM_NAME} <auth@${DOMAIN?Variable not set}>
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_AUTHENTIK__GEOIP: /geoip/GeoLite2-City.mmdb
AUTHENTIK_ERROR_REPORTING__ENABLED: "true"
AUTHENTIK_FOOTER_LINKS: "[]"
x-authentik-server-environment: &authentik-server-environment
environment:
<<: *authentik-env
x-authentik-worker-environment: &authentik-worker-environment
environment:
<<: *authentik-env
AUTHENTIK_FLOW_BACKGROUND_URL: ${AUTHENTIK_FLOW_BACKGROUND_URL:-https://raw.githubusercontent.com/regbo/public-html/master/authentik/background.png}
AUTHENTIK_BRAND_ICON_URL: ${AUTHENTIK_BRAND_ICON_URL?Variable nto set}
AUTHENTIK_INJECT_CSS_URL_0: https://raw.githubusercontent.com/regbo/public-html/master/authentik/input.css
AUTHENTIK_INJECT_CSS_URL_1: https://rawcdn.githack.com/regbo/public-html/2561d77f76d55b9f91afa697f2570f6ed74e6b94/authentik/hide-branding.css
services:
redis:
image: docker.io/library/redis:alpine
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:
- redis:/data
networks:
authentik:
aliases: [redis]
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: any
placement:
constraints: [node.role == manager]
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-latest}
hostname: authentik-server
<<: *authentik-server-environment
command: server
volumes:
- geoip:/geoip
- certs:/certs
- custom-templates:/templates
- media:/media
- dist:/web/dist
networks:
traefik-public: {}
authentik:
aliases: [authentik-server]
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m
deploy:
mode: global
restart_policy:
condition: any
placement:
constraints: [node.role == manager]
labels:
#required or treafik may select the correct ip
- traefik.docker.network=traefik-public
- traefik.enable=true
## Individual Application forwardAuth regex (catch any subdomain using individual application forwardAuth)
- traefik.http.routers.authentik-rtr-outpost.rule=Path(`/outpost.goauthentik.io`) || PathPrefix(`/outpost.goauthentik.io/`)
- traefik.http.routers.authentik-rtr-outpost.entrypoints=tcps
- traefik.http.routers.authentik-rtr-outpost.tls=true
- traefik.http.routers.authentik-rtr-outpost.priority=9223372036854775807
- traefik.http.routers.authentik-rtr-outpost.middlewares=authentik-mdw-outpost
- traefik.http.middlewares.authentik-mdw-outpost.headers.customresponseheaders.X-Authentik-Outpost=true
## HTTP Routers
- traefik.http.routers.authentik-rtr.rule=HostRegexp(`auth.{domain:\S+}`)
- traefik.http.routers.authentik-rtr.entrypoints=tcps
- traefik.http.routers.authentik-rtr.tls=true
# `authentik-server` refers to the service name in the compose file.
- traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik
- traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true
- traefik.http.middlewares.authentik.forwardauth.authResponseHeadersRegex=^X-Authentik-
## HTTP Services
- traefik.http.routers.authentik-rtr.service=authentik-svc
- traefik.http.services.authentik-svc.loadBalancer.server.port=9000
- traefik.http.services.authentik-svc.loadBalancer.sticky.cookie=true
- traefik.http.services.authentik-svc.loadBalancer.sticky.cookie.name=authentik_lb
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-latest}
user: root
<<: *authentik-worker-environment
entrypoint: /bin/bash
command:
- -c
- |
command -v jq >/dev/null 2>&1 || { echo "installing jq"; curl -fsSL https://glare.vercel.app/stedolan/jq/linux64 -o /usr/bin/jq; chmod +x /usr/bin/jq; }
echo "starting worker";
curl -fsSL https://api.github.com/repos/regbo/public-html/contents/authentik/run-worker.sh | jq -r ".content" | base64 --decode | bash
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- geoip:/geoip
- certs:/certs
- custom-templates:/templates
- media:/media
- dist:/dist
networks:
authentik: {}
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m
healthcheck:
test: ["CMD", "/lifecycle/ak", "healthcheck"]
interval: 30s
timeout: 30s
start_period: 60s
retries: 10
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
geoipupdate:
image: "maxmindinc/geoipupdate:latest"
volumes:
- "geoip:/usr/share/GeoIP"
environment:
GEOIPUPDATE_ACCOUNT_ID: ${GEOIPUPDATE_ACCOUNT_ID?Variable not set}
GEOIPUPDATE_LICENSE_KEY: ${GEOIPUPDATE_LICENSE_KEY?Variable not set}
GEOIPUPDATE_EDITION_IDS: "GeoLite2-City"
GEOIPUPDATE_FREQUENCY: "8"
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
postfix:
image: juanluisbaptiste/postfix:latest
environment:
SMTP_SERVER: ${POSTFIX_SMTP_HOST?Variable not set}
SMTP_PORT: ${POSTFIX_SMTP_PORT:-587}
SMTP_USERNAME: ${POSTFIX_SMTP_USERNAME}
SMTP_PASSWORD: ${POSTFIX_SMTP_PASSWORD}
SERVER_HOSTNAME: ${DOMAIN?Variable not set}
LOG_SUBJECT: "true"
DEBUG: ${POSTFIX_DEBUG:-false}
networks:
authentik:
aliases: [postfix]
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints:
- ${POSTFIX_DEPLOY_PLACEMENT_CONSTRAINTS:-node.role == manager}
volumes:
redis:
driver: "local"
driver_opts:
type: "none"
o: "bind"
device: "/mnt/gluster/authentik/redis"
geoip:
driver: "local"
driver_opts:
type: "none"
o: "bind"
device: "/mnt/gluster/authentik/geoip"
certs:
driver: "local"
driver_opts:
type: "none"
o: "bind"
device: "/mnt/gluster/authentik/certs"
custom-templates:
driver: "local"
driver_opts:
type: "none"
o: "bind"
device: "/mnt/gluster/authentik/custom-templates"
media:
driver: "local"
driver_opts:
type: "none"
o: "bind"
device: "/mnt/gluster/authentik/media"
dist:
driver: "local"
driver_opts:
type: "none"
o: "bind"
device: "/mnt/gluster/authentik/dist"
networks:
authentik: {}
traefik-public:
external: true
I want to know if I can use docker mount volume to replace the flow_background.jpg and branding logo, sidebar icon directly? Don't care about the footer links and others?
I want to know if I can use docker mount volume to replace the flow_background.jpg and branding logo, sidebar icon directly? Don't care about the footer links and others?
I do this in my environment:
- /myimg.jpg:/web/dist/assets/images/flow_background.jpg
It might be cached, so do a hard refresh after changing.
This might be closed by #4804.
@regbo @pupazze Does this solve your situation so you don't have to futz so much with the container? I have had great success using pure CSS so far. Specifically on updating the background: https://github.com/goauthentik/authentik/issues/4586#issuecomment-1452051178
were you smh able to make the cards rounded with a custom.css?
4831
youre not on "2023.2.3" right? stuff like this is still wrong for me (the orange part):
You need to update to gh-main
(step three) or the PR branch until #4804 lands in a release.
We'll be finalising #5048 hopefully soon-ish, the whitelabelling will be an option for enterprise licenses. For the file upload, as a relatively simple option, we're considering giving people that run authentik in docker-compose the option to set files to URLs (which is the default behaviour when no persistent storage is mounted, like on K8s), which would slightly improve this
It would also be great if the tenant logo input would have the same file-picker logic as application logos have (i.e. show a file-picker if a volume is mounted under /media
and also offer the possibility to revert back to the default again)
Another bug-ish issue is that Authentik offers to delete images even when once under /dist/static
are referenced which it definitely should not. In general media/file-input handling seems like it would benefit from a bit of a cleanup, either making it more powerful (separate media section similar to certificates, fa-icon overview etc.) or keeping it simpler but avoiding inconsistencies (get rid of the delete option, only always offer text field etc.).
As a heads up to @BeryJu comment above, it appears setting URLs, e.g. for a Tenant's Logo or Favicon, is now also possible when /media
is mounted into the 2023.8.1
container.
To update this issue:
Powered by authentik
footer for enterprise customersI'd like to add that, if possible, this function should be collecting the brand's logo path instead of the default logo's path. Additionally, the email stuff should overall support branding better as it stands with the event log even reflecting "Brand fallback" no matter the configuration.
Edit: I'll add the feature if anyone wants to point me in the right direction.
Is your feature request related to a problem? Please describe. The branding / customisation of authentik is somewhat inconsistent. While every flow can be branded in some way (wording, background image), a few things like the URL https://authentik.tld/if/session-end/my-app-name can't, as far as I can see.
Describe the solution you'd like Different stages may be possible:
Describe alternatives you've considered I might have overlooked something during the long hours I have looked into the customization details. In this case, please point me in the right direction, downgrade this to "question", and I'll share my findings here