diff --git a/services/kanidm/default.nix b/services/kanidm/default.nix index cd10c99..e34b153 100644 --- a/services/kanidm/default.nix +++ b/services/kanidm/default.nix @@ -24,9 +24,10 @@ idmAdminPasswordFile = config.vault.secrets.kanidm-idm-admin.outputDir; groups = { - admins = { }; - users = { }; - ssh-users = { }; + # overwriteMembers = false allows imperative member management via CLI + admins = { overwriteMembers = false; }; + users = { overwriteMembers = false; }; + ssh-users = { overwriteMembers = false; }; }; # Regular users (persons) are managed imperatively via kanidm CLI @@ -40,6 +41,20 @@ preferShortUsername = true; scopeMaps.users = [ "openid" "profile" "email" "groups" ]; }; + + systems.oauth2.openbao = { + displayName = "OpenBao Secrets"; + # Web UI callback only (CLI localhost not supported with confidential clients) + originUrl = "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; + # Enable RS256 signing algorithm (required by OpenBao) + enableLegacyCrypto = 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..b3efc71 --- /dev/null +++ b/terraform/vault/oidc.tf @@ -0,0 +1,50 @@ +# OIDC authentication backend for Kanidm integration +# Web UI only - CLI localhost redirects not supported with confidential clients +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@home.2rjus.net" } + role_type = "oidc" + oidc_scopes = ["openid", "profile", "email", "groups"] + + allowed_redirect_uris = [ + "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" + oidc_scopes = ["openid", "profile", "email", "groups"] + + allowed_redirect_uris = [ + "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 = <