Open DreamingRaven opened 1 year ago
an example for an LDAP Provider, app and outpost:
entries:
- model: authentik_blueprints.metaapplyblueprint
attrs:
identifiers:
name: Default - Authentication flow
required: true
- attrs:
authorization_flow: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
base_dn: DC=ldap,DC=goauthentik,DC=io
bind_mode: cached
gid_start_number: 4000
search_group: !Find [authentik_core.group, [name, "authentik Admins"]]
search_mode: cached
uid_start_number: 2000
id: provider
identifiers:
name: test
model: authentik_providers_ldap.ldapprovider
- attrs:
name: ldap
policy_engine_mode: any
provider: !KeyOf provider
id: app
identifiers:
slug: ldap
model: authentik_core.application
- attrs:
config:
authentik_host: http://localhost:9000/
providers:
- !KeyOf provider
type: ldap
id: outpost
identifiers:
name: ldap
model: authentik_outposts.outpost
metadata:
labels:
blueprints.goauthentik.io/generated: 'true'
name: authentik Export - 2022-08-31 21:14:20.484928+00:00
version: 1
There aren't examples for every object, but in general the JSON schema should help (https://goauthentik.io/blueprints/schema.json)
the fields under attrs
and identifiers
are all fields that are available via API, as that's what the blueprints use internally.
you can also use ak export_blueprint
in the server/worker container to export the current config to a blueprint
Actually that is quite helpful thanks for that. Also thanks for getting back to me so quickly.
It took me a second to break it down from the schema, but after I converted it into more comfortable (for me atleast) YAML, I could see a good number of the properties
that I had been looking for for a good number of maps.
One liner for anyone else who likes YAML:
curl https://goauthentik.io/blueprints/schema.json | yq --yaml-output
I also see what you mean by there are examples for every object. At first I thought you meant blueprint entry examples but you actually mean properties of the schema aren't fully populated in the schema.json (correct me if I am wrong). E.G shema.json does not list sub-properties of attrs
map, which you have used in the example LDAP app, provider, and outpost metaapplyblueprint blueprint.
Is there a way I can go any deeper and find even more of these properties somewhere? Maybe in the specific models? As I want to get a more complete picture so that I can generate these blueprints without the use of the GUI since really I want to generate this decoratively in helm / operator (I am building an authentik operator). I can always reverse engineer from clicked together bits and export_blueprint as you mentioned. Ideally it would be a lot more consistent to have an API I can gather extract this information from if there is such a thing atm, this would also help me in the long run maintain compatibility.
So like kubectl api-resources
, kubectl get crd
or kubectl explain
(or query the specific resources) but for authentik blueprint properties.
You can use these settings in vscode to load the schema for yaml files:
"yaml.schemas": {
"https://goauthentik.io/blueprints/schema.json": "blueprints/**/*.yaml"
},
Yes, the schema doesn't list all properties of all possible objects, as much as I want to do that it's not that easy. All the field names in attrs
and identifiers
are the same as for the API, you can use https://goauthentik.io/developer-docs/api/browser as a reference
I'm actually also thinking about building a (very simple) kubernetes operator into authentik, with a single Blueprint CRD that is automatically recreated/reconcilled in authentik
Yeah funnily enough that is exactly what I am doing among other CRDs.
I am currently making AkBlueprint, AkOutpost, AkProvider, and AkApplication CRDs and the managing operator. I feel it would be extremely convenient to be able to configure authentik in a kube native manner and have it dynamically load configuration in this way which is why I started adding it. In particular my end goal is that you can configure an application in a given namespace and have the controller automatically configure its ingress resource with forward auth and or any providers it needs for integration.
Thanks for the help, I appreciate it. I think I have most of what I need now anyway. If I have any specific issues with blueprints I may drop them in here if that is amiable.
@DreamingRaven thanks for your input on Gitops and Authentik CRDs, i am highly interested in a Authentik Operator. For blueprints i just tried a sidecar approach which collects configmaps (https://github.com/goauthentik/helm/pull/146) and supplies those as blueprints to authentik.
However your Operator looks more promising from a GitOps perspective, thank you for your work on this!
@benedikt-bartscher No problem, its nowhere near complete, but the basic infrastructure is there (SDK, basic controller, CICD builds, deployment etc), along with the basic authentik management (deploy, destroy, and apply some but not all CRDs). I would not recommend that you use it quite yet (even if a good chunk of the functionality is there) but I should be returning to the operator (https://gitlab.com/GeorgeRaven/authentik-manager) shortly once a few of my other deadlines are met as I have a very strong need for this myself for personal, commercial, and educational reasons. If you have anything you want in particular from the operator I would drop an issue there.
Here are a list of Operator that i find. https://github.com/goauthentik/authentik/issues/4558
But yes a official Operator with an stabil API whould be nice. But that need person to maintain, so even https://gitlab.com/GeorgeRaven/authentik-manager switch to blueprint.
so i believe as an first step https://github.com/goauthentik/helm/pull/146 with declararive blueprints (https://github.com/goauthentik/authentik/issues/5300) could be fast implemented and would solve the most problems
I have been working on this the last few days, the blueprint functionality should be in place very soon! I chose to go with internal storage, as it simplifies everything substantially since it wont fight against any gitops orchestration mechanism.
Currently:
authentik_blueprints_blueprintinstance
table to check if the blueprint is there alreadyI will drop a message here when its done. Once the last 3 tasks are complete it should be fully functional, after that it will be just keeping everything compatible in case the db structure changes / migrates, and adding new higher level CRDs to automate larger tasks. The ak CRD is already complete and manages the stack of authentik already although I want to add more automation to this going forward like rolling updates etc.
But yeah I get you, an official operator would have been nicer but its a lot to ask, they are such complex beasts and adds a lot more headaches for the authentik guys. The broad steps for mine will look like so, so hopefully that will be sufficient when it is ready:
archer@archbest ~/g/authentik-manager (staging)> kubectl get all -n auth
NAME READY STATUS RESTARTS AGE
pod/authentik-manager-68977fd74f-lltxj 1/1 Running 0 5s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/controller-manager-metrics-service ClusterIP 10.96.21.65 <none> 8443/TCP 6s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/authentik-manager 1/1 1 1 6s
NAME DESIRED CURRENT READY AGE
replicaset.apps/authentik-manager-68977fd74f 1 1 1 6s
archer@archbest ~/g/authentik-manager (staging)> kubectl apply -f operator/config/samples/akm_v1alpha1_ak.yaml
ak.akm.goauthentik.io/ak-sample created
archer@archbest ~/g/authentik-manager (staging)> kubectl apply -f operator/config/samples/akm_v1alpha1_secret.yaml
secret/auth created
archer@archbest ~/g/authentik-manager (staging)> kubectl get all -n auth
NAME READY STATUS RESTARTS AGE
pod/authentik-manager-68977fd74f-lltxj 1/1 Running 1 (30s ago) 61s
pod/authentik-server-96fff84ff-4mcwh 1/1 Running 0 29s
pod/authentik-server-96fff84ff-p7rqc 1/1 Running 0 29s
pod/authentik-server-96fff84ff-smlgs 1/1 Running 0 29s
pod/authentik-worker-5897cbfbf4-f8kb9 0/1 ContainerCreating 0 29s
pod/authentik-worker-5897cbfbf4-frgxk 1/1 Running 0 29s
pod/authentik-worker-5897cbfbf4-nl5r6 1/1 Running 0 29s
pod/pgadmin-6d8555b6b4-vzsmd 1/1 Running 0 29s
pod/postgres-0 1/1 Running 0 29s
pod/redis-master-0 0/1 Running 0 29s
pod/redis-replicas-0 0/1 Running 0 29s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/authentik-server ClusterIP 10.109.152.180 <none> 80/TCP,443/TCP,389/TCP,636/TCP,300/TCP,900/TCP 29s
service/authentik-worker ClusterIP 10.103.31.217 <none> 80/TCP,443/TCP,389/TCP,636/TCP,300/TCP,900/TCP 29s
service/controller-manager-metrics-service ClusterIP 10.96.21.65 <none> 8443/TCP 62s
service/pgadmin ClusterIP 10.103.81.150 <none> 80/TCP 29s
service/postgres ClusterIP 10.98.213.211 <none> 5432/TCP 29s
service/postgres-hl ClusterIP None <none> 5432/TCP 29s
service/redis-headless ClusterIP None <none> 6379/TCP 29s
service/redis-master ClusterIP 10.102.51.216 <none> 6379/TCP 29s
service/redis-replicas ClusterIP 10.100.43.181 <none> 6379/TCP 29s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/authentik-manager 1/1 1 1 62s
deployment.apps/authentik-server 3/3 3 3 29s
deployment.apps/authentik-worker 2/3 3 2 29s
deployment.apps/pgadmin 1/1 1 1 29s
NAME DESIRED CURRENT READY AGE
replicaset.apps/authentik-manager-68977fd74f 1 1 1 62s
replicaset.apps/authentik-server-96fff84ff 3 3 3 29s
replicaset.apps/authentik-worker-5897cbfbf4 3 3 2 29s
replicaset.apps/pgadmin-6d8555b6b4 1 1 1 29s
NAME READY AGE
statefulset.apps/postgres 1/1 29s
statefulset.apps/redis-master 0/1 29s
statefulset.apps/redis-replicas 0/3 29s
archer@archbest ~/g/authentik-manager (staging)> kubectl apply -f operator/config/samples/akm_v1alpha1_akblueprint.yaml
akblueprint.akm.goauthentik.io/akblueprint-sample created
archer@archbest ~/g/authentik-manager (staging)> kubectl get akblueprints.akm.goauthentik.io -n auth
NAME AGE
akblueprint-sample 81s
Having to play around a bit to reverse what exactly is expected in a few different fields though:
Ok I have the base blueprint handling just about sorted which I will release soon. This is a blueprint that was loaded from a cluster CRD using the operator: However one important case that I need to find a good solution for is default blueprint overrides. So say someone wanted to deploy a blueprint that overrides the default behavior for say the login page using:
apiVersion: akm.goauthentik.io/v1alpha1
kind: AkBlueprint
metadata:
labels:
app.kubernetes.io/name: akblueprint
app.kubernetes.io/instance: akblueprint-sample
app.kubernetes.io/part-of: operator
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: operator
name: akblueprint-sample
spec:
file: /blueprints/default/10-flow-default-authentication-flow.yaml
blueprint:
version: 1
metadata:
name: Default - Authentication flow
entries:
- model: authentik_blueprints.metaapplyblueprint
attrs:
identifiers:
name: Default - Password change flow
required: false
- attrs:
designation: authentication
# TODO: (USER) adjust the name, title to match your branding
name: login
title: Welcome to akm!
authentication: require_unauthenticated
identifiers:
slug: default-authentication-flow
model: authentik_flows.flow
id: flow
- 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: default-authentication-password
id: default-authentication-password
model: authentik_stages_password.passwordstage
- identifiers:
name: default-authentication-mfa-validation
id: default-authentication-mfa-validation
model: authentik_stages_authenticator_validate.authenticatorvalidatestage
- attrs:
user_fields:
- email
- username
identifiers:
name: default-authentication-identification
id: default-authentication-identification
model: authentik_stages_identification.identificationstage
- identifiers:
name: default-authentication-login
id: default-authentication-login
model: authentik_stages_user_login.userloginstage
- identifiers:
order: 10
stage: !KeyOf default-authentication-identification
target: !KeyOf flow
model: authentik_flows.flowstagebinding
- identifiers:
order: 20
stage: !KeyOf default-authentication-password
target: !KeyOf flow
model: authentik_flows.flowstagebinding
- identifiers:
order: 30
stage: !KeyOf default-authentication-mfa-validation
target: !KeyOf flow
model: authentik_flows.flowstagebinding
- identifiers:
order: 100
stage: !KeyOf default-authentication-login
target: !KeyOf flow
model: authentik_flows.flowstagebinding
So that it now says something different (in this case welcome to AKM). Usually you would overwrite the actual file itself with your new version but when you are interacting with the internal storage mechanism or just targeting the db directly I do not see a clear way to do so. If I were to overwrite the db entry that comes from a default file I expect that the file would then overwrite my table changes again whenever authentik re-scans the files and compares their contents. The clearest solution I can think of is to actually remove all the default blueprints and instead package them as default CRDs deployed with authentik. However I would like to avoid this as I am not certain what behavior authentik will have in the few moments it has no blueprints and I do not want to suffer any drift if the default blueprints get updated or changed over time compared to my CRDs.
TLDR: is there any way to tell authentik to ignore a default blueprint file without having to remove or overwrite it?
Hey Authentik team.
I just wanted to say thank you for all your hard work, I am loving Authentik, and I am keen to see it grow!
In my particular case I want to declaritively define an outpost, application, and provider. The former has a documented example for manual creation in kubernetes. However the latter two do not nor do they have any blueprint examples or breakdowns (if this is possible).
I believe blueprints are the key to this in Authentik and allowing for GitOps for persistent and consistent spin up and spin down of clusters in testing and production. If possible I would also like to create a GitOps documentation page for Kubernetes specifically as it is preferable in k8s (in my opinion) to spin up with all the desired flows configuration theming etc out of the gate without any clicks. Environment variables (they work well) and sealed-secrets (of my own addition) seem to cover half this GitOps use case and I believe blueprints is the final hurdle for me.