Enterprise Best Practices
Production High Availability
# Kubernetes high availability deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: authentik-server
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: authentik-server
template:
metadata:
labels:
app: authentik-server
spec:
containers:
- name: authentik
image: ghcr.io/goauthentik/server:2024.2.2
command: ["ak"]
args: ["server"]
env:
- name: AUTHENTIK_SECRET_KEY
valueFrom:
secretKeyRef:
name: authentik-secret
key: secret-key
- name: AUTHENTIK_POSTGRESQL__HOST
value: "postgres-cluster"
- name: AUTHENTIK_REDIS__HOST
value: "redis-cluster"
ports:
- containerPort: 9000
- containerPort: 9443
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /-/health/live/
port: 9000
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /-/health/ready/
port: 9000
initialDelaySeconds: 10
periodSeconds: 10
function Optimize-AuthentikPerformance
{
param(
[int]$WebWorkers = 4,
[int]$BackgroundWorkers = 2,
[string]$RedisMaxMemory = "256mb",
[string]$PostgresSharedBuffers = "256MB"
)
$optimizations = @{
web_server = @{
workers = $WebWorkers
worker_connections = 1000
keepalive_timeout = 65
client_max_body_size = "25M"
}
background_workers = @{
count = $BackgroundWorkers
max_tasks_per_child = 1000
pool_pre_ping = $true
}
redis = @{
maxmemory = $RedisMaxMemory
maxmemory_policy = "allkeys-lru"
save_intervals = @("900 1", "300 10", "60 10000")
}
postgresql = @{
shared_buffers = $PostgresSharedBuffers
effective_cache_size = "1GB"
maintenance_work_mem = "64MB"
max_connections = 200
}
}
Write-Host "Performance optimization recommendations:" -ForegroundColor Cyan
$optimizations | ConvertTo-Json -Depth 3
return $optimizations
}
Automation and Scripting
PowerShell Module for Authentik Management
# AuthentikManagement.psm1
class AuthentikClient
{
[string]$BaseUrl
[string]$ApiToken
[hashtable]$Headers
AuthentikClient([string]$url, [string]$token)
{
$this.BaseUrl = $url.TrimEnd('/')
$this.ApiToken = $token
$this.Headers = @{
'Authorization' = "Bearer $token"
'Content-Type' = 'application/json'
}
}
[object] InvokeApi([string]$endpoint, [string]$method = 'GET', [object]$body = $null)
{
$uri = "$($this.BaseUrl)$endpoint"
$params = @{
Uri = $uri
Method = $method
Headers = $this.Headers
}
if ($body)
{
$params.Body = $body | ConvertTo-Json -Depth 10
}
try
{
return Invoke-RestMethod @params
}
catch
{
Write-Error "API call failed: $($_.Exception.Message)"
return $null
}
}
[array] GetUsers([string]$search = "")
{
$endpoint = "/api/v3/core/users/"
if ($search) { $endpoint += "?search=$search" }
$response = $this.InvokeApi($endpoint)
return $response.results
}
[object] CreateUser([hashtable]$userData)
{
return $this.InvokeApi("/api/v3/core/users/", "POST", $userData)
}
[array] GetApplications()
{
$response = $this.InvokeApi("/api/v3/core/applications/")
return $response.results
}
[object] CreateApplication([hashtable]$appData)
{
return $this.InvokeApi("/api/v3/core/applications/", "POST", $appData)
}
}
function Connect-Authentik
{
param(
[Parameter(Mandatory)]
[string]$Url,
[Parameter(Mandatory)]
[string]$ApiToken
)
return [AuthentikClient]::new($Url, $ApiToken)
}
function New-AuthentikApplication
{
param(
[Parameter(Mandatory)]
[AuthentikClient]$Client,
[Parameter(Mandatory)]
[string]$Name,
[Parameter(Mandatory)]
[string]$Slug,
[string]$Provider,
[string]$Group = "",
[hashtable]$PolicyBindings = @{}
)
$appData = @{
name = $Name
slug = $Slug
provider = $Provider
group = $Group
policy_engine_mode = "any"
meta_description = "Created via PowerShell automation"
}
if ($PolicyBindings.Count -gt 0)
{
$appData.policy_bindings = $PolicyBindings
}
return $Client.CreateApplication($appData)
}
Export-ModuleMember -Function Connect-Authentik, New-AuthentikApplication
Bulk Operations Script
function Import-UsersFromCsv
{
param(
[Parameter(Mandatory)]
[string]$CsvPath,
[Parameter(Mandatory)]
[AuthentikClient]$AuthentikClient,
[string[]]$DefaultGroups = @(),
[switch]$SendWelcomeEmail
)
if (-not (Test-Path $CsvPath))
{
throw "CSV file not found: $CsvPath"
}
$users = Import-Csv -Path $CsvPath
$results = @()
Write-Host "Importing $($users.Count) users from CSV..." -ForegroundColor Cyan
foreach ($user in $users)
{
try
{
$userData = @{
username = $user.Username
email = $user.Email
first_name = $user.FirstName
last_name = $user.LastName
is_active = $true
groups = $DefaultGroups + ($user.Groups -split ',')
}
$result = $AuthentikClient.CreateUser($userData)
if ($result)
{
Write-Host "✓ Created user: $($user.Username)" -ForegroundColor Green
$results += @{
Username = $user.Username
Status = "Success"
UserId = $result.pk
}
if ($SendWelcomeEmail)
{
# Send welcome email logic here
}
}
else
{
Write-Warning "Failed to create user: $($user.Username)"
$results += @{
Username = $user.Username
Status = "Failed"
Error = "API call failed"
}
}
}
catch
{
Write-Error "Error creating user $($user.Username): $($_.Exception.Message)"
$results += @{
Username = $user.Username
Status = "Error"
Error = $_.Exception.Message
}
}
}
# Summary
$successful = ($results | Where-Object { $_.Status -eq "Success" }).Count
$failed = $results.Count - $successful
Write-Host "`nImport Summary:" -ForegroundColor Cyan
Write-Host " Total users processed: $($results.Count)" -ForegroundColor White
Write-Host " Successful: $successful" -ForegroundColor Green
Write-Host " Failed: $failed" -ForegroundColor Red
return $results
}
Navigation
◄ Troubleshooting · Authentik Overview