Repository navigation
Expand file tree
/
Copy path.env.example
More file actions
132 lines (125 loc) · 6.26 KB
/
Copy path.env.example
File metadata and controls
132 lines (125 loc) · 6.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Copy to .env and fill in. Compose uses it only for explicit ${VAR} interpolation; each service
# receives an allowlisted environment, so the API never receives MYSQL_ROOT_PASSWORD.
# ---------- MySQL container (local only) ----------
MYSQL_ROOT_PASSWORD=devroot
MYSQL_DATABASE=appdb
MYSQL_USER=appuser
MYSQL_PASSWORD=apppass
# REQUIRED: for a clean install choose a new name such as sharpbill_mysql84_data. For an
# existing 8.0 install, restore into a fresh 8.4 volume first; never point 8.4 at it implicitly.
MYSQL_DATA_VOLUME=
# Host port for optional GUI access to MySQL (loopback only). Change if 3306 is taken.
MYSQL_HOST_PORT=3306
# Host ports the app is published on. Change these if 8000 / 5173 are already in use locally.
API_HOST_PORT=8000
WEB_HOST_PORT=5173
# ---------- Backend ----------
APP_ENV=local
# ASP.NET Core's environment is independent from Sharpbill's fail-closed APP_ENV policy.
ASPNETCORE_ENVIRONMENT=Development
# Only used when running the backend OUTSIDE Docker; Compose passes the MySQL service values
# directly. The application and migrator build a safely escaped connection string from these parts.
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=appdb
DB_USER=appuser
DB_PASSWORD=apppass
# As an alternative for managed secret injection, ASP.NET Core also accepts a complete connection
# string in ConnectionStrings__Sharpbill. It must include SslMode=VerifyFull and SslCa in
# production. Clear every DB_* connection/transport variable when using this mutually exclusive path.
ConnectionStrings__Sharpbill=
DB_REQUIRE_TLS=false
# Verified CA bundle used when DB_REQUIRE_TLS=true (the backend image includes this RDS bundle).
DB_TLS_CA_PATH=/opt/sharpbill/certs/rds-global-bundle.pem
# Connection limits are per API process; include every worker/instance in the total DB budget.
DB_POOL_SIZE=5
DB_MAX_OVERFLOW=5
DB_POOL_TIMEOUT_SECONDS=10
DB_POOL_RECYCLE_SECONDS=280
DB_CONNECT_TIMEOUT_SECONDS=5
DB_READ_TIMEOUT_SECONDS=30
DB_WRITE_TIMEOUT_SECONDS=30
# Generate 32 random bytes with your secret manager, `openssl rand -hex 32`, or PowerShell:
# [Convert]::ToHexString([Security.Cryptography.RandomNumberGenerator]::GetBytes(32)).ToLowerInvariant()
SESSION_JWT_SECRET=
# Rotation overlap keys, comma-separated. Remove each old key only after its maximum token TTL.
SESSION_JWT_PREVIOUS_SECRETS=
SESSION_JWT_ISSUER=sharpbill
SESSION_JWT_AUDIENCE=sharpbill-web
SESSION_TTL_HOURS=8
COOKIE_SECURE=false
# Bound active device sessions, post-expiry retention, and total request-body memory exposure.
MAX_ACTIVE_SESSIONS_PER_USER=20
SESSION_RETENTION_DAYS=30
SESSION_PRUNE_BATCH_SIZE=500
REQUEST_BODY_MAX_BYTES=1048576
# CSV exports are capped before response headers and share one no-queue concurrency gate per API process.
EXPORT_MAX_BYTES=26214400
EXPORT_MAX_CONCURRENCY=2
# Bounded asynchronous access-telemetry writer and scheduled, independently bounded retention.
REQUEST_LOG_QUEUE_CAPACITY=2048
REQUEST_LOG_RETENTION_DAYS=90
REQUEST_LOG_PRUNE_BATCH_SIZE=2000
REQUEST_LOG_SHUTDOWN_TIMEOUT_SECONDS=5
# Each scheduled cycle removes at most (table batch size * max batches) rows per table.
RETENTION_WORKER_INTERVAL_SECONDS=3600
RETENTION_WORKER_MAX_BATCHES_PER_CYCLE=10
RETENTION_WORKER_SHUTDOWN_TIMEOUT_SECONDS=10
SECURITY_EVENT_RETENTION_DAYS=400
# Provisional contract-evidence default; counsel must approve it for the deployment.
LEGAL_ACCEPTANCE_RETENTION_DAYS=2555
PRECISE_LOCATION_RETENTION_HOURS=24
PENDING_ACCOUNT_RETENTION_DAYS=30
DISABLED_ACCOUNT_RETENTION_DAYS=365
ACCOUNT_ERASURE_GRACE_DAYS=30
NONCE_PRUNE_BATCH_SIZE=500
PRECISE_LOCATION_PRUNE_BATCH_SIZE=500
ACCOUNT_RETENTION_PRUNE_BATCH_SIZE=100
SECURITY_EVENT_PRUNE_BATCH_SIZE=500
LEGAL_ACCEPTANCE_PRUNE_BATCH_SIZE=500
# Leave blank until you create the OAuth apps; the login page hides a provider until its ID is set.
# Production validates Google's `number-slug.apps.googleusercontent.com` form and an Azure GUID.
GOOGLE_CLIENT_ID=
AZURE_CLIENT_ID=
# Bound synchronous signature verification and provider key retrieval. Key documents are fetched
# with explicit connect/read timeouts, coalesced, size-capped, briefly back off unknown `kid`
# floods, and may use a previously verified document only within the stale window during outage.
IDP_VERIFICATION_MAX_CONCURRENCY=8
IDP_NETWORK_MAX_CONCURRENCY=2
IDP_HTTP_CONNECT_TIMEOUT_SECONDS=2
IDP_HTTP_READ_TIMEOUT_SECONDS=3
IDP_KEY_CACHE_TTL_SECONDS=3600
IDP_KEY_CACHE_STALE_SECONDS=86400
IDP_KEY_REFRESH_WAIT_SECONDS=6
IDP_UNKNOWN_KID_BACKOFF_SECONDS=10
IDP_OUTAGE_BACKOFF_INITIAL_SECONDS=2
IDP_OUTAGE_BACKOFF_MAX_SECONDS=60
IDP_KEY_DOCUMENT_MAX_BYTES=1048576
# Your company tenant GUID — gates Microsoft-based admin bootstrap. Blank = disabled.
AZURE_ADMIN_TENANT_ID=
# Microsoft object IDs (oid), comma-separated, permitted to bootstrap admin inside the configured
# signed tenant. Bootstrap keys on immutable (tenant, oid), never mutable email/UPN. Blank = off.
AZURE_ADMIN_OBJECT_IDS=
# Google immutable OIDC subject IDs (`sub`), comma-separated, permitted to bootstrap admin.
GOOGLE_ADMIN_SUBJECTS=
# Local-development recovery bootstrap only. Hosted Google uses GOOGLE_ADMIN_SUBJECTS and
# Microsoft uses AZURE_ADMIN_OBJECT_IDS within AZURE_ADMIN_TENANT_ID.
ADMIN_EMAILS=you@example.com
# New-account admission is controlled in the database by site_settings.signup_mode. The policy
# applies provider-wide; this deployment intentionally has no email-domain or tenant allowlist.
LOG_LEVEL=INFO
# Required in production: the exact public HTTPS origin, with no path (for CSRF validation).
# This remains correct when a trusted reverse proxy terminates TLS in front of the API.
PUBLIC_ORIGIN=
# If the app runs behind a trusted reverse proxy, list explicit peer IP addresses or CIDR networks
# (comma-separated) so the real client IP is read from X-Forwarded-For for rate-limiting + the audit
# log. Hostnames, "*", and world-wide CIDRs are rejected; empty trusts no XFF and uses the socket
# peer (correct when there is no proxy in front).
TRUSTED_PROXY_IPS=
# ---------- Dev-only login bypass ----------
# A /api/auth/dev endpoint that mints a session without Google/Microsoft.
# It ONLY mounts when APP_ENV=local, DEV_AUTH_ENABLED=true, and DEV_AUTH_SECRET is strong.
# It never activates in a non-local environment.
DEV_AUTH_ENABLED=false
# Generate a separate 32-byte value; callers send it as X-Dev-Auth-Secret. Never reuse JWT secret.
DEV_AUTH_SECRET=