deployment, linting and infra configuration
Some checks failed
CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
CI/CD Pipeline / Policy Validation (push) Has been cancelled
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-firm-connectors) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-forms) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-hmrc) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ingestion) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-normalize-map) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ocr) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-indexer) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-reason) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rpa) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (ui-review) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (ui-review) (push) Has been cancelled
CI/CD Pipeline / Generate SBOM (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Notifications (push) Has been cancelled

This commit is contained in:
harkon
2025-10-14 07:42:31 +01:00
parent f0f7674b8d
commit eea46ac89c
41 changed files with 1017 additions and 1448 deletions

View File

@@ -0,0 +1,334 @@
# 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"

View File

@@ -0,0 +1,61 @@
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
query_range:
results_cache:
cache:
embedded_cache:
enabled: true
max_size_mb: 100
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
ruler:
alertmanager_url: http://localhost:9093
# Retention configuration
limits_config:
retention_period: 744h # 31 days
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
ingestion_rate_mb: 10
ingestion_burst_size_mb: 20
# Compactor for retention
compactor:
working_directory: /loki/compactor
shared_store: filesystem
compaction_interval: 10m
retention_enabled: true
retention_delete_delay: 2h
retention_delete_worker_count: 150
# Table manager for retention
table_manager:
retention_deletes_enabled: true
retention_period: 744h

View File

@@ -0,0 +1,49 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
# Docker container logs
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
filters:
- name: label
values: ["logging=promtail"]
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'logstream'
- source_labels: ['__meta_docker_container_label_com_docker_compose_project']
target_label: 'project'
- source_labels: ['__meta_docker_container_label_com_docker_compose_service']
target_label: 'service'
# System logs (optional)
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
# Application-specific logs
- job_name: ai-tax-agent
static_configs:
- targets:
- localhost
labels:
job: ai-tax-agent
environment: production
__path__: /var/log/ai-tax-agent/*.log

View File

@@ -16,3 +16,49 @@ http:
- X-authentik-meta-provider
- X-authentik-meta-app
- X-authentik-meta-version
# Large upload middleware for Gitea registry
gitea-large-upload:
buffering:
maxRequestBodyBytes: 5368709120 # 5GB
memRequestBodyBytes: 104857600 # 100MB
maxResponseBodyBytes: 5368709120 # 5GB
memResponseBodyBytes: 104857600 # 100MB
retryExpression: "IsNetworkError() && Attempts() < 3"
# Rate limiting for public APIs
api-ratelimit:
rateLimit:
average: 100
burst: 50
period: 1s
# Security headers
security-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
# CORS headers
api-cors:
headers:
accessControlAllowMethods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
accessControlAllowOriginList:
- "https://app.harkon.co.uk"
accessControlAllowHeaders:
- "Content-Type"
- "Authorization"
accessControlMaxAge: 100
addVaryHeader: true
# Security headers

View File

@@ -4,7 +4,9 @@ entryPoints:
address: ":80"
websecure:
address: ":443"
transport:
respondingTimeouts:
readTimeout: 30m
api:
dashboard: true