Add Authentik OIDC SSO as the default human login for OpenBao (#147)
ci/woodpecker/push/apply Pipeline failed
ci/woodpecker/push/apply Pipeline failed
## Why
Human login to OpenBao is LDAP-only, so operators keep a second credential set outside Authentik and group membership is maintained twice.
## How
- Add `auth_oidc_backend` module: `oidc`-type JWT auth mount, Authentik discovery URL, `listing_visibility: unauth`, credentials from `kv/service/authentik/oidc-vault`.
- Add `auth_oidc_role` module: oidc role with `user_claim` email, `groups_claim` `ak_groups`, scopes `openid profile email ak_groups`, the registered redirect URIs, `bound_audiences` `[vault]`.
- Add `auth_oidc_group` module: external identity group plus group alias on the OIDC mount accessor, policies from `policy_auth_map`.
- Add config under `config/auth_oidc_{backend,role,group}/`, discovery locals in `config/config.hcl`, `vault_cluster` variables and wiring, and terragrunt inputs.
- Bind `akP-vault-admin` on the `oidc` mount to `global-root`, alongside the existing LDAP `vault_admin` binding.
- Pin the mount path to the literal `oidc`: the registered redirect URIs embed `/ui/vault/auth/oidc/oidc/callback`.
Requires #146, terraform-authentik #33 and #148 applied first.
---------
Co-authored-by: BenVincent <benvin@main.unkin.net>
Reviewed-on: #147
Co-authored-by: unkin-agent <unkin-agent@unkin.net>
Co-committed-by: unkin-agent <unkin-agent@unkin.net>
This commit was merged in pull request #147.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# Authentik (OIDC) human SSO. The mount path is the filename and MUST stay
|
||||
# "oidc": the Authentik provider registers strict redirect URIs containing
|
||||
# /ui/vault/auth/oidc/oidc/callback, which encode the mount path.
|
||||
#
|
||||
# identity.unkin.net serves the public LetsEncrypt wildcard, so the OpenBao VMs
|
||||
# validate discovery against the system roots with no CA bundle work. Do not
|
||||
# swap it for identity.k8s.syd1.au.unkin.net (internal CA).
|
||||
#
|
||||
# listing_visibility unauth makes OIDC the offered default on the UI login page.
|
||||
# client_id/client_secret are read from kv/service/authentik/oidc-vault.
|
||||
---
|
||||
oidc_discovery_url: "https://identity.unkin.net/application/o/vault/"
|
||||
default_role: "default"
|
||||
description: "Authentik SSO - default human login"
|
||||
listing_visibility: "unauth"
|
||||
default_lease_ttl: 24h
|
||||
max_lease_ttl: 168h
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
# this file doesnt need anything in it, so this data is just to make sure yamlencode reads some yaml data
|
||||
# The filename is the Authentik group name asserted in the ak_groups claim.
|
||||
# Only akP-* permission groups may appear here; akR-* roles are grouping-only.
|
||||
description: foo
|
||||
@@ -0,0 +1,25 @@
|
||||
# Default OIDC login role (the mount's default_role), used by both the web UI
|
||||
# and `bao login -method=oidc`.
|
||||
#
|
||||
# The role grants no policies of its own: authorization comes from the external
|
||||
# identity groups under config/auth_oidc_group, matched on the ak_groups claim.
|
||||
# ak_groups is Authentik's hierarchy-expanding claim (plain `groups` only carries
|
||||
# direct memberships), so nested akP-* permission groups resolve.
|
||||
#
|
||||
# allowed_redirect_uris must match the provider's strict URIs exactly.
|
||||
---
|
||||
user_claim: "email"
|
||||
groups_claim: "ak_groups"
|
||||
oidc_scopes:
|
||||
- openid
|
||||
- profile
|
||||
- email
|
||||
- ak_groups
|
||||
bound_audiences:
|
||||
- vault
|
||||
allowed_redirect_uris:
|
||||
- "http://localhost:8250/oidc/callback"
|
||||
- "https://vault.k8s.syd1.au.unkin.net/ui/vault/auth/oidc/oidc/callback"
|
||||
- "https://vault.service.consul:8200/ui/vault/auth/oidc/oidc/callback"
|
||||
token_ttl: 3600
|
||||
token_max_ttl: 28800
|
||||
@@ -97,6 +97,27 @@ locals {
|
||||
})
|
||||
if startswith(file_path, "auth_ldap_group/")
|
||||
}
|
||||
auth_oidc_backend = {
|
||||
for file_path, content in local.all_configs :
|
||||
trimsuffix(basename(file_path), ".yaml") => content
|
||||
if startswith(file_path, "auth_oidc_backend/")
|
||||
}
|
||||
auth_oidc_role = {
|
||||
for file_path, content in local.all_configs :
|
||||
trimsuffix(replace(file_path, "auth_oidc_role/", ""), ".yaml") => merge(content, {
|
||||
role_name = trimsuffix(basename(file_path), ".yaml")
|
||||
backend = dirname(replace(file_path, "auth_oidc_role/", ""))
|
||||
})
|
||||
if startswith(file_path, "auth_oidc_role/")
|
||||
}
|
||||
auth_oidc_group = {
|
||||
for file_path, content in local.all_configs :
|
||||
trimsuffix(replace(file_path, "auth_oidc_group/", ""), ".yaml") => merge(content, {
|
||||
groupname = trimsuffix(basename(file_path), ".yaml")
|
||||
backend = split("/", replace(file_path, "auth_oidc_group/", ""))[0]
|
||||
})
|
||||
if startswith(file_path, "auth_oidc_group/")
|
||||
}
|
||||
auth_kubernetes_backend = {
|
||||
for file_path, content in local.all_configs :
|
||||
trimsuffix(replace(file_path, "auth_kubernetes_backend/", ""), ".yaml") => content
|
||||
|
||||
Reference in New Issue
Block a user