diff --git a/argocd-apps/add-ons/authentik.yaml b/argocd-apps/add-ons/authentik.yaml new file mode 100644 index 0000000..2cf07e8 --- /dev/null +++ b/argocd-apps/add-ons/authentik.yaml @@ -0,0 +1,55 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/sync-wave: "2" + name: authentik + namespace: argocd +spec: + destination: + namespace: authentik + server: https://kubernetes.default.svc + project: default + sources: + - chart: authentik + helm: + values: | + authentik: + error_reporting: + enabled: false + postgresql: + host: postgres-rw.postgres.svc.cluster.local + name: authentik + user: authentik + global: + envFrom: + - secretRef: + name: authentik-secrets + blueprints: + configMaps: + - authentik-blueprints + server: + resources: + limits: + memory: 1Gi + requests: + cpu: 100m + memory: 512Mi + worker: + resources: + limits: + memory: 1Gi + requests: + cpu: 50m + memory: 384Mi + repoURL: https://charts.goauthentik.io + targetRevision: 2026.8.3 + - path: infra/authentik + repoURL: https://gitea.whyredfire.dev/whyredfire/gitops.git + targetRevision: main + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/argocd-apps/add-ons/kustomization.yaml b/argocd-apps/add-ons/kustomization.yaml index 7f2228b..a3add21 100644 --- a/argocd-apps/add-ons/kustomization.yaml +++ b/argocd-apps/add-ons/kustomization.yaml @@ -4,7 +4,9 @@ resources: - anubis-operator.yaml - argocd-dashboard.yaml - argocd-repos.yaml + - authentik.yaml - cert-manager.yaml - cnpg.yaml + - postgres.yaml - sealed-secrets.yaml - traefik.yaml diff --git a/argocd-apps/add-ons/postgres.yaml b/argocd-apps/add-ons/postgres.yaml new file mode 100644 index 0000000..e5176b6 --- /dev/null +++ b/argocd-apps/add-ons/postgres.yaml @@ -0,0 +1,22 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/sync-wave: "1" + name: postgres + namespace: argocd +spec: + destination: + namespace: postgres + server: https://kubernetes.default.svc + project: default + source: + path: infra/postgres + repoURL: https://gitea.whyredfire.dev/whyredfire/gitops.git + targetRevision: main + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/infra/authentik/blueprints.yaml b/infra/authentik/blueprints.yaml new file mode 100644 index 0000000..6922b48 --- /dev/null +++ b/infra/authentik/blueprints.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: authentik-blueprints + namespace: authentik +data: + # Google is the only way in: its source has no enrollment flow, so a Google + # account can only log in when a user with the same email already exists. + google-login.yaml: | + version: 1 + metadata: + name: Google login + entries: + - model: authentik_blueprints.metaapplyblueprint + attrs: + identifiers: + path: default/flow-default-authentication-flow.yaml + required: true + - model: authentik_blueprints.metaapplyblueprint + attrs: + identifiers: + path: default/flow-default-source-authentication.yaml + required: true + - model: authentik_core.group + id: admins + identifiers: + name: admins + attrs: + is_superuser: true + - model: authentik_core.user + identifiers: + username: whyredfire + attrs: + email: whyredfire@gmail.com + groups: + - !KeyOf admins + name: Karan Parashar + - model: authentik_sources_oauth.oauthsource + id: google + identifiers: + slug: google + attrs: + authentication_flow: !Find [authentik_flows.flow, [slug, default-source-authentication]] + consumer_key: !Env GOOGLE_CLIENT_ID + consumer_secret: !Env GOOGLE_CLIENT_SECRET + name: Google + promoted: true + provider_type: google + user_matching_mode: email_link + - model: authentik_stages_identification.identificationstage + identifiers: + name: default-authentication-identification + attrs: + sources: + - !KeyOf google diff --git a/infra/authentik/httproute.yaml b/infra/authentik/httproute.yaml new file mode 100644 index 0000000..1d07b6b --- /dev/null +++ b/infra/authentik/httproute.yaml @@ -0,0 +1,23 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + annotations: + argocd.argoproj.io/sync-wave: "2" + name: authentik + namespace: authentik +spec: + hostnames: + - auth.whyredfire.dev + parentRefs: + - kind: Gateway + name: traefik-gateway + namespace: traefik + sectionName: websecure + rules: + - backendRefs: + - name: authentik-server + port: 80 + matches: + - path: + type: PathPrefix + value: / diff --git a/infra/authentik/kustomization.yaml b/infra/authentik/kustomization.yaml new file mode 100644 index 0000000..750911f --- /dev/null +++ b/infra/authentik/kustomization.yaml @@ -0,0 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - sealed-secret.yaml + - blueprints.yaml + - httproute.yaml diff --git a/infra/authentik/sealed-secret.yaml b/infra/authentik/sealed-secret.yaml new file mode 100644 index 0000000..fb66992 --- /dev/null +++ b/infra/authentik/sealed-secret.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + name: authentik-secrets + namespace: authentik +spec: + encryptedData: + AUTHENTIK_BOOTSTRAP_PASSWORD: AgAPgYcs6IXUWk3VUgoPNQXwP43kEKP26OAJmu7dA4vTRhmWwmJXN8ybRhX7jS2YPwGWxAWflxiM3x7F3jUohOpqN37et4zFCoUq43mQ3blbTMV4zhsuyMx0JIqhsafzlVWiKqmqIykVq8yJQ6886FkIS0u14i//YTcs0QMS7gum6pDEhehAg+FhwiNgm92iVCyhoh+3rL549akXe53UJNKwVzuWavEHZFTKJNmFa2g9YzYcJgNf46f7maPbfSg09E27XC9L7KNxxiodU2h0D50La8LMEX+X0fAbLtrXPf9MsJjcfNvy0kXqy/AB+A5zL/Yh4uVztWikE27evDvfeoWc9svCTIbBzwx1EtR/nC71IvN61ADpFGbTXA44jSOtPg6nNtOAq8AEqIp0p3uNbQK17cEfbmDtq8husTYF1i6e+VFVGIltPiGdRSZb92xtLGkf63YfdYXSy+xaiIJ/8ki4vgw91KY0l5/9sS1BqWR312UUEAtOGt7M4cydVEWToc1AdYj3RDBgPjmqoddiR66EMzhCFz5sxlU/rji7j4DAOFA4gqAV5JAZO1HehNFp2GajTi36d0XLe06/Z+IbEmSeTlPTGZOvxTweYcWexplzp/ob/MwAaMouPRcmae4/VTlu9Lex1bMYugc6bD8B7V+gmM/MhY7heQl+mSyBV0CO6JsZwC1tipzcJfaiBzUF8sZ7Ast3v+7omsjFo/CXqxbPNZrolipiEjE9IT3n3r2m7gpIkv+A/ie77iJF8k6zFRM= + AUTHENTIK_POSTGRESQL__PASSWORD: AgAoQ04gX1QOUI5kfNMNy07pnaqDTp4X6LDlQBBwSs13SVGZCJAL61hQymOaL/U2cCyc0N5nr7FCswHcqBE8t1esKlK/NB+BL9aWfO7uPonhdzsc2iKBONZYickCyyD+8Hgu/McQDPVo6vMQ51/82WL2ZKfwJEfTKmo1OfJ/I2Tls2KmczzlkNrCC9M5moObXl+PJlKJuxAkeXJc61MSn/vvsvksG5O0AKtXHmTk8E1t7krAbOqKy9CbVwHJAwH/NIhiOgJr/KziceWhHHQiEwC631ZpM+fZWiUSKETwpnLWSl7s8SvsEUNA9s/W2w24tpqSKrHOZtS6J0sT84FsV9U9T5MaZtZT9NG3FmNehxQpIlet6BSyJh+JMq5LjzA8ANvVvlXs4jhJyTcotLf/m1ZJbetVjFGJjvxUbVuxObpMentVrAeLO8cZqk1iTzqPdkrEeV38DN2E9oJSyQeRP6sZTnDd9xweou8nwMZWidyIDorTKSwvggje2YDXefc8+aOVVCN7pBOwKisEuPH35Ov/A2RDzmE3mQRC3EDuHJ+3dZbVawIawV0ZUIL52X+ongbllOtHABUfODY7tTC/VQMk07d3/zG5q7bCE2D+R0XE4oQJy2h2wYHiYUoGYM5JKC2me4TIx6Y+haksl2mqfC/yal3FLWMBdK4eC9VyXugO25l4yLVOcKa/QMhImHB6lbyNLGDuafnIanMkraWo73EqqXpF3IIqfzfgkj4aOO3Cbuu6BeQ4bNmmam+cWLqq1QQ= + AUTHENTIK_SECRET_KEY: AgAHHDs8mbJRc45DFgap2VUZn/F+m59hm9u2lebuJv70HSBxLLsHEn8nXLGUO3b2ScyPt1Qi2wbmRDENTjOHOYHtAQAjwV25r6RUiZ5TosRH2KhGx5N6gceorYQyk18l2CkKv4ObXjeGLJA0EqMarmFWiT24SFZdtIrOvWygLxg4XGful2h1Fw5uXK9PiUHgptrp/G5M5Htv0bvtD6m/FrgOlK6C6tK1D4vLL3VLX3/SceqNWVDIJmJao5JKO4IZTQxN8TN5k9K2CGrtOUhjCn4vLbYQKTPhiiidoQaipQ9FR+4KJMO0y8FbIy+3q7C/UZPyOTOu/2zI4t5h4TJY1+477A80GTLpE0aCBDpmFwgZY728wbTW4NyfIm15u0Um7OXhnJkXC1EqDbvlK4HYHiSDUjGChvlfMEY+D1datDlF1fEuIaeXtTqowpz3uy9qIEa0f1emS2J8TjIrKH3oW3mfmrJKSiySnCX1704ZPlwOJfnF5Z2vM6Oqo/mWHa6PSwPPRxSxEKVtSqD4KynzrUmx3GkrUs+7tntepA3yQoiDjyUyE71FwhJXO4sE3XcRGDUf4rB8CFO4+NgTbBAqFzNKYG32GIDhGjbMxBAJQMNXZhVcKceiaXf7G8LuaOEw39BkdtiFCdK3uXl9xaQPuStRsOYYQR2Dt0vt3AvDGjAW+McauCbYUD3rcAtVMo+rxEbejrotojWnb1OpGX0JqD5gHC68qlqY6BYkDbWpYojoKWJHuHlYxHIm8k7ghSq6npw94R526bxripNtcNq4Lh1NeM55LKruOEGr7n0dFcyAmQ== + GOOGLE_CLIENT_ID: AgCV2Rwe/bHbkQ3nkkIs4EFTbsEqQWRaWlXa/fHzkDyNKpd0CTOgqVb6Rd2KYyvoT9iDR0xt/8reLPd9e7B3G3V1oVFV7G1XiErBmzvxr6591+tXzo8JLVpIy0363R87idi2xIKGVii+G5aJvxxhua8IRsNfi4SRtoqpDzjgNbFtm5UDhhlCzcRKkm0zHgLw83d4Uwszu9X9II2A4FuMPD6KvsTFrgHevR1v3OerKl5kvTlUx0O3XEg5mnNUVk46J+D9wfg58bIlgUhMV8NtfKa8I5zmRKhCJySks1zlCgIudCLX7wPYupFgt0nrZjJGx7a546ntPdMVE4IJ+VhlQ94gjdWsVFm07espaQLph9T4CZDKxb6TwyNswhfFxH1Z9auyFf3Cfk2wx5GChNOL0mZ8Zrzcw008c8IUShF8je8JZ60teBffbBNao7XN6JM6a4ac5aKnNwFch9IJUU1qkvcJaZk5hAkeGO9uHrICb6lkr5Rj7t4h9l4mvgfIKXP5YCCKZ+yqrSI8Jpkch/cB0Sphgp7m7QXgGwmWRgdKEk1rP7ioIfoF66mLsfgvOkc+1ySvPgW/rCLbHwzMqJn1Fkk/afbRoWp/guFj1cOY9MrEQIn8ftugeV/0xWiL+y5RyJm7QZc1z5fSj/NTrVCZV0LhBHttPZzoGGWEqjLYQnyJ8p38lK7EU6Pmk4WrEMj7mmdYHEijyPhab+b7guOc+ULbPT7k7sBHXbKrTTUJa09jIqSS4jl2PNrzPCPDIvRpG/cMgNklhNPfvpDQcLdVRA7bsf7navZvDsQ= + GOOGLE_CLIENT_SECRET: AgDNFpqV5LGekTMvOBtPE9c6ZVPtT6wN+nCFRhZnvBKIz4I7U9jzisEN7yhc4ud22XJXpS5oR8hN4H+V6Js/bCZMDJefYcdstmHku14kUvoLRUtwPV9tdjiihmb57VLTnT1s1OzbnOqZPwXoCAmGAPLDgZrghBi0id21GgjU41jCHDJCcH1j9RHhE20JwsVG2uz9Tcp6MVYh94aq53V4//bvFXz4xQgVlN8c1jJ/W4rrNM9vmYdMwKyB5509oVWJigowsRlji0FXurR8ovz1AXpMuGj6hUGxLp0uHsqz7FV/0lsd4B2BR9cVRChAR8zDCiiKb4TH2Kmn676/Z+gtJ8vcOQg/WDT1ENzOr6dyndCLVxJvJuvl1EqinzhSqJjUy11HxqULApKKbX1iRJIAIGb6dpeKVoHDKg5xtcWGwaD6epG/tz20agkWBMCFNq5aS80npz28W5GeOQ8aF4X/rpjuEHVLrN+n0pgyS4wjwniB6UJMYRIYk45r0ICUtqyFjOiNzpU70NsPmEjDyItW1EVo+6tb0lRmOI5apm/9yayZXjFISwTAFPdBMrQL+ij4AGw4HMWMmN0aqDO+Kd1c9Jg6wUKluN2Lb6CaxehWeSJiz2wTEhEz8KBkInfezgSekNkw4wjJiBEZ4/M3G6Y/C61ekuVFarRc87cY+S3SomVZDGQcPysfQlieMVpHlfXq/CSDgHhZV3Q+S/wqpy5ZcfsyaU+v4PmvyEc12MZxQ1RGngVJow== + template: + metadata: + name: authentik-secrets + namespace: authentik diff --git a/infra/postgres/authentik-database.yaml b/infra/postgres/authentik-database.yaml new file mode 100644 index 0000000..573b4c2 --- /dev/null +++ b/infra/postgres/authentik-database.yaml @@ -0,0 +1,11 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Database +metadata: + name: authentik + namespace: postgres +spec: + cluster: + name: postgres + databaseReclaimPolicy: retain + name: authentik + owner: authentik diff --git a/infra/postgres/authentik-db-sealedsecret.yaml b/infra/postgres/authentik-db-sealedsecret.yaml new file mode 100644 index 0000000..9f78c90 --- /dev/null +++ b/infra/postgres/authentik-db-sealedsecret.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + name: authentik-db + namespace: postgres +spec: + encryptedData: + password: AgALpscM7BiDoZuUSlAI39CZYz3DvSaHQwzOpZEKp4tqfEYQ1r2DALOAbi4l3+6LzsMo63RNv3SYlhxFcbjjrDMiiaaB47iKDEmbSW/LQTJibiaoy67rgTs8T3I4awQbHeylwJQr5nS0BN6MeYh87PCmqFc3Orc5kCokSL9j7gVwOqNkq27RMJkghulUxAEONQrixFOiCHTFWCD/IybR1olUUacz7nKxCTLmcqDfzimGlF92VBbFaUzZH5W+0yd59zNqjhnmslIRiqli/ZVB2Z5ECuqr4YmrSmaCQvR5mzRmNjpmAeqCF/byFjfanPM6ZZ4NM2x7flqu8sULzZfBdXWmhIy03jPFFDBIvznHHW6y0K2r8kqewkoUsKgJEgZcsEvwe/F/gode3ukI02LuD2dKMNjeDaf8A4xaRx6h9U9cDiggmpHPW2HjO3kLp6ViEGPlGm3JuisnqncsBgfIh1T8ZMpmuM0WgAe6E3hFHnR6vbWYfSIi6nrEcpfLL+F2bBGYdUFBfjflaxXzhPnGDJ29GEBuyJcHPVRTqBhybS9rl+77dhCbPEsC5GN9MdCdS3uVWyKN+xIV1f/cJNsUFhDyU2rbkbFAebJurjPbKi92HPDaEq6OK3kunN9nNEZ9rE7d6ouw/gQ5Uq3CmaNDiVDorFfaW5DHVbRnm3MLdbLoUuN1AlU96/cDuSqDZjfLB69iB/+nt8TQLHopwQxj9AajfMyF+y9c2XvYZWvZGaCE1fTEfpIJ2fV1McnwbFi0uHk= + username: AgA9pxBlPvKPAX/NaHHFSN1ypRxKmd8CNcs92+l3JpDar81IYWaQPG0p99wYxrBp0414GIhojpkWks7+lVDSgmVzw9T+JQzow54lRxe7dHFOzfAQx1oQyGp8AkiGtjAIdUx9kgYhM01xQUDYtFDe3XnhVUkvjQNARctWyX+o/vyYTnK5BMHZB6viQOWrifNUmPQQRFnB9oEPGVqysYlJ2+o1sMyJYXOiTEMVkuk0rFp8AE2WGeyfR0pFwhSyn2g7bbFvUoQbECiG4y83AKmpmX4p25bAlzsIxb1kgUpYlqZXGMqLuQaVBJsBs3u7sDUjQZFRfz3rH2OLfNGZcCGT3c9Ueg05eRpAyWHP1kHWmkK2Yl4kPcyx54bBk2yv2h4lW7DmlsG6jE6bzKPtMTJOiJdkqkNSkerd062ktWYrpAg6iuGWB1A7Et+J07JaWd6xfANRknvH/D+CEQHuRM5qEtM8HVLuTlKSxX464d0nNKUw0rrSokWJWT5olroc+VjaHyXdF6LEYmgNXxtUwa95q6k8J78ZLidx7SawbFC5d5ErFbkq+6xOPWeKzcDExtcMd9UF1Ti90Ybp5ncyxoQLXCWhSV9SxjeS+f6H8Cs7JM39kxeOfLvvxw9qz2rSW6qbimh5KaXmO8KK3BFtrui+k5tlnv6qJaRbtMUV+p7WyK36wBk1fUMR0lfK8FRuWfnUuslP2wk17vlkvto= + template: + metadata: + labels: + cnpg.io/reload: "true" + name: authentik-db + namespace: postgres + type: kubernetes.io/basic-auth diff --git a/infra/postgres/cluster.yaml b/infra/postgres/cluster.yaml new file mode 100644 index 0000000..9b916ea --- /dev/null +++ b/infra/postgres/cluster.yaml @@ -0,0 +1,29 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: postgres + namespace: postgres +spec: + enablePDB: false + imageName: ghcr.io/cloudnative-pg/postgresql:18 + instances: 1 + managed: + roles: + - ensure: present + login: true + name: authentik + passwordSecret: + name: authentik-db + postgresql: + # Each app role may only connect to the database of the same name. + pg_hba: + - host sameuser all all scram-sha-256 + - host all all all reject + resources: + limits: + memory: 1Gi + requests: + cpu: 100m + memory: 256Mi + storage: + size: 5Gi diff --git a/infra/postgres/kustomization.yaml b/infra/postgres/kustomization.yaml new file mode 100644 index 0000000..36da0c9 --- /dev/null +++ b/infra/postgres/kustomization.yaml @@ -0,0 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - cluster.yaml + - authentik-db-sealedsecret.yaml + - authentik-database.yaml