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
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:
334
infra/base/authentik/bootstrap.yaml
Normal file
334
infra/base/authentik/bootstrap.yaml
Normal 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"
|
||||
61
infra/base/loki/loki-config.yml
Normal file
61
infra/base/loki/loki-config.yml
Normal 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
|
||||
|
||||
49
infra/base/promtail/promtail-config.yml
Normal file
49
infra/base/promtail/promtail-config.yml
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,9 @@ entryPoints:
|
||||
address: ":80"
|
||||
websecure:
|
||||
address: ":443"
|
||||
|
||||
transport:
|
||||
respondingTimeouts:
|
||||
readTimeout: 30m
|
||||
api:
|
||||
dashboard: true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user