Add Ceph dashboard SAML provider
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline failed

Ceph dashboard SSO is SAML 2.0 (no native OIDC), so onboard it via an Authentik
SAML provider + application. Also resolve SAML authorization/invalidation flows
by slug and the signing keypair by name (mirrors the oauth2 handling), since the
SAML path had not been exercised before.

- config/providers_saml/ceph.yaml: SP entity id/ACS derived from the dashboard
  base URL (audience .../auth/saml2/metadata, acs .../auth/saml2, HTTP-POST),
  signed with the built-in self-signed keypair.

Ceph side (separate, Puppet): ceph dashboard sso setup saml2
  https://dashboard.ceph.unkin.net <authentik-idp-metadata-url>

Validated with `terragrunt plan`: 2 to add (provider + application).
This commit is contained in:
2026-07-19 02:22:23 +10:00
parent 14ad52b835
commit 9c5937776e
2 changed files with 35 additions and 3 deletions
+15
View File
@@ -0,0 +1,15 @@
# SAML provider + application for the Ceph dashboard (dashboard.ceph.unkin.net).
# Ceph dashboard SSO is SAML 2.0 (no native OIDC). The SP entity id and ACS URL
# are derived by Ceph from its base URL:
# entity id (audience): <base>/auth/saml2/metadata
# ACS url (HTTP-POST): <base>/auth/saml2
# Configure the Ceph side (Puppet/mgr) with:
# ceph dashboard sso setup saml2 https://dashboard.ceph.unkin.net <authentik-idp-metadata-url>
name: Ceph Dashboard
authorization_flow: default-provider-authorization-implicit-consent
invalidation_flow: default-provider-invalidation-flow
acs_url: https://dashboard.ceph.unkin.net/auth/saml2
audience: https://dashboard.ceph.unkin.net/auth/saml2/metadata
sp_binding: post
# Authentik's built-in self-signed keypair, resolved by name; signs assertions.
signing_kp: authentik Self-signed Certificate
+20 -3
View File
@@ -52,17 +52,34 @@ resource "authentik_property_mapping_provider_scope" "groups_hierarchical" {
EOT EOT
} }
# Resolve SAML flows by slug and the signing keypair by name, so configs use
# human-readable names instead of Authentik UUIDs (mirrors the oauth2 handling).
data "authentik_flow" "saml_authorization" {
for_each = var.providers_saml
slug = each.value.authorization_flow
}
data "authentik_flow" "saml_invalidation" {
for_each = var.providers_saml
slug = each.value.invalidation_flow
}
data "authentik_certificate_key_pair" "saml_signing" {
for_each = { for k, v in var.providers_saml : k => v if v.signing_kp != null }
name = each.value.signing_kp
}
resource "authentik_provider_saml" "this" { resource "authentik_provider_saml" "this" {
for_each = var.providers_saml for_each = var.providers_saml
name = each.value.name name = each.value.name
authorization_flow = each.value.authorization_flow authorization_flow = data.authentik_flow.saml_authorization[each.key].id
invalidation_flow = each.value.invalidation_flow invalidation_flow = data.authentik_flow.saml_invalidation[each.key].id
acs_url = each.value.acs_url acs_url = each.value.acs_url
sp_binding = each.value.sp_binding sp_binding = each.value.sp_binding
audience = each.value.audience audience = each.value.audience
name_id_mapping = each.value.name_id_mapping name_id_mapping = each.value.name_id_mapping
signing_kp = each.value.signing_kp signing_kp = each.value.signing_kp != null ? data.authentik_certificate_key_pair.saml_signing[each.key].id : null
} }
# Resolve oauth2 flows by slug and scope mappings by managed identifier, and # Resolve oauth2 flows by slug and scope mappings by managed identifier, and