Skip to content

Configuration.md

Codewriter90x edited this page Jan 24, 2026 · 1 revision

Configuration

This document explains environment variables, application settings, and secrets management.

Configuration Sources

ASP.NET Core loads configuration from multiple sources in this order (later sources override earlier ones):

  1. appsettings.json (base configuration)
  2. appsettings.{Environment}.json (environment-specific)
  3. Environment variables
  4. Command-line arguments

Environment Variables

Database

Variable Required Description
DEFAULT_CONN_STRING Yes PostgreSQL connection string

Format:

Host=localhost;Database=opencashflow_db;Username=opencashflow;Password=your_password;Port=5432

Production considerations:

  • Use SSL: SSL Mode=Require;Trust Server Certificate=true
  • Connection pooling: Pooling=true;Minimum Pool Size=5;Maximum Pool Size=100

JWT Authentication

Variable Required Description
JWTSETTINGS__SECRETKEY Yes Signing key (min 64 characters)
JWTSETTINGS__ISSUER No Token issuer (default: https://api.opencashflow.local)
JWTSETTINGS__AUDIENCE No Token audience (default: https://app.opencashflow.local)

Generate a secure key:

openssl rand -base64 64

Stripe

Variable Required Description
STRIPE__SECRETKEY Yes* Stripe secret API key
STRIPE__PUBLISHABLEKEY Yes* Stripe publishable key
STRIPE__WEBHOOKSECRET Yes* Webhook signing secret

*Required only if Stripe integration is enabled.

Test mode keys:

  • Start with sk_test_ and pk_test_
  • Safe to use in development

Live mode keys:

  • Start with sk_live_ and pk_live_
  • Use only in production with proper security

CORS

Variable Required Description
CORS__ALLOWEDORIGINS__0 Yes First allowed origin
CORS__ALLOWEDORIGINS__1 No Second allowed origin
CORS__ALLOWEDORIGINS__N No Additional origins

Example:

CORS__ALLOWEDORIGINS__0=https://app.opencashflow.com
CORS__ALLOWEDORIGINS__1=https://admin.opencashflow.com

Application URLs

Variable Required Description
APPURL Yes Base URL of the web application
ASPNETCORE_ENVIRONMENT Yes Runtime environment

Valid environments:

  • Development - Local development
  • Staging - Pre-production testing
  • Production - Live environment

Email Configuration

Variable Required Description
EMAILCONFIGURATION__HOST Yes* SMTP server hostname
EMAILCONFIGURATION__PORT Yes* SMTP port (587 for TLS)
EMAILCONFIGURATION__USERNAME Yes* SMTP username
EMAILCONFIGURATION__PASSWORD Yes* SMTP password
EMAILCONFIGURATION__FROM Yes* Sender email address

*Required only if email functionality is enabled.

Error Tracking

Variable Required Description
SENTRY__DSN No Sentry Data Source Name
SENTRY__TRACESSAMPLERATE No Sampling rate (0.0-1.0)

Configuration Files

appsettings.json

Base configuration shared across all environments:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",
      "Microsoft.EntityFrameworkCore": "None"
    }
  },
  "AllowedHosts": "*",
  "JwtSettings": {
    "SecretKey": "",
    "Issuer": "https://api.opencashflow.local",
    "Audience": "https://app.opencashflow.local",
    "TokenExpirationMinutes": 15,
    "RefreshTokenExpirationDays": 7
  },
  "Account": {
    "CookieDomain": ".opencashflow.local",
    "API": "https://api.opencashflow.local",
    "AppUrl": "https://app.opencashflow.local/"
  }
}

appsettings.Development.json

Development-specific overrides:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft.AspNetCore": "Information"
    }
  },
  "JwtSettings": {
    "Issuer": "https://localhost:7002",
    "Audience": "https://localhost:7001"
  },
  "Account": {
    "CookieDomain": "localhost",
    "API": "https://localhost:7002",
    "AppUrl": "https://localhost:7001/"
  }
}

appsettings.Staging.json

Staging environment configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  },
  "JwtSettings": {
    "Issuer": "https://api-staging.opencashflow.com",
    "Audience": "https://staging.opencashflow.com"
  }
}

Cookie Configuration

Authentication cookies are configured in Configuration.cs:

Cookie Purpose Duration
.CoreAuth JWT token storage 15 min (or 30 days with "Remember Me")
.CoreAuth.session Session tracking Browser session
.FLCookie Fast login token 1 year

Security settings:

options.Cookie.HttpOnly = true;      // Prevents XSS
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;

JWT Token Configuration

Token Structure

{
  "sub": "user-id-guid",
  "email": "user@example.com",
  "tenant": "company-id-guid",
  "role": "Administrator",
  "permissions": ["CUST_PAYM_VIEW", "CUST_PAYM_NEW"],
  "iat": 1700000000,
  "exp": 1700000900,
  "iss": "https://api.opencashflow.local",
  "aud": "https://app.opencashflow.local"
}

Token Lifetimes

Token Type Default Duration Configurable
Access Token 15 minutes TokenExpirationMinutes
Refresh Token 7 days RefreshTokenExpirationDays
Remember Me 30 days Hardcoded

Logging Configuration

Serilog Setup

Logging is configured via Serilog with multiple sinks:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Warning()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .WriteTo.Console()
    .WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day)
    .WriteTo.Slack(webhookUrl, restrictedToMinimumLevel: LogEventLevel.Error)
    .CreateLogger();

Log Levels

Level When to Use
Verbose Detailed debugging
Debug Development diagnostics
Information General operational events
Warning Potential issues
Error Errors that don't crash the app
Fatal Critical errors

Log Output

  • Console: Real-time development feedback
  • File: Logs/log-YYYYMMDD.txt (rolling daily)
  • Slack: Error notifications (optional)
  • Sentry: Exception tracking (optional)

Environment-Specific Behavior

Development

if (builder.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI();
    options.RequireHttpsMetadata = false;
}

Staging

  • Detailed error pages disabled
  • Swagger UI available
  • Relaxed HTTPS requirements

Production

  • Generic error pages
  • Swagger disabled
  • HTTPS enforced
  • Stricter security headers

Feature Flags

Feature flags can be configured via appsettings.json:

{
  "Features": {
    "EnableStripeIntegration": true,
    "EnableEmailNotifications": true,
    "EnableAuditLogging": true,
    "MaintenanceMode": false
  }
}

Access in code:

var enableStripe = configuration.GetValue<bool>("Features:EnableStripeIntegration");

Validation

Connection String Validation

The application validates required settings at startup:

var connectionString = configuration["DEFAULT_CONN_STRING"];
if (string.IsNullOrEmpty(connectionString))
{
    throw new InvalidOperationException(
        "Database connection string is required. Set DEFAULT_CONN_STRING environment variable.");
}

JWT Key Validation

var jwtKey = configuration["JwtSettings:SecretKey"];
if (string.IsNullOrEmpty(jwtKey) || jwtKey.Length < 64)
{
    throw new InvalidOperationException(
        "JWT secret key must be at least 64 characters. Set JWTSETTINGS__SECRETKEY environment variable.");
}

Docker Environment

When running in Docker, environment variables are passed via:

docker-compose.yml

services:
  api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - DEFAULT_CONN_STRING=${DB_CONNECTION_STRING}
      - JWTSETTINGS__SECRETKEY=${JWT_SECRET}

Environment File

# .env file (not committed to Git)
DB_CONNECTION_STRING=Host=db;Database=opencashflow;Username=app;Password=secret
JWT_SECRET=your-64-character-secret-key-here

Configuration Best Practices

  1. Never commit secrets - Use environment variables
  2. Use different keys per environment - Dev, staging, and production should have unique JWT keys
  3. Validate at startup - Fail fast if required configuration is missing
  4. Use structured configuration - Group related settings under sections
  5. Document all settings - Maintain this documentation
  6. Use secrets managers in production - Azure Key Vault, AWS Secrets Manager, etc.

OpenCashFlow

Preview Status

  • Developer Preview
  • Not production-ready
  • First-run setup included

Clone this wiki locally