From 99a0b05fb1cd09f593e2e4e46e6618b2ea1c122f Mon Sep 17 00:00:00 2001 From: val Date: Tue, 24 Mar 2026 18:42:04 +0100 Subject: [PATCH 1/2] working version --- .env.sample | 11 +++++++ README.md | 15 ++++++++- abra.sh | 1 + compose.authentikgroupsync.yml | 54 ++++++++++++++++++++++++++++++++ entrypoint.authentikgroupsync.sh | 30 ++++++++++++++++++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 compose.authentikgroupsync.yml create mode 100644 entrypoint.authentikgroupsync.sh diff --git a/.env.sample b/.env.sample index e1d4b02..584fd8b 100644 --- a/.env.sample +++ b/.env.sample @@ -96,3 +96,14 @@ FILE_STORAGE_UPLOAD_MAX_SIZE=26214400 #AWS_S3_FORCE_PATH_STYLE=true #AWS_S3_ACL=private #SECRET_AWS_SECRET_KEY_VERSION=v1 + +# COMPOSE_FILE="$COMPOSE_FILE:compose.authentikgroupsync.yml" +# # details on env here: https://github.com/burritosoftware/Outline-Authentik-Connector/blob/master/.env.example +# AGS_AUTHENTIK_URL= +# SECRET_AGS_OUTLINE_TOKEN_VERSION=v1 +# SECRET_AGS_AUTHENTIK_TOKEN_VERSION=v1 +# SECRET_AGS_WEBHOOK_SECRET_VERSION=v1 +# SECRET_AGS_WEBHOOK_SECRET_VERSION=v1 +# AGS_AUTO_CREATE_GROUPS=True +# #AGS_SYNC_GROUP_REGEX= +# #AGS_DEBUG=True \ No newline at end of file diff --git a/README.md b/README.md index 4c448b8..74c7d39 100644 --- a/README.md +++ b/README.md @@ -78,4 +78,17 @@ revisions to (instead of deleting them). - **Valid Redirect URIs**: `https://YOURAPPDOMAIN/auth/oidc.callback` - Reference the client/provider info to populate the `_AUTH_URI` `_TOKEN_URI` and `_USERINFO_URI` values - Set the OIDC secret using the value from the client/provider `abra app secret insert YOURAPPNAME oidc_client_secret v1 SECRETVALUE` -- `abra app deploy YOURAPPDOMAIN` \ No newline at end of file +- `abra app deploy YOURAPPDOMAIN` + +### Advanced: Group Sync with Authentik +- As `outline` doesn't support group sync, you can make use of an [extra service, the Outline-Authentik-Connector,](https://github.com/burritosoftware/Outline-Authentik-Connector) to do so. +- Just uncomment the respective section in your `.env`, and set the necessary envs. +- Then [follow these instructions](https://github.com/burritosoftware/Outline-Authentik-Connector?tab=readme-ov-file#outline-setup) to create the needed user and tokens + - ! for the authentik-token make sure you don't use the token it shows when creating the user (that is a password), create as the user (it will expire) but in the admin interface (path: `https://login..../if/admin/#/core/tokens`). Also setting the needed global permissions was not possible on the user directly, but I had to create a role for this. + +- and insert them as secrets: +``` +abra app secret insert YOURAPPNAME ags_outline_token v1 SECRETVALUE +abra app secret insert YOURAPPNAME ags_authentik_token v1 SECRETVALUE +abra app secret insert YOURAPPNAME ags_webhook_secret v1 SECRETVALUE +``` \ No newline at end of file diff --git a/abra.sh b/abra.sh index 31b06d9..fdaeff6 100644 --- a/abra.sh +++ b/abra.sh @@ -1,6 +1,7 @@ export APP_ENTRYPOINT_VERSION=v11 export DB_ENTRYPOINT_VERSION=v2 export PG_BACKUP_VERSION=v1 +export AGS_ENTRYPOINT_VERSION=v1 create_email_user() { if [ -z "$1" ]; then diff --git a/compose.authentikgroupsync.yml b/compose.authentikgroupsync.yml new file mode 100644 index 0000000..405351c --- /dev/null +++ b/compose.authentikgroupsync.yml @@ -0,0 +1,54 @@ +--- +version: "3.8" + +services: + outline-authentik-connector: + image: burritosoftware/outline-authentik-connector:latest + + secrets: + - ags_outline_token + - ags_authentik_token + - ags_webhook_secret + environment: + - AUTHENTIK_URL=${AGS_AUTHENTIK_URL} + - OUTLINE_URL=https://${DOMAIN} + - OUTLINE_TOKEN_FILE=/var/run/secrets/ags_outline_token + - OUTLINE_WEBHOOK_SECRET_FILE=/var/run/secrets/ags_webhook_secret + - AUTHENTIK_TOKEN_FILE=/var/run/secrets/ags_authentik_token + - AUTO_CREATE_GROUPS=${AGS_AUTO_CREATE_GROUPS:-True} + - DEBUG=${AGS_DEBUG:-False} + - SYNC_GROUP_REGEX=${AGS_SYNC_GROUP_REGEX:-.*} + deploy: + labels: + - "traefik.enable=true" + - "traefik.http.routers.sync-router.rule=Host(`groupsync.${DOMAIN}`)" + - "traefik.http.routers.sync-router.entrypoints=web-secure" + - "traefik.http.routers.sync-router.tls.certresolver=${LETS_ENCRYPT_ENV}" + - "traefik.http.services.sync-router.loadbalancer.server.port=80" + + networks: + - backend + - proxy + + configs: + - source: ags_entrypoint + target: /docker-entrypoint.sh + mode: 0555 + + entrypoint: /docker-entrypoint.sh + +secrets: + ags_outline_token: + name: ${STACK_NAME}_ags_outline_token_${SECRET_AGS_OUTLINE_TOKEN_VERSION} + external: true + ags_authentik_token: + name: ${STACK_NAME}_ags_authentik_token_${SECRET_AGS_AUTHENTIK_TOKEN_VERSION} + external: true + ags_webhook_secret: + name: ${STACK_NAME}_ags_webhook_secret_${SECRET_AGS_WEBHOOK_SECRET_VERSION} + external: true + +configs: + ags_entrypoint: + name: ${STACK_NAME}_ags_entrypoint_${AGS_ENTRYPOINT_VERSION} + file: entrypoint.authentikgroupsync.sh \ No newline at end of file diff --git a/entrypoint.authentikgroupsync.sh b/entrypoint.authentikgroupsync.sh new file mode 100644 index 0000000..87c8df9 --- /dev/null +++ b/entrypoint.authentikgroupsync.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +set -e + +load_secret() { + env_var="$1" + secret_file="$2" + + if [ -f "$secret_file" ]; then + value=$(cat "$secret_file") + if [ -z "$value" ]; then + echo >&2 "error: $secret_file is empty" + exit 1 + fi + export "$env_var"="$value" + else + echo >&2 "[info] didn't set $env_var because $secret_file does not exist. If you don't use the secret or it is no secret at all you can safely ignore this message." + fi +} + +# load every env-var that ends on _FILE +for var in $(env | grep "_FILE="); do + key=$(echo "$var" | sed 's/_FILE=.*//') + value=$(echo "$var" | sed 's/.*_FILE=//') + load_secret "$key" "$value" + + echo "loaded $key=$value" +done + +exec uvicorn connect:app --host=0.0.0.0 --port=80 \ No newline at end of file -- 2.49.0 From 3355293a0545833bfa8bfc3f267eb8a9fbd6a260 Mon Sep 17 00:00:00 2001 From: val Date: Wed, 25 Mar 2026 14:32:18 +0100 Subject: [PATCH 2/2] shortened secrets, added healthcheck, removed debug log --- .env.sample | 1 - README.md | 6 +++--- compose.authentikgroupsync.yml | 34 ++++++++++++++++++++------------ entrypoint.authentikgroupsync.sh | 2 -- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/.env.sample b/.env.sample index 584fd8b..cd1df38 100644 --- a/.env.sample +++ b/.env.sample @@ -103,7 +103,6 @@ FILE_STORAGE_UPLOAD_MAX_SIZE=26214400 # SECRET_AGS_OUTLINE_TOKEN_VERSION=v1 # SECRET_AGS_AUTHENTIK_TOKEN_VERSION=v1 # SECRET_AGS_WEBHOOK_SECRET_VERSION=v1 -# SECRET_AGS_WEBHOOK_SECRET_VERSION=v1 # AGS_AUTO_CREATE_GROUPS=True # #AGS_SYNC_GROUP_REGEX= # #AGS_DEBUG=True \ No newline at end of file diff --git a/README.md b/README.md index 74c7d39..df83d46 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ revisions to (instead of deleting them). - and insert them as secrets: ``` -abra app secret insert YOURAPPNAME ags_outline_token v1 SECRETVALUE -abra app secret insert YOURAPPNAME ags_authentik_token v1 SECRETVALUE -abra app secret insert YOURAPPNAME ags_webhook_secret v1 SECRETVALUE +abra app secret insert YOURAPPNAME agsoutline v1 SECRETVALUE +abra app secret insert YOURAPPNAME agsauthentik v1 SECRETVALUE +abra app secret insert YOURAPPNAME agswebhook v1 SECRETVALUE ``` \ No newline at end of file diff --git a/compose.authentikgroupsync.yml b/compose.authentikgroupsync.yml index 405351c..a6164d8 100644 --- a/compose.authentikgroupsync.yml +++ b/compose.authentikgroupsync.yml @@ -3,21 +3,23 @@ version: "3.8" services: outline-authentik-connector: - image: burritosoftware/outline-authentik-connector:latest + image: burritosoftware/outline-authentik-connector:1.2 secrets: - - ags_outline_token - - ags_authentik_token - - ags_webhook_secret + - agsoutline + - agsauthentik + - agswebhook + environment: - AUTHENTIK_URL=${AGS_AUTHENTIK_URL} - OUTLINE_URL=https://${DOMAIN} - - OUTLINE_TOKEN_FILE=/var/run/secrets/ags_outline_token - - OUTLINE_WEBHOOK_SECRET_FILE=/var/run/secrets/ags_webhook_secret - - AUTHENTIK_TOKEN_FILE=/var/run/secrets/ags_authentik_token + - OUTLINE_TOKEN_FILE=/var/run/secrets/agsoutline + - OUTLINE_WEBHOOK_SECRET_FILE=/var/run/secrets/agswebhook + - AUTHENTIK_TOKEN_FILE=/var/run/secrets/agsauthentik - AUTO_CREATE_GROUPS=${AGS_AUTO_CREATE_GROUPS:-True} - DEBUG=${AGS_DEBUG:-False} - SYNC_GROUP_REGEX=${AGS_SYNC_GROUP_REGEX:-.*} + deploy: labels: - "traefik.enable=true" @@ -26,6 +28,12 @@ services: - "traefik.http.routers.sync-router.tls.certresolver=${LETS_ENCRYPT_ENV}" - "traefik.http.services.sync-router.loadbalancer.server.port=80" + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://0.0.0.0:80/ | grep -q '\"status\":\"running\"' || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + networks: - backend - proxy @@ -38,14 +46,14 @@ services: entrypoint: /docker-entrypoint.sh secrets: - ags_outline_token: - name: ${STACK_NAME}_ags_outline_token_${SECRET_AGS_OUTLINE_TOKEN_VERSION} + agsoutline: + name: ${STACK_NAME}_agsoutline_${SECRET_AGS_OUTLINE_TOKEN_VERSION} external: true - ags_authentik_token: - name: ${STACK_NAME}_ags_authentik_token_${SECRET_AGS_AUTHENTIK_TOKEN_VERSION} + agsauthentik: + name: ${STACK_NAME}_agsauthentik_${SECRET_AGS_AUTHENTIK_TOKEN_VERSION} external: true - ags_webhook_secret: - name: ${STACK_NAME}_ags_webhook_secret_${SECRET_AGS_WEBHOOK_SECRET_VERSION} + agswebhook: + name: ${STACK_NAME}_agswebhook_${SECRET_AGS_WEBHOOK_SECRET_VERSION} external: true configs: diff --git a/entrypoint.authentikgroupsync.sh b/entrypoint.authentikgroupsync.sh index 87c8df9..cc49aaf 100644 --- a/entrypoint.authentikgroupsync.sh +++ b/entrypoint.authentikgroupsync.sh @@ -23,8 +23,6 @@ for var in $(env | grep "_FILE="); do key=$(echo "$var" | sed 's/_FILE=.*//') value=$(echo "$var" | sed 's/.*_FILE=//') load_secret "$key" "$value" - - echo "loaded $key=$value" done exec uvicorn connect:app --host=0.0.0.0 --port=80 \ No newline at end of file -- 2.49.0