diff --git a/authentik-application/README.md b/authentik-application/README.md index 7218441..1ee7c55 100644 --- a/authentik-application/README.md +++ b/authentik-application/README.md @@ -121,7 +121,8 @@ helm uninstall authentik-application-release | blueprint.provider.proxy.ingress.domain | string | `nil` | domain of application (where outpost should be deployed) | | blueprint.provider.proxy.ingress.enabled | bool | `false` | deploy ingress on application domain for e.g. logout (WIP) | | blueprint.provider.proxy.skipPathRegex | string | `""` | | -| blueprint.provider.type | string | `"oidc"` | type of application connection, current support: oidc and proxy | +| blueprint.provider.saml | string | `nil` | | +| blueprint.provider.type | string | `"oidc"` | type of application connection, current support: oidc, saml and proxy | | secret.labels | object | `{}` | label of secret to store generated secret | | secret.name | string | `""` | name of secret to store generated secret (like clientI) | diff --git a/authentik-application/files/application.yaml.gotmpl b/authentik-application/files/application.yaml.gotmpl new file mode 100644 index 0000000..51e4a82 --- /dev/null +++ b/authentik-application/files/application.yaml.gotmpl @@ -0,0 +1,30 @@ +{{- with get . "root" }} +- model: authentik_core.Application + id: {{ .Values.blueprint.application.name | default (include "authentik-application.fullname" .) }} + identifiers: + slug: {{ .Values.blueprint.application.slug }} + state: present + attrs: + name: {{ .Values.blueprint.application.name | default (include "authentik-application.fullname" .) }} + slug: {{ .Values.blueprint.application.slug }} + {{- if .Values.blueprint.provider.enabled }} + provider: !KeyOf {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} + {{- end }} + policy_engine_mode: {{ .Values.blueprint.application.policyEngineMode }} + {{- with .Values.blueprint.application.group }} + group: {{ . | quote }} + {{- end }} + {{- with .Values.blueprint.application.launchURL }} + meta_launch_url: {{ . | quote }} + {{- end }} + open_in_new_tab: {{ toYaml .Values.blueprint.application.openInNewTab }} + {{- with .Values.blueprint.application.icon }} + icon: {{ . | quote }} + {{- end }} + {{- with .Values.blueprint.application.description }} + meta_description: {{ . | quote }} + {{- end }} + {{- with .Values.blueprint.application.publisher }} + meta_publisher: {{ . | quote }} + {{- end }} +{{- end }}{{/* end with of get-root */}} diff --git a/authentik-application/files/groups.yaml.gotmpl b/authentik-application/files/groups.yaml.gotmpl new file mode 100644 index 0000000..840222c --- /dev/null +++ b/authentik-application/files/groups.yaml.gotmpl @@ -0,0 +1,47 @@ +{{- $bindPolicyID := get . "bindPolicyID" }} +{{- with get . "root" }} +{{- if (not (kindIs "slice" .Values.blueprint.groups)) }} + +- model: authentik_core.group + id: "app: {{ .Values.blueprint.application.slug }}" + identifiers: + name: "app: {{ .Values.blueprint.application.slug }}" + state: "present" + attrs: + name: "app: {{ .Values.blueprint.application.slug }}" + +- model: authentik_policies.PolicyBinding + id: {{ printf "%s-app-%s" (include "authentik-application.fullname" .) .Values.blueprint.application.slug | quote }} + identifiers: + pk: {{ $bindPolicyID | quote }} + attrs: + group: !KeyOf "app: {{ .Values.blueprint.application.slug }}" + order: 10 + target: !Find [authentik_core.Application, [slug, {{ .Values.blueprint.application.slug }}]] +{{- end }} + +{{- range $group := .Values.blueprint.groups }} + +- model: authentik_core.group + id: {{ $group.slug | quote }} + identifiers: + name: {{ $group.slug | quote }} + state: {{ $group.state | default "present" | quote }} + attrs: + name: {{ $group.slug | quote }} + {{- with $group.parent }} + parent: !Find [authentik_core.group, [name, {{ . | quote }}]] + {{- else}} + parent: null + {{- end }} + +- model: authentik_policies.PolicyBinding + id: {{ printf "%s-app-%s" (include "authentik-application.fullname" $) $group.slug | quote }} + identifiers: + pk: {{ $group.bindID | quote }} + attrs: + group: !KeyOf {{ $group.slug | quote}} + order: 10 + target: !Find [authentik_core.Application, [slug, {{ $.Values.blueprint.application.slug }}]] +{{- end }} +{{- end }}{{/* end with of get-root */}} diff --git a/authentik-application/files/provider/oidc.yaml.gotmpl b/authentik-application/files/provider/oidc.yaml.gotmpl new file mode 100644 index 0000000..c90f18f --- /dev/null +++ b/authentik-application/files/provider/oidc.yaml.gotmpl @@ -0,0 +1,29 @@ +{{- $clientID := get . "clientID" }} +{{- $clientSecret := get . "clientSecret" }} +{{- with get . "root" }} +- model: authentik_providers_oauth2.OAuth2Provider + id: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} + identifiers: + name: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} + state: present + attrs: + authorization_flow: !Find [authentik_flows.flow, [slug, {{ .Values.blueprint.provider.authorizationFlow }}]] + {{- with .Values.blueprint.provider.oidc }} + client_type: {{ .clientType | quote }} + client_id: {{ $clientID | quote }} + client_secret: {{ $clientSecret | quote }} + redirect_uris: {{ .redirectURL }} + {{- with .tokenDuration }} + access_token_validity: {{ . | quote }} + {{- end }} + {{- with .signingKey }} + signing_key: !Find [authentik_crypto.CertificateKeyPair, [name, {{ . }}]] + {{- end }} + {{- with .scopes }} + property_mappings: + {{- range . }} + - !Find [authentik_providers_oauth2.ScopeMapping, [scope_name, {{ . }}]] + {{- end }} + {{- end }} + {{- end }} +{{- end }}{{/* end with of get-root */}} diff --git a/authentik-application/files/provider/proxy.yaml.gotmpl b/authentik-application/files/provider/proxy.yaml.gotmpl new file mode 100644 index 0000000..d67d8c4 --- /dev/null +++ b/authentik-application/files/provider/proxy.yaml.gotmpl @@ -0,0 +1,15 @@ +{{- with get . "root" }} +- model: authentik_providers_proxy.ProxyProvider + id: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} + identifiers: + name: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} + state: present + attrs: + authorization_flow: !Find [authentik_flows.flow, [slug, {{ .Values.blueprint.provider.authorizationFlow }}]] + mode: "forward_single" + {{- with .Values.blueprint.provider.proxy }} + external_host: {{ .externalHost | quote }} + skip_path_regex: {{ .skipPathRegex | quote }} + cookie_domain: {{ .cookieDomain | quote }} + {{- end }} +{{- end }}{{/* end with of get-root */}} diff --git a/authentik-application/templates/_helpers.tpl b/authentik-application/templates/_helpers.tpl index 3eb9b18..93dd0fb 100644 --- a/authentik-application/templates/_helpers.tpl +++ b/authentik-application/templates/_helpers.tpl @@ -60,3 +60,19 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} + +{{/* +needs argument: + root: $.Values + name: + default: + overwrite: +*/}} +{{- define "authentik-application.staticValue" -}} +{{- $ := get . "root" }} +{{- $secretName := $.Values.secret.name | default (include "authentik-application.fullname" $) }} +{{- $secretObj := (lookup "v1" "Secret" $.Release.Namespace $secretName) | default dict }} +{{- $secretData := (get $secretObj "data") | default dict }} +{{- $valueCoded := (get $secretData .name) | default (.default | b64enc) }} +{{- .overwrite | default ($valueCoded | b64dec) }} +{{- end }} diff --git a/authentik-application/templates/secrets.yaml b/authentik-application/templates/secrets.yaml index 696a67a..9e59346 100644 --- a/authentik-application/templates/secrets.yaml +++ b/authentik-application/templates/secrets.yaml @@ -1,36 +1,24 @@ -{{- $clientID := .Values.blueprint.provider.oidc.clientID }} -{{- $clientSecret := .Values.blueprint.provider.oidc.clientSecret }} -{{- $bindPolicyID := .Values.blueprint.application.bindPolicyID }} -{{- if or (and .Values.blueprint.provider.enabled (eq .Values.blueprint.provider.type "oidc") (not $clientID) (not $clientSecret)) (and (not $bindPolicyID) (eq (len .Values.blueprint.groups) 0)) }} +{{- $clientID := include "authentik-application.staticValue" (dict "root" $ "name" "clientID" "default" (randAlphaNum 32) "overwrite" .Values.blueprint.provider.oidc.clientID) }} +{{- $clientSecret := include "authentik-application.staticValue" (dict "root" $ "name" "clientSecret" "default" (randAlphaNum 32) "overwrite" .Values.blueprint.provider.oidc.clientSecret) }} +{{- $bindPolicyID := include "authentik-application.staticValue" (dict "root" $ "name" "bindPolicyID" "default" (uuidv4) "overwrite" .Values.blueprint.application.bindPolicyID) }} --- -{{- $secretName := .Values.secret.name | default (include "authentik-application.fullname" .) }} apiVersion: v1 kind: Secret metadata: - name: {{ $secretName }} + name: {{ include "authentik-application.fullname" . }} labels: {{- include "authentik-application.labels" . | nindent 4 }} {{- with .Values.secret.labels }} {{- toYaml . | nindent 4 }} {{- end }} stringData: - {{- $secretObj := (lookup "v1" "Secret" .Release.Namespace $secretName) | default dict }} - {{- $secretData := (get $secretObj "data") | default dict }} - - {{- $bindPolicyIDCoded := (get $secretData "bindPolicyID") | default (uuidv4 | b64enc) }} - {{- $bindPolicyID = $bindPolicyID | default ($bindPolicyIDCoded | b64dec) }} bindPolicyID: {{ $bindPolicyID | quote }} {{- if .Values.blueprint.provider.enabled }} issuerURL: {{ print .Values.blueprint.authentik.domain "/application/o/" .Values.blueprint.application.slug "/" }} {{- with .Values.blueprint.provider.oidc }} - {{- $clientIDCoded := (get $secretData "clientID") | default (randAlphaNum 32 | b64enc) }} - {{- $clientID = $clientID | default ($clientIDCoded | b64dec) }} clientID: {{ $clientID | quote }} - - {{- $clientSecretCoded := (get $secretData "clientSecret") | default (randAlphaNum 32 | b64enc) }} - {{- $clientSecret = $clientSecret | default ($clientSecretCoded | b64dec) }} clientSecret: {{ $clientSecret | quote }} redirectURL: {{ .redirectURL }} @@ -50,9 +38,8 @@ stringData: {{- with .claimGroups }} claimGroups: {{ . | quote }} {{- end }} - {{- end }} - {{- end }}{{/* end when-oidc */}} -{{- end }} + {{- end }}{{/* end with oidc */}} + {{- end }}{{/* end if provider */}} --- apiVersion: v1 kind: Secret @@ -69,124 +56,10 @@ stringData: metadata: name: {{ include "authentik-application.fullname" . }} entries: - + {{- $tplValues := (dict "root" $ "Template" .Template "bindPolicyID" $bindPolicyID "clientID" $clientID "clientSecret" $clientSecret) }} {{- if .Values.blueprint.provider.enabled }} - {{- if (eq .Values.blueprint.provider.type "oidc") }} - - model: authentik_providers_oauth2.OAuth2Provider - id: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} - identifiers: - name: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} - state: present - attrs: - authorization_flow: !Find [authentik_flows.flow, [slug, {{ .Values.blueprint.provider.authorizationFlow }}]] - {{- with .Values.blueprint.provider.oidc }} - client_type: {{ .clientType | quote }} - client_id: {{ $clientID | quote }} - client_secret: {{ $clientSecret | quote }} - redirect_uris: {{ .redirectURL }} - {{- with .tokenDuration }} - access_token_validity: {{ . | quote }} - {{- end }} - {{- with .signingKey }} - signing_key: !Find [authentik_crypto.CertificateKeyPair, [name, {{ . }}]] - {{- end }} - {{- with .scopes }} - property_mappings: - {{- range . }} - - !Find [authentik_providers_oauth2.ScopeMapping, [scope_name, {{ . }}]] - {{- end }} - {{- end }} - {{- end }}{{/* with-oidc */}} - {{- end }}{{/* if-oidc */}} - - {{- if (eq .Values.blueprint.provider.type "proxy") }} - - model: authentik_providers_proxy.ProxyProvider - id: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} - identifiers: - name: {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} - state: present - attrs: - authorization_flow: !Find [authentik_flows.flow, [slug, {{ .Values.blueprint.provider.authorizationFlow }}]] - mode: "forward_single" - {{- with .Values.blueprint.provider.proxy }} - external_host: {{ .externalHost | quote }} - skip_path_regex: {{ .skipPathRegex | quote }} - cookie_domain: {{ .cookieDomain | quote }} - {{- end }}{{/* with-proxy */}} - {{- end }}{{/* if-proxy */}} + {{- tpl (.Files.Get (printf "files/provider/%s.yaml.gotmpl" .Values.blueprint.provider.type)) $tplValues | nindent 6 }} {{- end }} - - - model: authentik_core.Application - id: {{ .Values.blueprint.application.name | default (include "authentik-application.fullname" .) }} - identifiers: - slug: {{ .Values.blueprint.application.slug }} - state: present - attrs: - name: {{ .Values.blueprint.application.name | default (include "authentik-application.fullname" .) }} - slug: {{ .Values.blueprint.application.slug }} - {{- if .Values.blueprint.provider.enabled }} - provider: !KeyOf {{ .Values.blueprint.provider.name | default (include "authentik-application.fullname" .) }} - {{- end }} - policy_engine_mode: {{ .Values.blueprint.application.policyEngineMode }} - {{- with .Values.blueprint.application.group }} - group: {{ . | quote }} - {{- end }} - {{- with .Values.blueprint.application.launchURL }} - meta_launch_url: {{ . | quote }} - {{- end }} - open_in_new_tab: {{ toYaml .Values.blueprint.application.openInNewTab }} - {{- with .Values.blueprint.application.icon }} - icon: {{ . | quote }} - {{- end }} - {{- with .Values.blueprint.application.description }} - meta_description: {{ . | quote }} - {{- end }} - {{- with .Values.blueprint.application.publisher }} - meta_publisher: {{ . | quote }} - {{- end }} - - {{- if (not (kindIs "slice" .Values.blueprint.groups)) }} - - - model: authentik_core.group - id: "app: {{ .Values.blueprint.application.slug }}" - identifiers: - name: "app: {{ .Values.blueprint.application.slug }}" - state: "present" - attrs: - name: "app: {{ .Values.blueprint.application.slug }}" - - - model: authentik_policies.PolicyBinding - id: {{ printf "%s-app-%s" (include "authentik-application.fullname" .) .Values.blueprint.application.slug | quote }} - identifiers: - pk: {{ $bindPolicyID | quote }} - attrs: - group: !KeyOf "app: {{ .Values.blueprint.application.slug }}" - order: 10 - target: !Find [authentik_core.Application, [slug, {{ .Values.blueprint.application.slug }}]] - {{- end }} - - {{- range $group := .Values.blueprint.groups }} - - model: authentik_core.group - id: {{ $group.slug | quote }} - identifiers: - name: {{ $group.slug | quote }} - state: {{ $group.state | default "present" | quote }} - attrs: - name: {{ $group.slug | quote }} - {{- with $group.parent }} - parent: !Find [authentik_core.group, [name, {{ . | quote }}]] - {{- else}} - parent: null - {{- end }} - - - model: authentik_policies.PolicyBinding - id: {{ printf "%s-app-%s" (include "authentik-application.fullname" $) $group.slug | quote }} - identifiers: - pk: {{ $group.bindID | quote }} - attrs: - group: !KeyOf {{ $group.slug | quote}} - order: 10 - target: !Find [authentik_core.Application, [slug, {{ $.Values.blueprint.application.slug }}]] - {{- end }} - + {{- tpl (.Files.Get "files/application.yaml.gotmpl") $tplValues | nindent 6 }} + {{- tpl (.Files.Get "files/groups.yaml.gotmpl") $tplValues | nindent 6 }} diff --git a/authentik-application/values.yaml b/authentik-application/values.yaml index aaddb0d..b632d61 100644 --- a/authentik-application/values.yaml +++ b/authentik-application/values.yaml @@ -16,8 +16,8 @@ blueprint: enabled: true name: "" authorizationFlow: "default-provider-authorization-implicit-consent" - # -- type of application connection, current support: oidc and proxy - type: "oidc" # or proxy + # -- type of application connection, current support: oidc, saml and proxy + type: "oidc" oidc: clientType: "confidential" # -- client id - generated if secret enabled @@ -29,6 +29,7 @@ blueprint: signingKey: "" # -- Scope scopes: + saml: proxy: externalHost: skipPathRegex: ""