# FILE: blueprints/ai-tax-agent-bootstrap.yaml # Authentik Bootstrap (v2025.x): users, groups, scope mappings, OIDC providers, applications version: 1 metadata: name: AI Tax Agent — Bootstrap + OIDC Providers entries: # --- Groups first (so the admin user can reference them) ------------------- - model: authentik_core.group state: present identifiers: name: "Administrators" attrs: is_superuser: true - model: authentik_core.group state: present identifiers: name: "Tax Reviewers" attrs: is_superuser: false - model: authentik_core.group state: present identifiers: name: "Accountants" attrs: is_superuser: false - model: authentik_core.group state: present identifiers: name: "Clients" attrs: is_superuser: false # --- Admin user ------------------------------------------------------------ - model: authentik_core.user state: present identifiers: username: admin attrs: name: "System Administrator" email: admin@local.lan is_active: true is_staff: true is_superuser: true groups: - !Find [authentik_core.group, [name, "Administrators"]] # --- Scope mappings (find existing ones and get stable IDs) ----------------- - id: scope_openid model: authentik_providers_oauth2.scopemapping identifiers: scope_name: openid - id: scope_profile model: authentik_providers_oauth2.scopemapping identifiers: scope_name: profile - id: scope_email model: authentik_providers_oauth2.scopemapping identifiers: scope_name: email - id: scope_groups model: authentik_providers_oauth2.scopemapping identifiers: scope_name: groups - id: scope_offline model: authentik_providers_oauth2.scopemapping identifiers: scope_name: offline_access # Helper finders - id: default_signing_key model: authentik_crypto.certificatekeypair state: present identifiers: name: "authentik Self-signed Certificate" - id: default_authz_flow model: authentik_flows.flow state: present identifiers: slug: "default-authentication-flow" - id: default_inval_flow model: authentik_flows.flow state: present identifiers: slug: "default-invalidation-flow" # ========= OIDC Providers + Applications ================================== # --- AI Tax Agent API ------------------------------------------------------ - model: authentik_providers_oauth2.oauth2provider state: present identifiers: name: "AI Tax Agent API" attrs: client_id: "ai-tax-agent-api" client_secret: !Env [AUTHENTIK_API_CLIENT_SECRET, "changeme-api-secret"] authorization_grant_type: "authorization-code" client_type: "confidential" issuer_mode: "per_provider" sub_mode: "hashed_user_id" include_claims_in_id_token: true signing_key: !KeyOf default_signing_key redirect_uris: - matching_mode: strict url: "https://api.local.lan/auth/callback" - matching_mode: strict url: "https://review.local.lan/auth/callback" scope_mappings: - !KeyOf scope_openid - !KeyOf scope_profile - !KeyOf scope_email - !KeyOf scope_groups - !KeyOf scope_offline authorization_flow: !KeyOf default_authz_flow invalidation_flow: !KeyOf default_inval_flow - model: authentik_core.application state: present identifiers: slug: "ai-tax-agent-api" attrs: name: "AI Tax Agent API" provider: !Find [ authentik_providers_oauth2.oauth2provider, [name, "AI Tax Agent API"], ] meta_launch_url: "https://api.local.lan" meta_description: "AI Tax Agent API Services" meta_publisher: "AI Tax Agent" policy_engine_mode: "any" # --- MinIO ----------------------------------------------------------------- - model: authentik_providers_oauth2.oauth2provider state: present identifiers: name: "MinIO" attrs: client_id: "minio" client_secret: !Env [AUTHENTIK_MINIO_CLIENT_SECRET, "changeme-minio-secret"] authorization_grant_type: "authorization-code" client_type: "confidential" issuer_mode: "per_provider" sub_mode: "hashed_user_id" include_claims_in_id_token: true signing_key: !KeyOf default_signing_key redirect_uris: - matching_mode: strict url: "https://minio.local.lan/oauth_callback" scope_mappings: - !KeyOf scope_openid - !KeyOf scope_profile - !KeyOf scope_email - !KeyOf scope_groups - !KeyOf scope_offline authorization_flow: !KeyOf default_authz_flow invalidation_flow: !KeyOf default_inval_flow - model: authentik_core.application state: present identifiers: slug: "minio" attrs: name: "MinIO" provider: !Find [authentik_providers_oauth2.oauth2provider, [name, "MinIO"]] meta_launch_url: "https://minio.local.lan" meta_description: "Object storage console" meta_publisher: "AI Tax Agent" policy_engine_mode: "any" # --- UI Review (Proxy Provider for ForwardAuth) --------------------------- - model: authentik_providers_proxy.proxyprovider state: present identifiers: name: "UI Review Proxy" attrs: external_host: "https://review.${DOMAIN:-local}" internal_host: "http://ui-review:3030" authorization_flow: !KeyOf default_authz_flow invalidation_flow: !KeyOf default_inval_flow mode: "forward_single" cookie_domain: "${DOMAIN:-local}" - model: authentik_core.application state: present identifiers: slug: "ui-review" attrs: name: "UI Review" provider: !Find [ authentik_providers_proxy.proxyprovider, [name, "UI Review Proxy"], ] meta_launch_url: "https://review.${DOMAIN:-local}" meta_description: "Tax Agent Platform - Review UI" meta_publisher: "AI Tax Agent" policy_engine_mode: "any" # --- Vault ----------------------------------------------------------------- - model: authentik_providers_oauth2.oauth2provider state: present identifiers: name: "Vault" attrs: client_id: "vault" client_secret: !Env [AUTHENTIK_VAULT_CLIENT_SECRET, "changeme-vault-secret"] authorization_grant_type: "authorization-code" client_type: "confidential" issuer_mode: "per_provider" sub_mode: "hashed_user_id" include_claims_in_id_token: true signing_key: !KeyOf default_signing_key redirect_uris: - matching_mode: strict url: "https://vault.local.lan/ui/vault/auth/oidc/oidc/callback" - matching_mode: strict url: "https://vault.local.lan/oidc/callback" - matching_mode: strict url: "http://localhost:8250/oidc/callback" scope_mappings: - !KeyOf scope_openid - !KeyOf scope_profile - !KeyOf scope_email - !KeyOf scope_groups - !KeyOf scope_offline authorization_flow: !KeyOf default_authz_flow invalidation_flow: !KeyOf default_inval_flow - model: authentik_core.application state: present identifiers: slug: "vault" attrs: name: "Vault" provider: !Find [authentik_providers_oauth2.oauth2provider, [name, "Vault"]] meta_launch_url: "https://vault.local.lan" meta_description: "Secrets management (Vault)" meta_publisher: "AI Tax Agent" policy_engine_mode: "any" # --- Grafana SSO Configuration ------------------------------------------- # Custom Role Mapping for Grafana - model: authentik_providers_oauth2.scopemapping state: present identifiers: name: "Grafana Role Mapping" attrs: name: "Grafana Role Mapping" description: "Maps Authentik groups to Grafana roles" scope_name: "role" expression: | # Map Authentik groups to Grafana roles user_groups = [group.name for group in request.user.ak_groups.all()] # Admin role mapping if "authentik Admins" in user_groups or "Administrators" in user_groups: return "Admin" # Editor role mapping if "Tax Reviewers" in user_groups or "Accountants" in user_groups: return "Editor" # Default to Viewer role return "Viewer" # Grafana OAuth2 Provider - model: authentik_providers_oauth2.oauth2provider state: present identifiers: name: "Grafana" attrs: client_id: "grafana" client_secret: "${AUTHENTIK_GRAFANA_CLIENT_SECRET:-changeme-grafana-secret}" client_type: "confidential" redirect_uris: "https://grafana.${DOMAIN:-local.lan}/login/generic_oauth" sub_mode: "hashed_user_id" include_claims_in_id_token: true issuer_mode: "per_provider" signing_key: !Find [ authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"], ] property_mappings: - !Find [ authentik_providers_oauth2.scopemapping, [scope_name, "openid"], ] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, "email"]] - !Find [ authentik_providers_oauth2.scopemapping, [scope_name, "profile"], ] - !Find [ authentik_providers_oauth2.scopemapping, [scope_name, "groups"], ] - !Find [ authentik_providers_oauth2.scopemapping, [name, "Grafana Role Mapping"], ] authorization_flow: !KeyOf default_authz_flow invalidation_flow: !KeyOf default_inval_flow # Grafana Application - model: authentik_core.application state: present identifiers: slug: "grafana" attrs: name: "Grafana" provider: !Find [authentik_providers_oauth2.oauth2provider, [name, "Grafana"]] meta_launch_url: "https://grafana.${DOMAIN:-local.lan}" meta_description: "Grafana monitoring and observability platform" meta_publisher: "Grafana Labs" policy_engine_mode: "any"