Compare commits

...

6 Commits

Author SHA1 Message Date
benvin 4dadd1f4ab Merge pull request 'Add ArgoCD OAuth2/OIDC provider' (#3) from benvin/argocd-oidc into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #3
2026-07-12 23:04:47 +10:00
benvin a6dca8eb96 Merge branch 'main' into benvin/argocd-oidc
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline was successful
2026-07-12 23:02:21 +10:00
benvin 3af322dff3 Merge pull request 'Fix perpetual redirect_uri drift on oauth2 providers' (#5) from benvin/fix-redirect-uri-type into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #5
2026-07-12 23:02:09 +10:00
unkinben c62fdb574a Add argocd-admins group
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline was successful
Declaratively manage the group that argocd-rbac-cm maps to role:admin, so
onboarding ArgoCD SSO does not require creating the group by hand in the UI.
2026-07-12 22:58:32 +10:00
unkinben 1fc0b70e1a Add ArgoCD OAuth2/OIDC provider
Extends Authentik SSO to ArgoCD so cluster operators log in with their
Authentik identity and group membership instead of the local admin account.

- Add config/providers_oauth2/argocd.yaml: confidential OAuth2 provider +
  application (slug argocd), client_id argocd, openid/email/profile scopes,
  web SSO and CLI (localhost:8085) redirect URIs. client_secret is read from
  Vault at kv/kubernetes/namespace/argocd/default/oauth-credentials, matching
  the existing Grafana pattern.
2026-07-12 22:58:32 +10:00
unkinben 5faa2f84f6 Fix perpetual redirect_uri drift on oauth2 providers
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline was successful
authentik_provider_oauth2.allowed_redirect_uris is list(map(string)) and the
API always stores a redirect_uri_type key on each entry. The module only set
matching_mode and url, so every plan showed the Grafana provider being updated
in-place (state map had 3 keys, config map had 2) and never converged.

Add redirect_uri_type to the redirect_uris object, defaulting to
"authorization". `terragrunt plan` now reports no changes.
2026-07-12 22:57:57 +10:00
3 changed files with 29 additions and 2 deletions
+3
View File
@@ -0,0 +1,3 @@
# Members of this group get ArgoCD role:admin (mapped in argocd-rbac-cm).
# Everyone else who logs in via Authentik gets role:readonly.
name: argocd-admins
+21
View File
@@ -0,0 +1,21 @@
# OAuth2/OIDC provider + application for the in-cluster ArgoCD
# (argocd.k8s.syd1.au.unkin.net). client_secret is read from Vault, not committed.
name: ArgoCD
authorization_flow: default-provider-authorization-implicit-consent
invalidation_flow: default-provider-invalidation-flow
client_type: confidential
client_id: argocd
client_secret_vault:
mount: kv
path: kubernetes/namespace/argocd/default/oauth-credentials
scope_mappings:
- goauthentik.io/providers/oauth2/scope-openid
- goauthentik.io/providers/oauth2/scope-email
- goauthentik.io/providers/oauth2/scope-profile
redirect_uris:
# Web UI SSO callback.
- matching_mode: strict
url: https://argocd.k8s.syd1.au.unkin.net/auth/callback
# `argocd login --sso` CLI callback (local listener).
- matching_mode: strict
url: http://localhost:8085/auth/callback
+3
View File
@@ -40,9 +40,12 @@ variable "providers_oauth2" {
# Managed identifiers of scope property mappings (e.g. # Managed identifiers of scope property mappings (e.g.
# goauthentik.io/providers/oauth2/scope-openid). Resolved to ids. # goauthentik.io/providers/oauth2/scope-openid). Resolved to ids.
scope_mappings = optional(list(string), []) scope_mappings = optional(list(string), [])
# allowed_redirect_uris is list(map(string)); the API always stores a
# redirect_uri_type key, so it must be set here or every plan drifts.
redirect_uris = optional(list(object({ redirect_uris = optional(list(object({
matching_mode = optional(string, "strict") matching_mode = optional(string, "strict")
url = string url = string
redirect_uri_type = optional(string, "authorization")
})), []) })), [])
signing_key = optional(string, null) signing_key = optional(string, null)
access_token_validity = optional(string, "minutes=10") access_token_validity = optional(string, "minutes=10")