includes/config.phpstarts the secured session and resolves the source release version.includes/config.local.phpis loaded when present.- Environment variables supply constants not already defined by private configuration.
- Safe or empty defaults are used last.
The release version is resolved before private configuration so an installer-generated APP_VERSION value cannot pin a future source upgrade. An explicit APP_VERSION environment variable remains supported.
Environment variables are preferred in managed hosting and containers. On shared hosting, protect includes/config.local.php with the supplied includes/.htaccess or equivalent web-server rules.
| Constant | Environment variable | Default | Notes |
|---|---|---|---|
DB_HOST |
LICENSE_DB_HOST, fallback DB_HOST |
localhost |
Database hostname or IP address. |
DB_PORT |
LICENSE_DB_PORT, fallback DB_PORT |
3306 |
MySQL/MariaDB TCP port. |
DB_NAME |
LICENSE_DB_NAME, fallback DB_NAME |
empty | Required. |
DB_USER |
LICENSE_DB_USER, fallback DB_USER |
empty | Use a database-specific least-privilege account. |
DB_PASS |
LICENSE_DB_PASS, fallback DB_PASS |
empty | Required when the database account has a password. |
APP_NAME |
APP_NAME |
Licora |
Application label. |
APP_URL |
APP_URL |
http://localhost |
Public application root, without a query string or fragment. |
APP_VERSION |
APP_VERSION |
5.8.4 |
Source release identity returned by the verification API. |
APP_TIMEZONE |
APP_TIMEZONE |
Asia/Dhaka |
PHP runtime timezone. |
APP_LOCALE |
APP_LOCALE |
en |
Application locale metadata. |
MAIL_FROM_NAME |
MAIL_FROM_NAME |
APP_NAME |
Mail display name. CR/LF characters are rejected by the installer. |
ENVIRONMENT |
APP_ENV |
production |
Controls PHP error reporting; public exception responses remain generic. |
APP_KEY |
LICENSE_APP_KEY, fallback APP_KEY |
empty | Application secret generated by the installer. |
ENCRYPTION_KEY |
LICENSE_ENCRYPTION_KEY |
empty | High-entropy encryption secret. Required for reliable encrypted-value recovery. |
CSRF_SECRET |
LICENSE_CSRF_SECRET |
empty | Compatibility secret; session CSRF tokens remain random. |
JWT_SECRET |
LICENSE_JWT_SECRET |
empty | Reserved for compatible future use. |
API_RATE_LIMIT |
API_RATE_LIMIT |
1000 |
Global hourly IP limit used by the API endpoints. |
API_VERSION |
API_VERSION |
v1 |
Compatibility metadata. |
| Allowed origin | LICENSE_ALLOWED_ORIGIN |
APP_URL |
Exact-origin match used by the full API endpoint. |
LICENSE_DB_HOST=127.0.0.1
LICENSE_DB_PORT=3306
LICENSE_DB_NAME=license_system
LICENSE_DB_USER=license_app
LICENSE_DB_PASS=replace-with-a-secret
APP_NAME=Licora
APP_URL=https://licenses.example.com/licora
APP_ENV=production
APP_TIMEZONE=Asia/Dhaka
APP_LOCALE=en
MAIL_FROM_NAME=Licora
LICENSE_APP_KEY=replace-with-a-random-64-character-secret
LICENSE_ENCRYPTION_KEY=replace-with-a-random-64-character-secret
LICENSE_CSRF_SECRET=replace-with-a-random-64-character-secret
LICENSE_JWT_SECRET=replace-with-a-random-64-character-secret
API_RATE_LIMIT=1000
LICENSE_ALLOWED_ORIGIN=https://app.example.comA fresh v5.8.4 wizard installation writes includes/config.local.php atomically and then creates includes/.licora-installed. Preserve both files, together with includes/.licora-encryption.key when present, during backup or upgrade operations.
Never commit or publish:
includes/config.local.phpincludes/.licora-encryption.keyincludes/.licora-installed- temporary
*.installing.*files .envor.env.*deployment files
The settings table contains both active runtime-backed values and legacy/stored-only values retained for backward compatibility. In v5.5.1 the Admin Settings page exposes only controls that the current runtime actually consumes: default_license_hours, default_device_limit, license_min_hours, license_max_hours, and log_retention_days. Stored-only legacy keys are not deleted by this release and are not presented as active controls.
API endpoints, runtime limits, application version/environment, Cron CLI commands and Secure API v2 key status/fingerprint are displayed as read-only operational information. The API v2 public key may be downloaded by a Super Admin; the private signing key remains server-only and is never displayed or downloadable. Review FEATURE_MATRIX.md for implementation status.
Fresh installation executes the existing database.sql, including tables, indexes, foreign keys, and triggers. The database account therefore needs the privileges required by that schema. Shared hosts that deny TRIGGER will not complete the standard installer. v5.2.1 returns a non-secret diagnostic when that denial is detected.
| Purpose | Environment/constant | Default |
|---|---|---|
| Require HTTPS | LICENSE_V2_REQUIRE_HTTPS |
1 |
| Trust proxy HTTPS header | LICENSE_TRUST_PROXY_HEADERS |
0 |
| Maximum JSON body bytes | LICENSE_V2_MAX_BODY_BYTES |
32768 |
| Base v2 request limit/hour | LICENSE_V2_RATE_LIMIT |
300 |
| Default clock skew seconds | LICENSE_V2_CLOCK_SKEW |
300 |
| Signing key ID | LICENSE_V2_SIGNING_KEY_ID |
primary-v1 |
| Signing private-key path | LICENSE_V2_SIGNING_PRIVATE_KEY_PATH |
includes/.licora-v2-signing-private.pem |
| Signing public-key path | LICENSE_V2_SIGNING_PUBLIC_KEY_PATH |
includes/.licora-v2-signing-public.pem |
Signing key files are deployment material, not repository configuration. Existing deployments can generate/validate them either with php scripts/setup-v2.php or, when shell access is unavailable, through Admin → Client Apps → Initialize API v2. Both paths use the same additive provisioner and refuse partial or mismatched existing key pairs.
| Purpose | Environment/constant | Default |
|---|---|---|
| Require HTTPS | ADMIN_API_REQUIRE_HTTPS |
1 |
| Maximum JSON body bytes | ADMIN_API_MAX_BODY_BYTES |
65536 |
| Request clock skew seconds | ADMIN_API_CLOCK_SKEW |
300 |
Per-key application assignments, scopes, IP/CIDR allowlists, hourly limits, expiry and lifecycle state are managed under Admin → Settings → Admin License API. Keep HTTPS required in production. LICENSE_TRUST_PROXY_HEADERS affects forwarded HTTPS detection for this API too and must be enabled only behind a trusted proxy that overwrites the forwarded-protocol header.
Set LICENSE_TRUST_PROXY_HEADERS=1 only when Licora is behind a trusted reverse proxy that overwrites the forwarded-protocol header. Never enable it for direct public traffic where clients can supply X-Forwarded-Proto themselves.
| Purpose | Constant / environment variable | Default |
|---|---|---|
| Official release repository | LICORA_UPDATE_REPOSITORY |
vibtools/Licora (pinned; non-official values are rejected) |
| Cached automatic check interval | LICORA_UPDATE_CHECK_INTERVAL |
21600 seconds |
| GitHub HTTP/download timeout | LICORA_UPDATE_HTTP_TIMEOUT |
120 seconds |
| Maximum accepted release package | LICORA_UPDATE_MAX_PACKAGE_BYTES |
104857600 bytes |
| Manifest verification public key | LICORA_UPDATE_PUBLIC_KEY_PATH |
includes/updater/update-signing-public.pem |
| Optional GitHub API token | LICORA_GITHUB_TOKEN |
unset |
The updater has no arbitrary URL field. Release metadata is obtained only from the pinned official vibtools/Licora GitHub repository and every install requires a valid dedicated updater signature. LICORA_GITHUB_TOKEN is optional and should be a least-privilege token used only when API rate limits require it. Do not place the private update signing key on a production Licora deployment; it belongs only in the repository release automation secret LICORA_UPDATE_SIGNING_PRIVATE_KEY.
The database settings table stores updater_auto_check, updater_check_interval_seconds, updater_channel, cached release metadata and updater history pointers. updater_auto_check=0 disables automatic outbound GitHub checks but does not disable the explicit Super Admin Check for Updates action. In updater protocol v1, updater_channel is reserved and fixed to stable; it is not a selectable beta/dev channel. Automatic checking is notification-only; installation always requires a Super Admin action.
The Phase 1 Dashboard read model adds no deployment secret or database setting. Device recently_seen reporting uses a fixed five-minute (300 second) read-only window. Dashboard AJAX data is authenticated, non-cacheable and contains no private signing keys, API credentials or database credentials. API v2 readiness is a boolean-only check that requires both the full v2 schema and a readable matching private/public signing key pair; key contents and paths are never returned. Cron status is limited to script availability because v5.7.1 does not add a scheduler heartbeat. Phase 2 adds no deployment setting or secret; the browser controller consumes the same authenticated read-only snapshot every 30 seconds and on manual refresh.
The Developer Guide adds no new secret, environment variable, database setting or outbound service. It derives the current installation root and existing API v2 endpoint URLs from the shared UI integration helper. Example clients accept the Licora Base URL, App ID, license key and app version at runtime; no API v1 master/shared key is embedded in public-client examples.