diff --git a/.env.sample b/.env.sample index 4dbb118..f45f555 100644 --- a/.env.sample +++ b/.env.sample @@ -33,3 +33,6 @@ AUTHENTIK_LOG_LEVEL=info # SECRET_ADMIN_PASS_VERSION=v1 # X_FRAME_OPTIONS_ALLOW_FROM=dashboard.example.org +## FLOW OPTIONS +WELCOME_MESSAGE="Welcome to Authentik" +DEFAULT_LANGUAGE=en diff --git a/abra.sh b/abra.sh index f4b3f2a..2e5874a 100644 --- a/abra.sh +++ b/abra.sh @@ -1 +1,2 @@ export CUSTOM_CSS_VERSION=v1 +export CUSTOM_FLOWS_VERSION=v1 diff --git a/compose.yml b/compose.yml index 41f6642..b97893a 100644 --- a/compose.yml +++ b/compose.yml @@ -20,6 +20,9 @@ x-env: &env - AUTHENTIK_EMAIL__FROM - AUTHENTIK_LOG_LEVEL - AUTHENTIK_SETTINGS__THEME__BACKGROUND + - WELCOME_MESSAGE + - DEFAULT_LANGUAGE + - DOMAIN version: '3.8' @@ -83,6 +86,9 @@ services: - media:/media - /var/run/docker.sock:/var/run/docker.sock - custom-templates:/templates + configs: + - source: custom_flows + target: /blueprints/custom_flows.yaml environment: *env db: @@ -151,3 +157,7 @@ configs: name: ${STACK_NAME}_custom_css_${CUSTOM_CSS_VERSION} file: custom.css.tmpl template_driver: golang + custom_flows: + name: ${STACK_NAME}_custom_flows_${CUSTOM_FLOWS_VERSION} + file: custom_flows.yaml.tmpl + template_driver: golang diff --git a/custom_flows.yaml.tmpl b/custom_flows.yaml.tmpl new file mode 100644 index 0000000..be4c381 --- /dev/null +++ b/custom_flows.yaml.tmpl @@ -0,0 +1,355 @@ +version: 1 +metadata: + labels: + blueprints.goauthentik.io/instantiate: "true" + name: Custom - Flows +context: +####### Translations ######## + transl_recovery: {{ if eq (env "DEFAULT_LANGUAGE") "de" }} Passwort Zurücksetzen {{ else }} Reset your password {{ end }} + transl_password: {{ if eq (env "DEFAULT_LANGUAGE") "de" }} Passwort {{ else }} Password {{ end }} + transl_password_repeat: {{ if eq (env "DEFAULT_LANGUAGE") "de" }} Passwort (wiederholen) {{ else }} Password (repeat) {{ end }} + transl_username: {{ if eq (env "DEFAULT_LANGUAGE") "de" }} Benutzername {{ else }} Username {{ end }} + transl_name: {{ if eq (env "DEFAULT_LANGUAGE") "de" }} Vor- und Nachname {{ else }} Full name {{ end }} + +entries: +######## Email Recovery Flow ######## +- identifiers: + slug: default-recovery-flow + id: recovery_flow + model: authentik_flows.flow + attrs: + name: Default recovery flow + title: !Context transl_recovery + designation: recovery + +### PROMPTS +- identifiers: + field_key: password + label: !Context transl_password + id: prompt-field-password + model: authentik_stages_prompt.prompt + attrs: + type: password + required: true + placeholder: !Context transl_password + order: 30 + placeholder_expression: false +- identifiers: + field_key: password_repeat + label: !Context transl_password_repeat + id: prompt-field-password-repeat + model: authentik_stages_prompt.prompt + attrs: + type: password + required: true + placeholder: !Context transl_password_repeat + order: 31 + placeholder_expression: false + + +### STAGES +- identifiers: + name: default-recovery-email + id: default-recovery-email + model: authentik_stages_email.emailstage + attrs: + use_global_settings: true + token_expiry: 30 + subject: authentik + template: email/password_reset.html + activate_user_on_success: true +- identifiers: + name: default-recovery-user-write + id: default-recovery-user-write + model: authentik_stages_user_write.userwritestage +- identifiers: + name: default-recovery-identification + id: default-recovery-identification + model: authentik_stages_identification.identificationstage + attrs: + user_fields: + - email + - username +- identifiers: + name: default-recovery-user-login + id: default-recovery-user-login + model: authentik_stages_user_login.userloginstage + attrs: + session_duration: seconds=0 +- identifiers: + name: Change your password + id: stage-prompt-password + model: authentik_stages_prompt.promptstage + attrs: + fields: + - !KeyOf prompt-field-password + - !KeyOf prompt-field-password-repeat + validation_policies: [] + +### STAGE BINDINGS +- identifiers: + target: !KeyOf recovery_flow + stage: !KeyOf default-recovery-identification + order: 10 + model: authentik_flows.flowstagebinding + id: flow-binding-identification + attrs: + evaluate_on_plan: true + re_evaluate_policies: true + policy_engine_mode: any + invalid_response_action: retry +- identifiers: + target: !KeyOf recovery_flow + stage: !KeyOf default-recovery-email + order: 20 + model: authentik_flows.flowstagebinding + id: flow-binding-email + attrs: + evaluate_on_plan: true + re_evaluate_policies: true + policy_engine_mode: any + invalid_response_action: retry +- identifiers: + target: !KeyOf recovery_flow + stage: !KeyOf stage-prompt-password + order: 30 + model: authentik_flows.flowstagebinding + attrs: + evaluate_on_plan: true + re_evaluate_policies: false + policy_engine_mode: any + invalid_response_action: retry +- identifiers: + target: !KeyOf recovery_flow + stage: !KeyOf default-recovery-user-write + order: 40 + model: authentik_flows.flowstagebinding + attrs: + evaluate_on_plan: true + re_evaluate_policies: false + policy_engine_mode: any + invalid_response_action: retry +- identifiers: + target: !KeyOf recovery_flow + stage: !KeyOf default-recovery-user-login + order: 100 + model: authentik_flows.flowstagebinding + attrs: + evaluate_on_plan: true + re_evaluate_policies: false + policy_engine_mode: any + invalid_response_action: retry + +### POLICIES +## ISSUES with this policy +## https://github.com/goauthentik/authentik/blob/493cdd5c0f8caaec7a7dd474f1aa131e32fd39c3/blueprints/example/flows-recovery-email-verification.yaml#L37 +## https://github.com/goauthentik/authentik/commit/317e9ec6053742e17ba74fb6aa38dc15aaf6657f#diff-a5c56bb7c60e27dda1b131b3fc2a17e3af6624e7cfaaa2337ec6b077ca489f34 +# - identifiers: +# name: default-recovery-skip-if-restored +# id: default-recovery-skip-if-restored +# model: authentik_policies_expression.expressionpolicy +# attrs: +# expression: | +# return request.context.get('is_restored', False) + +### POLICY BINDINGS +# - identifiers: +# policy: !KeyOf default-recovery-skip-if-restored +# target: !KeyOf flow-binding-identification +# order: 0 +# model: authentik_policies.policybinding +# attrs: +# negate: false +# enabled: true +# timeout: 30 +# - identifiers: +# policy: !KeyOf default-recovery-skip-if-restored +# target: !KeyOf flow-binding-email +# order: 0 +# model: authentik_policies.policybinding +# attrs: +# negate: false +# enabled: true +# timeout: 30 + + + +######## Authentication Flow ######## +- attrs: + designation: authentication + name: custom-authentication-flow + title: {{ env "WELCOME_MESSAGE" }} + identifiers: + slug: custom-authentication-flow + id: authentication_flow + model: authentik_flows.flow + +### STAGES +- attrs: + backends: + - authentik.core.auth.InbuiltBackend + - authentik.sources.ldap.auth.LDAPBackend + - authentik.core.auth.TokenBackend + configure_flow: !Find [authentik_flows.flow, [slug, default-password-change]] + identifiers: + name: custom-authentication-password + id: custom-authentication-password + model: authentik_stages_password.passwordstage + +- identifiers: + name: custom-authentication-mfa-validation + id: custom-authentication-mfa-validation + model: authentik_stages_authenticator_validate.authenticatorvalidatestage + +- attrs: + password_stage: !KeyOf custom-authentication-password + recovery_flow: !KeyOf recovery_flow # !Find [authentik_flows.flow, [slug, default-recovery-flow]] + user_fields: + - email + - username + identifiers: + name: custom-authentication-identification + id: custom-authentication-identification + model: authentik_stages_identification.identificationstage + +- attrs: + session_duration: seconds=0 + identifiers: + name: custom-authentication-login + id: custom-authentication-login + model: authentik_stages_user_login.userloginstage + +### STAGE BINDINGS +- identifiers: + order: 10 + stage: !KeyOf custom-authentication-identification + target: !KeyOf authentication_flow + model: authentik_flows.flowstagebinding +- identifiers: + order: 30 + stage: !KeyOf custom-authentication-mfa-validation + target: !KeyOf authentication_flow + model: authentik_flows.flowstagebinding +- identifiers: + order: 100 + stage: !KeyOf custom-authentication-login + target: !KeyOf authentication_flow + model: authentik_flows.flowstagebinding + +######## Invitation Enrollment Flow ######## +- attrs: + designation: enrollment + name: invitation-enrollment-flow + title: {{ env "WELCOME_MESSAGE" }} + identifiers: + slug: invitation-enrollment-flow + id: invitation-enrollment-flow + model: authentik_flows.flow + +### PROMPTS +- identifiers: + field_key: username + label: !Context transl_username + id: prompt-field-username + model: authentik_stages_prompt.prompt + attrs: + type: username + required: true + placeholder: !Context transl_username + order: 0 + placeholder_expression: false +- identifiers: + field_key: name + label: !Context transl_name + id: prompt-field-name + model: authentik_stages_prompt.prompt + attrs: + type: text + required: true + placeholder: !Context transl_name + order: 1 + placeholder_expression: false +- identifiers: + field_key: email + label: Email + id: prompt-field-email + model: authentik_stages_prompt.prompt + attrs: + type: email + required: true + placeholder: muster@example.com + order: 2 + placeholder_expression: false + +### STAGES + +- id: invitation-stage + identifiers: + name: invitation-stage + model: authentik_stages_invitation.invitationstage + +- attrs: + fields: + - !KeyOf prompt-field-username + - !KeyOf prompt-field-name + - !KeyOf prompt-field-email + - !KeyOf prompt-field-password + - !KeyOf prompt-field-password-repeat + id: enrollment-prompt-userdata + identifiers: + name: enrollment-prompt-userdata + model: authentik_stages_prompt.promptstage + +- id: enrollment-user-write + identifiers: + name: enrollment-user-write + model: authentik_stages_user_write.userwritestage + +- attrs: + session_duration: seconds=0 + id: enrollment-user-login + identifiers: + name: enrollment-user-login + model: authentik_stages_user_login.userloginstage + +### STAGE BINDINGS +- identifiers: + order: 1 + stage: !KeyOf invitation-stage + target: !KeyOf invitation-enrollment-flow + model: authentik_flows.flowstagebinding +- identifiers: + order: 10 + stage: !KeyOf enrollment-prompt-userdata + target: !KeyOf invitation-enrollment-flow + model: authentik_flows.flowstagebinding +- identifiers: + order: 20 + stage: !KeyOf enrollment-user-write + target: !KeyOf invitation-enrollment-flow + model: authentik_flows.flowstagebinding +- identifiers: + order: 100 + stage: !KeyOf enrollment-user-login + target: !KeyOf invitation-enrollment-flow + model: authentik_flows.flowstagebinding + +######## System Tenant ########## +- attrs: + attributes: + settings: + locale: {{ env "DEFAULT_LANGUAGE" }} + # branding_favicon: /static/dist/assets/icons/icon.png + # branding_logo: /static/dist/assets/icons/icon_left_brand.svg + # branding_title: Authentik + # default: true + domain: {{ env "DOMAIN" }} + # event_retention: days=365 + flow_authentication: !KeyOf authentication_flow + flow_recovery: !KeyOf recovery_flow + flow_invalidation: !Find [authentik_flows.flow, [slug, default-invalidation-flow]] + flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]] + identifiers: + pk: 047cce25-aae2-4b02-9f96-078e155f803d + id: system_tenant + model: authentik_tenants.tenant