Configuration
AuthProxy uses a hierarchical configuration system based on JSON files and environment variables. This guide covers all configuration options and best practices.
Configuration Sources
Configuration is loaded in the following order (later sources override earlier ones):
appsettings.json(base configuration)appsettings.{Environment}.json(environment-specific)- Environment variables
- Command line arguments
Frontend Runtime Configuration
The authentication PWA reads deployment-specific settings from authproxy-settings.js. These
settings are separate from backend appsettings.json and can be changed when composing the
deployed PWA assets.
Local PIN vault
The optional PIN shortcut is disabled by default:
window.Config = {
AuthProxy: {
PIN_VAULT_ENABLED: "false",
},
};
Set PIN_VAULT_ENABLED to "true" to let users save their PassKey sign-in seed under a
four-digit PIN after a successful phone-and-password login.
The option is shown only when all of the following are true:
- the deployment flag is
"true" - PassKey is enabled for the project
- the browser supports the Web Crypto API
- the browser does not already contain a PIN vault for this origin
The vault is browser-local and stored under the application's origin. It contains an AES-GCM encrypted PassKey seed, random salt and IV, a masked phone display value, and local lockout metadata. It does not store the password or PIN. Signing out keeps the vault; users can remove it from the PIN screen with Forget this device.
A four-digit PIN has only 10,000 combinations. The local delay and eight-attempt wipe apply to the normal UI only; anyone who can copy or modify the browser's site data can bypass that metadata and test the encrypted blob offline. Enable this feature only where treating access to the device and origin storage as equivalent to possession of the PassKey is acceptable. Prefer FIDO2/WebAuthn when phishing resistance or hardware-backed key protection is required.
Core Configuration
Database Connection
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=authproxy_db;User Id=authproxy_user;Password=secure_password;TrustServerCertificate=true;Encrypt=true;"
}
}
Connection String Parameters:
| Parameter | Description | Example |
|---|---|---|
Server | SQL Server hostname | localhost or sql-server |
Database | Database name | authproxy_db or project123_authproxy |
User Id | SQL authentication user | authproxy_user |
Password | SQL authentication password | Use secrets management! |
TrustServerCertificate | Skip certificate validation (dev only) | true for dev, false for prod |
Encrypt | Enable TLS encryption | true (recommended) |
Service Configuration
{
"Config": {
"ServiceId": 10,
"Project": "CustomerProject",
"Domain": "app.customer.com",
"CoreApiKey": "generated_secure_key_for_internal_communication",
"Modules": {
"Wallet": "http://wallet-service:80",
"Chat": "http://chat-service:80",
"CRM": "http://crm-service:80",
"Core": "http://core-service:80"
}
}
}
Critical Parameters:
| Parameter | Purpose | Example | Required |
|---|---|---|---|
ServiceId | Service instance id for TimeTick ID generation (AuthProxy: 10-19, node p1 = 10) | 10 | ✅ Yes |
Project | Project name | "CustomerProject" | ✅ Yes |
Domain | Your verified project domain | "app.customer.com" | ✅ Yes |
CoreApiKey | Secret key for internal API authentication | Generated securely | ✅ Yes |
Modules.* | URLs of other ItBuild modules | "http://service:80" | ☐ Optional |
ServiceId Assignment:
- Single node:
10(nodep1, default) - Distributed deployment:
11-19for the remaining nodes (p2-p10) - Each instance must have a unique ServiceId for TimeTick uniqueness
FIDO2 Configuration
WebAuthn/FIDO2 hardware key authentication:
{
"FIDO2": {
"serverDomain": "customer.com",
"serverName": "app.customer.com",
"timestampDriftTolerance": 300000,
"origins": [
"https://app.customer.com",
"https://dev.itbuild.app:8001",
"https://dev.itbuild.app:8081"
]
}
}
Parameters:
| Parameter | Description | Example |
|---|---|---|
serverDomain | RP ID (Relying Party) - root domain | "customer.com" |
serverName | Display name shown in authenticator | "app.customer.com" |
timestampDriftTolerance | Clock drift tolerance (ms) | 300000 (5 minutes) |
origins | Allowed origins for WebAuthn | ["https://app.customer.com"] |
Important: origins must match exactly where users access your app (including port for dev).
OAuth Configuration
Google OAuth integration:
{
"GoogleOAuth": {
"ClientId": "your-google-client-id.apps.googleusercontent.com",
"ClientSecret": "your-google-client-secret"
}
}
Setup:
- Create OAuth 2.0 credentials in Google Cloud Console
- Add authorized redirect URI:
https://app.customer.com/auth/v1/google/callback - Copy Client ID and Client Secret to config
Telegram Bot Configuration
Telegram authentication:
{
"TelegramBot": {
"Token": "bot_token_from_botfather"
}
}
Setup:
- Create bot via @BotFather
- Copy bot token to config
- Configure bot commands and description
Monitoring (Uptrace)
OpenTelemetry integration with Uptrace:
{
"Uptrace": {
"Dsn": "http://uptrace-server:14318",
"ServiceName": "authproxy",
"ServiceVersion": "1.0.0"
}
}
Parameters:
| Parameter | Description | Example |
|---|---|---|
Dsn | Uptrace collector endpoint | "http://uptrace:14318" |
ServiceName | Service identifier for traces | "authproxy" |
ServiceVersion | Version for trace filtering | "1.0.0" |
Logging Configuration
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore": "Warning",
"System.Net.Http.HttpClient": "Warning"
}
}
}
Log Levels:
Trace- Very detailed, for debugging onlyDebug- Detailed information for developmentInformation- General flow informationWarning- Unexpected but recoverable eventsError- Errors and exceptionsCritical- Critical failures
Production Recommendation:
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.AspNetCore": "Error"
}
}
}
CORS Configuration
{
"Cors": {
"AllowedOrigins": [
"https://app.customer.com",
"https://admin.customer.com"
],
"AllowCredentials": true
}
}
Important: CORS for cross-app routes is enforced through the dual-flag pair introduced in 2026-04 — both AppFlag.AppAuthAndCORS on the calling user_app and RouteFlags.AppAuthAndCORS on the matching route_map row must be set. There is no separate cors_policy table; the calling origin is verified against the user_app's registered domain list. See Reverse Proxy → CORS gating.
FIDO2.origins is an independent allowlist used only by the WebAuthn ceremony (browser-side credential registration / assertion). Do not assume that adding an origin to FIDO2.origins opens it for CORS — the two lists are separate by design.
Session Configuration
{
"Session": {
"Cookie": {
"Name": "sessionid",
"HttpOnly": true,
"Secure": true,
"SameSite": "Lax",
"MaxAge": 86400
}
}
}
Parameters:
| Parameter | Description | Recommended Value |
|---|---|---|
HttpOnly | Prevent JavaScript access | true (security) |
Secure | HTTPS only | true in production |
SameSite | CSRF protection | Lax or Strict |
MaxAge | Session duration (seconds) | 86400 (24 hours) |
Complete Example
appsettings.json (Development)
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=authproxy_dev;User Id=sa;Password=DevPassword123;TrustServerCertificate=true;"
},
"Config": {
"ServiceId": 10,
"Project": "MyProject",
"Domain": "localhost:5000",
"CoreApiKey": "dev_api_key_insecure",
"Modules": {
"Wallet": "http://localhost:5001",
"Core": "http://localhost:5002"
}
},
"FIDO2": {
"serverDomain": "localhost",
"serverName": "localhost:5000",
"timestampDriftTolerance": 300000,
"origins": [
"http://localhost:5000",
"https://localhost:5001"
]
},
"GoogleOAuth": {
"ClientId": "your-dev-client-id.apps.googleusercontent.com",
"ClientSecret": "your-dev-client-secret"
},
"Uptrace": {
"Dsn": "http://localhost:14318",
"ServiceName": "authproxy-dev"
},
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft.AspNetCore": "Information"
}
}
}
appsettings.Production.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=prod-sql-server;Database=project123_authproxy;User Id=authproxy_prod;Password=${SQL_PASSWORD};Encrypt=true;TrustServerCertificate=false;"
},
"Config": {
"ServiceId": 10,
"Domain": "app.customer.com",
"Modules": {
"Wallet": "http://project123-wallet:80",
"Chat": "http://project123-chat:80",
"CRM": "http://project123-crm:80",
"Core": "http://project123-core:80"
}
},
"FIDO2": {
"serverDomain": "customer.com",
"serverName": "app.customer.com",
"origins": [
"https://app.customer.com"
]
},
"Session": {
"Cookie": {
"Secure": true,
"SameSite": "Strict"
}
},
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.AspNetCore": "Error"
}
}
}
Environment Variables
Override configuration using environment variables (useful for Docker):
Syntax
Use double underscore __ for nested properties:
# ConnectionStrings:DefaultConnection
export ConnectionStrings__DefaultConnection="Server=sql;Database=db;..."
# ServiceId
export ServiceId="11"
# Config:Modules:Wallet
export Config__Modules__Wallet="http://wallet:80"
Docker Example
docker run -d \
-e ConnectionStrings__DefaultConnection="Server=sql-server;Database=project123_authproxy;User Id=authproxy;Password=SecurePass123;Encrypt=true;" \
-e ServiceId="10" \
-e Config__Domain="app.customer.com" \
-e Config__CoreApiKey="secure_api_key" \
-e ASPNETCORE_ENVIRONMENT="Production" \
authproxy:latest
Docker Compose Example
version: '3.8'
services:
authproxy:
image: authproxy:latest
ports:
- "8001:80"
environment:
- ConnectionStrings__DefaultConnection=Server=sql-server;Database=project123_authproxy;User Id=authproxy;Password=SecurePass123;
- ServiceId=10
- Config__Project=MyProject
- Config__Domain=app.customer.com
- Config__CoreApiKey=${CORE_API_KEY}
- Config__Modules__Wallet=http://wallet:80
- Config__Modules__Core=http://core:80
- FIDO2__serverDomain=customer.com
- FIDO2__serverName=app.customer.com
- GoogleOAuth__ClientId=${GOOGLE_CLIENT_ID}
- GoogleOAuth__ClientSecret=${GOOGLE_CLIENT_SECRET}
- Uptrace__Dsn=http://uptrace:14318
- ASPNETCORE_ENVIRONMENT=Production
networks:
- project_network
sql-server:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=SqlServerPass123!
volumes:
- sql_data:/var/opt/mssql
networks:
- project_network
networks:
project_network:
volumes:
sql_data:
Secrets Management
NEVER commit secrets to Git!
Option 1: .env File (Development)
Create .env file (add to .gitignore):
SQL_PASSWORD=DevPassword123
GOOGLE_CLIENT_SECRET=your-secret
CORE_API_KEY=dev_api_key
Load in code:
Source-level examples and database statements are maintained in the module repositories. This public page describes the operational contract and configuration intent.
Option 2: User Secrets (Development)
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=localhost;..."
dotnet user-secrets set "GoogleOAuth:ClientSecret" "your-secret"
Option 3: Docker Secrets (Production)
services:
authproxy:
secrets:
- db_password
- google_secret
secrets:
db_password:
external: true
google_secret:
external: true
Option 4: Azure Key Vault / AWS Secrets Manager
Use cloud provider secrets management for production.
Validation
Check Configuration on Startup
AuthProxy validates critical configuration at startup:
Source-level examples and database statements are maintained in the module repositories. This public page describes the operational contract and configuration intent.
Test Configuration
# Development
dotnet run --environment Development
# Check logs for:
[Information] Configuration loaded successfully
[Information] Database connection: OK
[Information] ServiceId: 10
[Information] Domain: localhost:5000
Troubleshooting
"Database connection failed"
Check:
- SQL Server is running
- Connection string is correct
- Database exists
- User has permissions
- Firewall allows connection
Test:
# From container
docker exec -it authproxy sh
/opt/mssql-tools/bin/sqlcmd -S sql-server -U sa -P 'Password123'
"FIDO2 origin mismatch"
Error: DOMException: The operation either timed out or was not allowed
Fix: Add your URL to FIDO2.origins:
{
"FIDO2": {
"origins": [
"https://app.customer.com",
"http://localhost:5000" // Add for dev
]
}
}
"Module communication failed"
Check:
- Module URL in
Config.Modules.*is correct - Module is running
- Docker network allows communication
Test:
docker exec -it authproxy wget http://wallet-service:80/health
"Configuration override not working"
Check load order:
- Base config loads first
- Environment-specific overrides base
- Environment variables override files
Debug:
# Check environment
docker exec -it authproxy printenv | grep Config__