Skip to main content

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):

  1. appsettings.json (base configuration)
  2. appsettings.{Environment}.json (environment-specific)
  3. Environment variables
  4. 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.

Security boundary

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:

ParameterDescriptionExample
ServerSQL Server hostnamelocalhost or sql-server
DatabaseDatabase nameauthproxy_db or project123_authproxy
User IdSQL authentication userauthproxy_user
PasswordSQL authentication passwordUse secrets management!
TrustServerCertificateSkip certificate validation (dev only)true for dev, false for prod
EncryptEnable TLS encryptiontrue (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:

ParameterPurposeExampleRequired
ServiceIdService instance id for TimeTick ID generation (AuthProxy: 10-19, node p1 = 10)10✅ Yes
ProjectProject name"CustomerProject"✅ Yes
DomainYour verified project domain"app.customer.com"✅ Yes
CoreApiKeySecret key for internal API authenticationGenerated securely✅ Yes
Modules.*URLs of other ItBuild modules"http://service:80"☐ Optional

ServiceId Assignment:

  • Single node: 10 (node p1, default)
  • Distributed deployment: 11-19 for 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:

ParameterDescriptionExample
serverDomainRP ID (Relying Party) - root domain"customer.com"
serverNameDisplay name shown in authenticator"app.customer.com"
timestampDriftToleranceClock drift tolerance (ms)300000 (5 minutes)
originsAllowed 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:

  1. Create OAuth 2.0 credentials in Google Cloud Console
  2. Add authorized redirect URI: https://app.customer.com/auth/v1/google/callback
  3. Copy Client ID and Client Secret to config

Telegram Bot Configuration

Telegram authentication:

{
"TelegramBot": {
"Token": "bot_token_from_botfather"
}
}

Setup:

  1. Create bot via @BotFather
  2. Copy bot token to config
  3. Configure bot commands and description

Monitoring (Uptrace)

OpenTelemetry integration with Uptrace:

{
"Uptrace": {
"Dsn": "http://uptrace-server:14318",
"ServiceName": "authproxy",
"ServiceVersion": "1.0.0"
}
}

Parameters:

ParameterDescriptionExample
DsnUptrace collector endpoint"http://uptrace:14318"
ServiceNameService identifier for traces"authproxy"
ServiceVersionVersion 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 only
  • Debug - Detailed information for development
  • Information - General flow information
  • Warning - Unexpected but recoverable events
  • Error - Errors and exceptions
  • Critical - 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:

ParameterDescriptionRecommended Value
HttpOnlyPrevent JavaScript accesstrue (security)
SecureHTTPS onlytrue in production
SameSiteCSRF protectionLax or Strict
MaxAgeSession 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:

Implementation detail

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:

Implementation detail

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:

  1. SQL Server is running
  2. Connection string is correct
  3. Database exists
  4. User has permissions
  5. 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:

  1. Module URL in Config.Modules.* is correct
  2. Module is running
  3. Docker network allows communication

Test:

docker exec -it authproxy wget http://wallet-service:80/health

"Configuration override not working"

Check load order:

  1. Base config loads first
  2. Environment-specific overrides base
  3. Environment variables override files

Debug:

# Check environment
docker exec -it authproxy printenv | grep Config__