515 lines
21 KiB
YAML
515 lines
21 KiB
YAML
# Kaboot Authentik Blueprint
|
|
# This blueprint automatically configures all Authentik resources needed for Kaboot.
|
|
# Place in authentik/blueprints/ and it will be auto-imported on container startup.
|
|
#
|
|
# Prerequisites:
|
|
# - Set AUTHENTIK_BOOTSTRAP_PASSWORD and AUTHENTIK_BOOTSTRAP_TOKEN in .env
|
|
# - Mount this directory to /blueprints/custom in docker-compose.yml
|
|
#
|
|
#
|
|
# What this creates:
|
|
# - Kaboot OAuth2/OIDC Provider (public client)
|
|
# - Kaboot Application
|
|
# - kaboot-users Group
|
|
# - kaboot-ai-access Group
|
|
# - kaboot-admin Group
|
|
# - kaboot-early-access Group
|
|
# - Enrollment flow with prompt, user write, and login stages
|
|
# - Password complexity policy
|
|
# - Test user (kaboottest) - for manual browser testing
|
|
# - Service account (kaboot-test-service) - for API testing
|
|
#
|
|
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
|
---
|
|
version: 1
|
|
metadata:
|
|
name: Kaboot Application Setup
|
|
labels:
|
|
blueprints.goauthentik.io/description: "Complete Kaboot OAuth2/OIDC setup with enrollment flow"
|
|
blueprints.goauthentik.io/instantiate: "true"
|
|
|
|
# This blueprint depends on default authentik resources being created first.
|
|
# The depends_on ensures proper ordering during initial bootstrap.
|
|
depends_on:
|
|
- default/flow-default-authentication-flow.yaml
|
|
- default/flow-default-invalidation-flow.yaml
|
|
- default/flow-default-provider-authorization-implicit-consent.yaml
|
|
- default/flow-default-provider-invalidation.yaml
|
|
- default/flow-default-user-settings-flow.yaml
|
|
- system/providers-oauth2.yaml
|
|
|
|
entries:
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# CUSTOM INVALIDATION FLOW (must be defined before brand that references it)
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-logout-stage
|
|
model: authentik_stages_user_logout.userlogoutstage
|
|
identifiers:
|
|
name: kaboot-logout
|
|
attrs:
|
|
name: kaboot-logout
|
|
|
|
- id: kaboot-redirect-stage
|
|
model: authentik_stages_redirect.redirectstage
|
|
identifiers:
|
|
name: kaboot-redirect-to-app
|
|
attrs:
|
|
name: kaboot-redirect-to-app
|
|
mode: static
|
|
target_static: http://localhost:5173
|
|
|
|
- id: kaboot-invalidation-flow
|
|
model: authentik_flows.flow
|
|
identifiers:
|
|
slug: kaboot-invalidation-flow
|
|
attrs:
|
|
name: Kaboot Logout Flow
|
|
title: Logging out...
|
|
slug: kaboot-invalidation-flow
|
|
designation: invalidation
|
|
authentication: none
|
|
background: /media/branding/background.svg
|
|
|
|
- id: kaboot-invalidation-logout-binding
|
|
model: authentik_flows.flowstagebinding
|
|
identifiers:
|
|
target: !KeyOf kaboot-invalidation-flow
|
|
stage: !KeyOf kaboot-logout-stage
|
|
attrs:
|
|
order: 0
|
|
evaluate_on_plan: true
|
|
re_evaluate_policies: false
|
|
|
|
- id: kaboot-invalidation-redirect-binding
|
|
model: authentik_flows.flowstagebinding
|
|
identifiers:
|
|
target: !KeyOf kaboot-invalidation-flow
|
|
stage: !KeyOf kaboot-redirect-stage
|
|
attrs:
|
|
order: 10
|
|
evaluate_on_plan: true
|
|
re_evaluate_policies: false
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# GROUPS
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-users-group
|
|
model: authentik_core.group
|
|
identifiers:
|
|
name: kaboot-users
|
|
attrs:
|
|
name: kaboot-users
|
|
|
|
- id: kaboot-ai-access-group
|
|
model: authentik_core.group
|
|
identifiers:
|
|
name: kaboot-ai-access
|
|
attrs:
|
|
name: kaboot-ai-access
|
|
|
|
- id: kaboot-admin-group
|
|
model: authentik_core.group
|
|
identifiers:
|
|
name: kaboot-admin
|
|
attrs:
|
|
name: kaboot-admin
|
|
|
|
- id: kaboot-early-access-group
|
|
model: authentik_core.group
|
|
identifiers:
|
|
name: kaboot-early-access
|
|
attrs:
|
|
name: kaboot-early-access
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# GROUPS SCOPE MAPPING
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: groups-scope-mapping
|
|
model: authentik_providers_oauth2.scopemapping
|
|
identifiers:
|
|
managed: goauthentik.io/providers/oauth2/scope-kaboot-groups
|
|
attrs:
|
|
name: "Kaboot Groups Scope"
|
|
scope_name: groups
|
|
description: "Include user groups in the token"
|
|
expression: |
|
|
return {"groups": [group.name for group in request.user.ak_groups.all()]}
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# OAUTH2/OIDC PROVIDER
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-oauth2-provider
|
|
model: authentik_providers_oauth2.oauth2provider
|
|
identifiers:
|
|
name: Kaboot OAuth2
|
|
attrs:
|
|
name: Kaboot OAuth2
|
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
|
invalidation_flow: !KeyOf kaboot-invalidation-flow
|
|
signing_key: !Find [authentik_crypto.certificatekeypair, [name, authentik Internal JWT Certificate]]
|
|
client_type: public
|
|
client_id: kaboot-spa
|
|
redirect_uris:
|
|
- url: http://localhost:5173/callback
|
|
matching_mode: strict
|
|
- url: http://localhost:5173/silent-renew.html
|
|
matching_mode: strict
|
|
- url: http://localhost:5173
|
|
matching_mode: strict
|
|
access_code_validity: minutes=1
|
|
access_token_validity: minutes=30
|
|
refresh_token_validity: days=30
|
|
sub_mode: hashed_user_id
|
|
include_claims_in_id_token: true
|
|
issuer_mode: per_provider
|
|
property_mappings:
|
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
|
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
|
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
|
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, offline_access]]
|
|
- !KeyOf groups-scope-mapping
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# APPLICATION
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-application
|
|
model: authentik_core.application
|
|
identifiers:
|
|
slug: kaboot
|
|
attrs:
|
|
name: Kaboot
|
|
slug: kaboot
|
|
provider: !KeyOf kaboot-oauth2-provider
|
|
policy_engine_mode: any
|
|
meta_launch_url: http://localhost:5173
|
|
|
|
- id: kaboot-group-policy-binding
|
|
model: authentik_policies.policybinding
|
|
identifiers:
|
|
target: !KeyOf kaboot-application
|
|
group: !KeyOf kaboot-users-group
|
|
attrs:
|
|
order: 0
|
|
enabled: true
|
|
negate: false
|
|
timeout: 30
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# BRANDING (must be after application is created)
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-brand
|
|
model: authentik_brands.brand
|
|
identifiers:
|
|
domain: authentik-default
|
|
attrs:
|
|
domain: authentik-default
|
|
default: true
|
|
branding_title: Kaboot
|
|
branding_logo: /media/branding/logo.svg
|
|
branding_favicon: /media/branding/logo.svg
|
|
flow_authentication: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
|
|
flow_invalidation: !KeyOf kaboot-invalidation-flow
|
|
flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]]
|
|
default_application: !KeyOf kaboot-application
|
|
attributes:
|
|
settings:
|
|
theme:
|
|
base: light
|
|
css: |
|
|
/* Kaboot Theme for Authentik */
|
|
|
|
:root {
|
|
--ak-accent: #2563eb;
|
|
--ak-primary: #2563eb;
|
|
--ak-primary-dark: #1e40af;
|
|
--ak-primary-light: #60a5fa;
|
|
--ak-error: #ef4444;
|
|
--ak-success: #22c55e;
|
|
--pf-global--FontFamily--sans-serif: "Inter", system-ui, -apple-system, sans-serif;
|
|
}
|
|
|
|
/* Background color fallback (image set via Flow settings) */
|
|
body {
|
|
background-color: #2563eb !important;
|
|
}
|
|
|
|
/* Login Card */
|
|
.pf-c-login__main {
|
|
background-color: #ffffff !important;
|
|
border-radius: 2rem !important;
|
|
box-shadow: 0 10px 0 rgba(0,0,0,0.1) !important;
|
|
padding: 3rem !important;
|
|
max-width: 500px !important;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* Inputs */
|
|
.pf-c-form-control {
|
|
border: 2px solid #e5e7eb !important;
|
|
border-radius: 1rem !important;
|
|
padding: 0.75rem 1rem !important;
|
|
font-weight: 600 !important;
|
|
color: #333 !important;
|
|
font-size: 1rem !important;
|
|
box-shadow: none !important;
|
|
transition: all 0.2s ease !important;
|
|
}
|
|
|
|
.pf-c-form-control:focus {
|
|
border-color: #2563eb !important;
|
|
outline: none !important;
|
|
}
|
|
|
|
/* Primary Button - Kaboot Signature 3D Style */
|
|
.pf-c-button.pf-m-primary {
|
|
background-color: #333333 !important;
|
|
color: #ffffff !important;
|
|
border: none !important;
|
|
border-radius: 1rem !important;
|
|
padding: 0.75rem 1.5rem !important;
|
|
font-weight: 800 !important;
|
|
font-size: 1.1rem !important;
|
|
box-shadow: 0 6px 0 #000000 !important;
|
|
transform: translateY(0) !important;
|
|
transition: all 0.1s ease !important;
|
|
text-transform: uppercase !important;
|
|
letter-spacing: 0.05em !important;
|
|
}
|
|
|
|
.pf-c-button.pf-m-primary:hover {
|
|
background-color: #1a1a1a !important;
|
|
}
|
|
|
|
.pf-c-button.pf-m-primary:active {
|
|
transform: translateY(6px) !important;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
/* Secondary/Link Buttons */
|
|
.pf-c-button.pf-m-secondary, .pf-c-button.pf-m-link {
|
|
color: #2563eb !important;
|
|
font-weight: 600 !important;
|
|
}
|
|
|
|
/* Titles */
|
|
.pf-c-title {
|
|
font-weight: 900 !important;
|
|
color: #111827 !important;
|
|
text-align: center !important;
|
|
margin-bottom: 1.5rem !important;
|
|
}
|
|
|
|
/* Logo styling if present in header */
|
|
.pf-c-brand {
|
|
filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1));
|
|
}
|
|
|
|
/* Alert/Notification boxes */
|
|
.pf-c-alert {
|
|
border-radius: 1rem !important;
|
|
border: 2px solid transparent !important;
|
|
box-shadow: 0 4px 0 rgba(0,0,0,0.05) !important;
|
|
}
|
|
|
|
.pf-c-alert.pf-m-danger {
|
|
background-color: #fef2f2 !important;
|
|
border-color: #fca5a5 !important;
|
|
color: #991b1b !important;
|
|
}
|
|
|
|
/* Footer links */
|
|
.pf-c-login__main-footer-links-item-link {
|
|
color: #6b7280 !important;
|
|
font-weight: 500 !important;
|
|
}
|
|
|
|
/* Hide the default background image if any */
|
|
.pf-c-background-image {
|
|
display: none !important;
|
|
}
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# FLOW BACKGROUNDS
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: update-authentication-flow-background
|
|
model: authentik_flows.flow
|
|
identifiers:
|
|
slug: default-authentication-flow
|
|
attrs:
|
|
title: Welcome to Kaboot!
|
|
background: /media/branding/background.svg
|
|
|
|
- id: update-authorization-flow-background
|
|
model: authentik_flows.flow
|
|
identifiers:
|
|
slug: default-provider-authorization-implicit-consent
|
|
attrs:
|
|
background: /media/branding/background.svg
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# PASSWORD POLICY
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: password-complexity-policy
|
|
model: authentik_policies_password.passwordpolicy
|
|
identifiers:
|
|
name: password-complexity
|
|
attrs:
|
|
name: password-complexity
|
|
password_field: password
|
|
length_min: 8
|
|
amount_uppercase: 1
|
|
amount_lowercase: 1
|
|
amount_digits: 1
|
|
error_message: "Password must be at least 8 characters with 1 uppercase, 1 lowercase, and 1 digit."
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# ENROLLMENT STAGES
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: enrollment-prompt-stage
|
|
model: authentik_stages_prompt.promptstage
|
|
identifiers:
|
|
name: enrollment-prompt
|
|
attrs:
|
|
name: enrollment-prompt
|
|
fields:
|
|
- !Find [authentik_stages_prompt.prompt, [name, default-source-enrollment-field-username]]
|
|
- !Find [authentik_stages_prompt.prompt, [name, default-user-settings-field-email]]
|
|
- !Find [authentik_stages_prompt.prompt, [name, default-password-change-field-password]]
|
|
- !Find [authentik_stages_prompt.prompt, [name, default-password-change-field-password-repeat]]
|
|
validation_policies:
|
|
- !KeyOf password-complexity-policy
|
|
|
|
- id: enrollment-user-write-stage
|
|
model: authentik_stages_user_write.userwritestage
|
|
identifiers:
|
|
name: enrollment-user-write
|
|
attrs:
|
|
name: enrollment-user-write
|
|
user_creation_mode: always_create
|
|
create_users_as_inactive: false
|
|
create_users_group: !KeyOf kaboot-users-group
|
|
user_type: internal
|
|
|
|
- id: enrollment-user-login-stage
|
|
model: authentik_stages_user_login.userloginstage
|
|
identifiers:
|
|
name: enrollment-user-login
|
|
attrs:
|
|
name: enrollment-user-login
|
|
session_duration: hours=24
|
|
remember_me_offset: days=30
|
|
network_binding: no_binding
|
|
geoip_binding: no_binding
|
|
terminate_other_sessions: false
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# ENROLLMENT FLOW
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: enrollment-flow
|
|
model: authentik_flows.flow
|
|
identifiers:
|
|
slug: enrollment-flow
|
|
attrs:
|
|
name: Enrollment Flow
|
|
title: Sign Up
|
|
slug: enrollment-flow
|
|
designation: enrollment
|
|
authentication: none
|
|
background: /media/branding/background.svg
|
|
|
|
- id: enrollment-flow-prompt-binding
|
|
model: authentik_flows.flowstagebinding
|
|
identifiers:
|
|
target: !KeyOf enrollment-flow
|
|
stage: !KeyOf enrollment-prompt-stage
|
|
attrs:
|
|
order: 10
|
|
evaluate_on_plan: true
|
|
re_evaluate_policies: false
|
|
invalid_response_action: retry
|
|
|
|
- id: enrollment-flow-user-write-binding
|
|
model: authentik_flows.flowstagebinding
|
|
identifiers:
|
|
target: !KeyOf enrollment-flow
|
|
stage: !KeyOf enrollment-user-write-stage
|
|
attrs:
|
|
order: 20
|
|
evaluate_on_plan: true
|
|
re_evaluate_policies: false
|
|
invalid_response_action: retry
|
|
|
|
- id: enrollment-flow-user-login-binding
|
|
model: authentik_flows.flowstagebinding
|
|
identifiers:
|
|
target: !KeyOf enrollment-flow
|
|
stage: !KeyOf enrollment-user-login-stage
|
|
attrs:
|
|
order: 30
|
|
evaluate_on_plan: true
|
|
re_evaluate_policies: false
|
|
invalid_response_action: retry
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# LINK ENROLLMENT FLOW TO DEFAULT LOGIN
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: update-identification-stage
|
|
model: authentik_stages_identification.identificationstage
|
|
identifiers:
|
|
name: default-authentication-identification
|
|
attrs:
|
|
enrollment_flow: !KeyOf enrollment-flow
|
|
user_fields:
|
|
- email
|
|
- username
|
|
case_insensitive_matching: true
|
|
show_matched_user: true
|
|
show_source_labels: false
|
|
pretend_user_exists: true
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# TEST USER (for manual browser testing)
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-test-user
|
|
model: authentik_core.user
|
|
identifiers:
|
|
username: kaboottest
|
|
attrs:
|
|
username: kaboottest
|
|
name: Kaboot Test
|
|
email: kaboottest@test.com
|
|
path: users
|
|
is_active: true
|
|
groups:
|
|
- !KeyOf kaboot-users-group
|
|
- !KeyOf kaboot-ai-access-group
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# SERVICE ACCOUNT (for API/automated testing)
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
- id: kaboot-test-service-account
|
|
model: authentik_core.user
|
|
identifiers:
|
|
username: kaboot-test-service
|
|
attrs:
|
|
username: kaboot-test-service
|
|
name: Kaboot Test Service
|
|
path: users
|
|
type: service_account
|
|
is_active: true
|
|
groups:
|
|
- !KeyOf kaboot-users-group
|
|
- !KeyOf kaboot-ai-access-group
|