From d7f660362021af78e54b1f45152adab7911da181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torjus=20H=C3=A5kestad?= Date: Mon, 9 Feb 2026 19:20:13 +0100 Subject: [PATCH] vault: add OpenBao OIDC integration with Kanidm --- services/kanidm/default.nix | 24 ++++++++++++++++++ terraform/vault/approle.tf | 1 + terraform/vault/oidc.tf | 49 +++++++++++++++++++++++++++++++++++++ terraform/vault/policies.tf | 47 +++++++++++++++++++++++++++++++++++ terraform/vault/secrets.tf | 6 +++++ 5 files changed, 127 insertions(+) create mode 100644 terraform/vault/oidc.tf diff --git a/services/kanidm/default.nix b/services/kanidm/default.nix index cd10c99..e99b93f 100644 --- a/services/kanidm/default.nix +++ b/services/kanidm/default.nix @@ -40,6 +40,21 @@ preferShortUsername = true; scopeMaps.users = [ "openid" "profile" "email" "groups" ]; }; + + systems.oauth2.openbao = { + displayName = "OpenBao Secrets"; + # Both CLI (localhost) and Web UI callback URLs + originUrl = [ + "http://localhost:8250/oidc/callback" + "https://vault.home.2rjus.net:8200/ui/vault/auth/oidc/oidc/callback" + ]; + originLanding = "https://vault.home.2rjus.net:8200/"; + basicSecretFile = config.vault.secrets.openbao-oauth2.outputDir; + preferShortUsername = true; + # Allow groups scope for role binding + scopeMaps.admins = [ "openid" "profile" "email" "groups" ]; + scopeMaps.users = [ "openid" "profile" "email" "groups" ]; + }; }; }; @@ -72,6 +87,15 @@ group = "kanidm"; }; + # Vault secret for OpenBao OAuth2 client secret + vault.secrets.openbao-oauth2 = { + secretPath = "services/openbao/oauth2-client-secret"; + extractKey = "password"; + services = [ "kanidm" ]; + owner = "kanidm"; + group = "kanidm"; + }; + # Note: Kanidm does not expose Prometheus metrics # If metrics support is added in the future, uncomment: # homelab.monitoring.scrapeTargets = [ diff --git a/terraform/vault/approle.tf b/terraform/vault/approle.tf index 15ce4db..a88dfef 100644 --- a/terraform/vault/approle.tf +++ b/terraform/vault/approle.tf @@ -106,6 +106,7 @@ locals { "secret/data/hosts/kanidm01/*", "secret/data/kanidm/*", "secret/data/services/grafana/*", + "secret/data/services/openbao/*", ] } diff --git a/terraform/vault/oidc.tf b/terraform/vault/oidc.tf new file mode 100644 index 0000000..9191227 --- /dev/null +++ b/terraform/vault/oidc.tf @@ -0,0 +1,49 @@ +# OIDC authentication backend for Kanidm integration +resource "vault_jwt_auth_backend" "oidc" { + path = "oidc" + type = "oidc" + oidc_discovery_url = "https://auth.home.2rjus.net/oauth2/openid/openbao" + oidc_client_id = "openbao" + oidc_client_secret = random_password.auto_secrets["services/openbao/oauth2-client-secret"].result + default_role = "default" + + tune { + listing_visibility = "unauth" + default_lease_ttl = "1h" + max_lease_ttl = "24h" + token_type = "default-service" + } +} + +# Admin role - maps Kanidm admins group to admin policy +resource "vault_jwt_auth_backend_role" "admin" { + backend = vault_jwt_auth_backend.oidc.path + role_name = "admin" + token_policies = ["oidc-admin"] + + user_claim = "preferred_username" + groups_claim = "groups" + bound_claims = { groups = "admins" } + role_type = "oidc" + + allowed_redirect_uris = [ + "http://localhost:8250/oidc/callback", + "https://vault.home.2rjus.net:8200/ui/vault/auth/oidc/oidc/callback", + ] +} + +# Default role - any authenticated user (limited access) +resource "vault_jwt_auth_backend_role" "default" { + backend = vault_jwt_auth_backend.oidc.path + role_name = "default" + token_policies = ["oidc-default"] + + user_claim = "preferred_username" + groups_claim = "groups" + role_type = "oidc" + + allowed_redirect_uris = [ + "http://localhost:8250/oidc/callback", + "https://vault.home.2rjus.net:8200/ui/vault/auth/oidc/oidc/callback", + ] +} diff --git a/terraform/vault/policies.tf b/terraform/vault/policies.tf index 35c5657..05dd3b7 100644 --- a/terraform/vault/policies.tf +++ b/terraform/vault/policies.tf @@ -8,3 +8,50 @@ path "sys/metrics" { } EOT } + +# OIDC admin policy - full read/write to all secrets +resource "vault_policy" "oidc_admin" { + name = "oidc-admin" + + policy = <