-
-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy path.env.example
More file actions
211 lines (192 loc) · 8.32 KB
/
Copy path.env.example
File metadata and controls
211 lines (192 loc) · 8.32 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# Copy this file to .env.local (or .env.development or .env.production)
# Do not commit .env.local to version control, as it may contain sensitive information.
# In production, API_BASE_PATH must be set; other variables are optional.
# In development, the variables are used to launch the API and the Unit Test server.
# valid values: development, test, staging, production
APP_ENV=development
##
# WebSocket Configuration
# Set the same value for WS_PORT in the Unit Test frontend project folder
# See: https://github.com/Liturgical-Calendar/LiturgicalCalendarAPI/blob/development/public/LitCalTestServer.php
# NOTE: Port 8080 is reserved for Zitadel, port 8081 for Login V2
##
WS_PORT=8082
# Maximum concurrent HTTP requests for WebSocket server (default: 10 in production, 4 in development)
# Reduce this on memory-constrained servers to prevent overwhelming the API
WS_MAX_CONCURRENCY=10
# Maximum outbound API requests dispatched per rolling 1-second window (default: 3).
# Keeps the WebSocket test server under the public API's per-IP rate limit (nginx limit_req)
# without needing server-side IP exemptions. Set to match your API's unauthenticated rate.
WS_MAX_REQUEST_RATE=3
# Optional first-party API key the WebSocket test server sends (X-Api-Key header) on its internal
# API requests, so they authenticate and bypass the unauthenticated per-IP rate limit.
# Mint one with: php scripts/mint-official-key.php --name=test-runner --owner=<zitadel_user_id>
# Leave empty to fall back to unauthenticated requests (subject to UNAUTHENTICATED_RATE_LIMIT).
WS_API_KEY=
##
# API Configuration
# These variables control where the API launches and how the Unit Test server connects to it
##
API_PROTOCOL=http
API_HOST=localhost
# This determines the port on which 'composer start' will launch the API
# It also instructs the Unit Test server on which port to look for the API
# If launching from VSCode tasks, set the same value in tasks.json
API_PORT=8000
# API Base Path - required in production or if dev server is not launched from public folder
# The API cannot infer whether its path is `/api/` or `/api/{version}/`
# In local development, leave empty (API runs at root)
# In production, typically /api/dev/ or /api/v5/
# Trailing slash is optional (the code normalizes either format)
# IMPORTANT: This value must match across the API and Unit Test Interface .env files
API_BASE_PATH=
##
# JWT Authentication Configuration
# Generate a secure 64-character hex string: php -r "echo bin2hex(random_bytes(32));"
##
JWT_ALGORITHM=HS256
JWT_EXPIRY=3600
JWT_REFRESH_EXPIRY=604800
# IMPORTANT: Change to a strong random string in production (minimum 32 characters)
JWT_SECRET=change-this-to-a-secure-random-string-in-production-minimum-32-chars
##
# Admin User Credentials
# Generate password hash: php -r "echo password_hash('your-password', PASSWORD_ARGON2ID);"
# In dev/test: falls back to default password "password" if hash is missing/invalid
# In staging/production: a valid ADMIN_PASSWORD_HASH is required
##
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH=CHANGE_ME_GENERATE_WITH_password_hash
# DEPLOY_TOKEN — long random shared secret used by GitHub Actions to
# authenticate deploy-time requests to POST /_ops/migrate.
# Generate with: openssl rand -hex 32
# Must be set in staging/production .env files; the GitHub Actions secret
# of the same name is sent in the X-Deploy-Token request header.
DEPLOY_TOKEN=
##
# CORS Configuration
# Comma-separated list of allowed origins for credentialed CORS requests (auth endpoints)
# Use '*' to allow all origins (not recommended for production with cookie-based auth)
# Example: https://example.com,https://admin.example.com
##
CORS_ALLOWED_ORIGINS=*
##
# Cookie Domain Configuration
# For cross-subdomain cookie sharing (e.g., frontend at frontend.example.com, API at api.example.com)
# Set to the parent domain with a leading dot to share cookies across all subdomains
# Leave empty or unset to use the exact host (default behavior)
# Example: .example.com (shares cookies across all *.example.com subdomains)
##
# COOKIE_DOMAIN=.example.com
##
# Rate Limiting for Authentication
# Protects against brute-force attacks on the /auth/login endpoint
##
# Maximum failed login attempts before lockout (default: 5)
RATE_LIMIT_LOGIN_ATTEMPTS=5
# Time window in seconds for tracking attempts (default: 900 = 15 minutes)
RATE_LIMIT_LOGIN_WINDOW=900
# Path for rate limit data files (default: system temp directory)
# RATE_LIMIT_STORAGE_PATH=/var/lib/litcal/rate_limits
##
# Unauthenticated Rate Limiting
# Rate limit per hour for requests without an API key (limited by IP address).
# Set higher in development/test environments to avoid hitting limits during test suites.
##
UNAUTHENTICATED_RATE_LIMIT=10
##
# API Key Rate Limiting
# Default rate_limit_per_hour for newly generated API keys when the user does not specify one.
# Authenticated requests use the rate_limit_per_hour value stored in the API key record.
##
API_KEY_DEFAULT_RATE_LIMIT=100
##
# HTTPS Enforcement
# In staging/production, auth endpoints require HTTPS by default
# Set to "false" to disable (e.g., if TLS is terminated at load balancer)
# When using a reverse proxy, ensure it sets X-Forwarded-Proto header
##
HTTPS_ENFORCEMENT=true
##
# Redis Configuration (for WebSocket server caching)
# Uses Redis (or APCu fallback) for caching
# Configure either Unix socket OR TCP connection (socket takes precedence)
# If not configured, defaults to TCP 127.0.0.1:6379
##
# Unix socket connection (recommended for local Redis):
# REDIS_SOCKET=/var/run/redis/redis.sock
# TCP connection:
# REDIS_HOST=127.0.0.1
# REDIS_PORT=6379
##
# OpenFGA outbox reconciliation
# Configures the Redis Streams-based reconciler for async tuple operations
##
REDIS_OUTBOX_STREAM=litcal:reconcile-stream
REDIS_OUTBOX_GROUP=reconciler
REDIS_OUTBOX_CONSUMER_NAME= # default: hostname
OUTBOX_MAX_ATTEMPTS=10
OUTBOX_BACKSTOP_GRACE_SECONDS=60
##
# Docker Compose Port Configuration
# These variables are read by docker-compose.yml for port mappings
# All services are bound to 127.0.0.1 (localhost only)
##
# ZITADEL_PORT=8080
# ZITADEL_LOGIN_PORT=8081
# OPENFGA_HTTP_PORT=8083
# OPENFGA_GRPC_PORT=8084
# OPENFGA_PLAYGROUND_PORT=3001
# OPENFGA_DB_USER=openfga
# OPENFGA_DB_PASSWORD=openfga_secure_password
# OPENFGA_DB_NAME=openfga
# OpenFGA Playground UI is OFF by default for security.
# Local dev: enable with the line below to use http://127.0.0.1:3001
# OPENFGA_PLAYGROUND_ENABLED=true
# OpenFGA server-side auth (defaults to "none" — anyone with network reach can
# call the gRPC/HTTP API). For production set both of the following and also
# set OPENFGA_API_TOKEN below to one of the keys you list here:
# OPENFGA_AUTHN_METHOD=preshared
# OPENFGA_AUTHN_PRESHARED_KEYS=replace-with-strong-random-key
# ADMINER_PORT=8088
# MAILPIT_PORT=8025
# DB_PORT=5432
##
# Zitadel OIDC Configuration (for RBAC)
# Configure after setting up Zitadel via docker compose
# See: infrastructure/README.md for setup instructions
##
# ZITADEL_ISSUER=http://localhost:8080
# ZITADEL_CLIENT_ID=your-api-client-id
# ZITADEL_PROJECT_ID=your-project-id
# Internal URL for Docker networking (when API and Zitadel run in the same compose stack)
# Set to the Docker service name so server-side requests route through the Docker network
# Leave unset when the API runs on the host (default: uses ZITADEL_ISSUER for all requests)
# ZITADEL_INTERNAL_URL=http://zitadel:8080
##
# OpenFGA Configuration (fine-grained authorization)
# Configure after setting up OpenFGA via docker compose and running setup-openfga.sh
# The setup script will output the store ID and authorization model ID
##
# OPENFGA_API_URL=http://localhost:8083
# OPENFGA_STORE_ID=your-store-id
# OPENFGA_MODEL_ID=your-model-id
# Optional: preshared key for OpenFGA authentication (required if OPENFGA_AUTHN_METHOD=preshared)
# OPENFGA_API_TOKEN=your-preshared-key
##
# PostgreSQL Configuration (for app-specific data: permissions, API keys, audit log)
# Only required when using RBAC features
##
# DB_HOST=localhost
# DB_PORT=5432
# DB_NAME=litcal
# DB_USER=litcal
# DB_PASSWORD=litcal_secure_password
##
# Environment Admin Fallback
# When enabled, allows authentication via ADMIN_USERNAME/ADMIN_PASSWORD_HASH
# even when Zitadel is unavailable. Useful for disaster recovery.
# Default is disabled (false) for security. Only enable explicitly when needed.
# IMPORTANT: Keep disabled in production unless absolutely necessary.
##
ALLOW_ENV_ADMIN_FALLBACK=false