Configuration¶
Configuration is typed and loaded with this precedence:
- Operating system environment variables
.envfile when present- Safe defaults
Never commit a real .env file. Use .env.example as the template.
Important groups:
- Application identity:
APP_NAME,APP_ENV,APP_VERSION,INSTANCE_ID - HTTP and timeouts
- CORS
- TLS mode and certificate paths
- MongoDB URI, database, timeouts, pool sizes
- Authentication:
AUTH_ENABLED,AUTH_CLIENT_ID,AUTH_CLIENT_SECRET,AUTH_JWT_SECRET,AUTH_ISSUER,AUTH_AUDIENCE,AUTH_ACCESS_TOKEN_TTL,AUTH_TOKEN_MAX_BODY_BYTES - Integration actor:
INTEGRATION_ACTOR_USER_ID - Tenant defaults:
DEFAULT_COMPANY_ID,DEFAULT_ORGANIZATION_ID - Idempotency:
IDEMPOTENCY_ENABLED,IDEMPOTENCY_REQUIRED,IDEMPOTENCY_RETENTION_HOURS,IDEMPOTENCY_PROCESSING_LEASE_SECONDS - Request archive:
REQUEST_ARCHIVE_ENABLED,REQUEST_ARCHIVE_REQUIRED,REQUEST_ARCHIVE_RETENTION_DAYS,REQUEST_ARCHIVE_STORE_RAW_BODY - Worker and health push placeholders
When AUTH_ENABLED=true, startup fails fast unless client ID, client secret, JWT secret, issuer, audience, and TTL are valid. Client secret and JWT secret must be different and at least 32 characters/bytes.
INTEGRATION_ACTOR_USER_ID¶
Required configuration for inbound work-order persistence audit fields.
| Property | Value |
|---|---|
| Purpose | _id of an existing active user used for project/product audit fields |
| Format | 24-character hexadecimal MongoDB ObjectID of a real user document — never a generated/random ID |
| Secret? | No (still never logged or returned in API responses) |
| Tenant | Must belong to the same company/organization as the request tenant when used at runtime |
| Empty / invalid format | Fail-fast configuration error at startup (required + 24-hex only) |
| Persistence | check and live inbound POST verify the user exists and is active; tenant match is request-time only |
Safe diagnostics expose auth_enabled, auth_client_id, auth_issuer, auth_audience, auth_access_token_ttl, and integration_actor_configured (boolean). The actor ObjectID is never logged. Secrets are never logged.
See Authentication and Work-Order Persistence for usage details.
DEFAULT_COMPANY_ID and DEFAULT_ORGANIZATION_ID¶
Optional environment-level tenant defaults used when inbound work-order requests and outbound GET endpoints omit both company_id and organization_id.
| Property | Value |
|---|---|
| Purpose | Fallback tenant pair for inbound POST and outbound GET APIs |
| Format | 24-character hexadecimal MongoDB ObjectID strings |
| Secret? | No |
| Pair rule | Both must be empty, or both must be valid ObjectIDs |
| One only set | Fail-fast configuration error at startup |
| Runtime partial request | Exactly one request/query value → 400 TENANT_CONTEXT_INCOMPLETE (defaults are not applied) |
When both are empty, callers must supply the tenant pair on every request. When both are set, single-tenant deployments may omit tenant fields from payloads and query strings.
See Inbound Work Orders, Machine Events, and Production Performance.
Idempotency and request archive¶
| Variable | Default | Notes |
|---|---|---|
IDEMPOTENCY_ENABLED |
true |
Master switch for live idempotency |
IDEMPOTENCY_REQUIRED |
true |
Require Idempotency-Key on live endpoint when enabled |
IDEMPOTENCY_RETENTION_HOURS |
720 |
Positive integer; document expires_at |
IDEMPOTENCY_PROCESSING_LEASE_SECONDS |
300 |
Min 30, max 3600 |
REQUEST_ARCHIVE_ENABLED |
true |
Archive inbound work-order attempts |
REQUEST_ARCHIVE_REQUIRED |
true |
Fail with 503 if initial archive insert fails |
REQUEST_ARCHIVE_RETENTION_DAYS |
90 |
Positive integer |
REQUEST_ARCHIVE_STORE_RAW_BODY |
true |
Store raw body when within limits |
Invalid values fail fast at startup. Full Idempotency-Key values are not written to INFO logs (hash/short form only). Secrets remain redacted.
See Idempotency and Request Archive.
Runtime Configuration Paths¶
Windows¶
When deployed as a Native Windows Service (recommended):
text
C:\IQVizyon\IQVIntegrationAPI\
bin\ # Application binary
config\ # Configuration directory
.env # Environment file
logs\ # Application logs
backups\ # Pre-update backups
deployment\ # Deployment metadata
The service loads its configuration from C:\IQVizyon\IQVIntegrationAPI\config\.env.
Linux¶
When deployed as a systemd service:
```text /opt/iqvizyon/iqv-integration-api/ bin/ # Application binary deployment/ # Deployment metadata
/etc/iqvizyon/iqv-integration-api.env # Environment file
/var/log/iqvizyon/iqv-integration-api/ # Application logs
/var/lib/iqvizyon/iqv-integration-api/ backups/ # Pre-update backups ```
The service loads its configuration from /etc/iqvizyon/iqv-integration-api.env.
--env-file Flag¶
The binary accepts an --env-file flag to specify the environment file location:
bash
./iqv-integration-api service install --env-file /etc/iqvizyon/iqv-integration-api.env
./iqv-integration-api service run --env-file /etc/iqvizyon/iqv-integration-api.env
powershell
.\iqv-integration-api.exe service install --env-file C:\IQVizyon\IQVIntegrationAPI\config\.env
.\iqv-integration-api.exe service run --env-file C:\IQVizyon\IQVIntegrationAPI\config\.env
Docker¶
Windows Docker typically mounts an operator .env / -EnvFile from the project or an explicit path. Linux Docker production uses /etc/iqvizyon/iqv-integration-api.docker.env (bootstrapped from the package example + CLI; never overwritten if it already exists).
HTTP_HOST should remain 0.0.0.0 inside the container. Publish with HostPort, not by changing HTTP_HOST to a public hostname. PUBLIC_BASE_URL is the externally visible URL (host + HostPort).
See Docker Installation.
Who creates the env file
Windows installers never auto-create .env. Copy .env.example first.
Linux production install.sh may create /etc/iqvizyon/iqv-integration-api.env (or the Docker env path) from the package example plus CLI flags. An existing file is never overwritten.
Configuration field matrix¶
Source of truth: internal/config/config.go and .env.example. Fields not present in code are not listed.
| Name | Required | Conditional required | Default | Type | Example | Secret? | Used by | Validation |
|---|---|---|---|---|---|---|---|---|
APP_NAME |
No | — | iqv-integration-api |
string | iqv-integration-api |
No | Identity | — |
APP_ENV |
No | — | development |
string | production |
No | Identity | — |
APP_VERSION |
No | — | dev |
string | 1.2.3 |
No | Identity | — |
INSTANCE_ID |
No | — | local-development |
string | host-a |
No | Identity | — |
LOG_LEVEL |
No | — | debug |
string | info |
No | Logging | — |
LOG_FORMAT |
No | — | json |
string | json |
No | Logging | — |
HTTP_HOST |
No | — | 0.0.0.0 |
string | 0.0.0.0 |
No | HTTP | — |
HTTP_PORT |
No | — | 8080 |
int | 4242 |
No | HTTP / installers | Positive port |
API_PREFIX |
No | — | /api/v1 |
string | /api/v1 |
No | HTTP | — |
PUBLIC_BASE_URL |
No | — | http://localhost:8080 |
URL string | https://api.example |
No | HTTP | — |
HTTP_READ_TIMEOUT |
No | — | 15s |
duration | 15s |
No | HTTP | Parseable duration |
HTTP_READ_HEADER_TIMEOUT |
No | — | 10s |
duration | 10s |
No | HTTP | Parseable duration |
HTTP_WRITE_TIMEOUT |
No | — | 30s |
duration | 30s |
No | HTTP | Parseable duration |
HTTP_IDLE_TIMEOUT |
No | — | 60s |
duration | 60s |
No | HTTP | Parseable duration |
HTTP_SHUTDOWN_TIMEOUT |
No | — | 20s |
duration | 20s |
No | HTTP / systemd | Parseable duration |
HTTP_REQUEST_TIMEOUT |
No | — | 30s |
duration | 30s |
No | HTTP | Parseable duration |
HTTP_MAX_BODY_BYTES |
No | — | 10485760 |
int64 | 10485760 |
No | HTTP | Non-negative |
INBOUND_MAX_BODY_BYTES |
No | — | 10485760 |
int64 | 10485760 |
No | Inbound | Non-negative |
INBOUND_MAX_PROJECTS_PER_REQUEST |
No | — | 100 |
int | 100 |
No | Inbound | Positive |
CORS_ENABLED |
No | — | false |
bool | true |
No | CORS | Bool |
CORS_ALLOWED_ORIGINS |
No | When CORS enabled | empty | CSV | https://a.com |
No | CORS | CSV list |
CORS_ALLOWED_METHODS |
No | — | GET,POST,… | CSV | … | No | CORS | CSV list |
CORS_ALLOWED_HEADERS |
No | — | Authorization,… | CSV | … | No | CORS | CSV list |
CORS_ALLOW_CREDENTIALS |
No | — | false |
bool | false |
No | CORS | Bool |
TLS_MODE |
No | — | disabled |
enum string | disabled |
No | TLS | Known modes |
TLS_CERT_FILE |
No | When TLS enabled | empty | path | /etc/ssl/cert.pem |
No | TLS | Path when required |
TLS_KEY_FILE |
No | When TLS enabled | empty | path | /etc/ssl/key.pem |
Yes (file) | TLS | Path when required |
MONGODB_URI |
Yes (runtime) | — | mongodb://127.0.0.1:27017 |
URI | mongodb://host:27017 |
Yes | Mongo / check / serve | Non-empty at serve; Docker installers reject localhost inside container |
MONGODB_DATABASE |
No | — | champion |
string | champion |
No | Mongo | — |
MONGODB_CONNECT_TIMEOUT |
No | — | 10s |
duration | 10s |
No | Mongo | Duration |
MONGODB_PING_TIMEOUT |
No | — | 5s |
duration | 5s |
No | Mongo | Duration |
MONGODB_OPERATION_TIMEOUT |
No | — | 15s |
duration | 15s |
No | Mongo | Duration |
MONGODB_MAX_POOL_SIZE |
No | — | 100 |
int | 100 |
No | Mongo | ≥ 0 |
MONGODB_MIN_POOL_SIZE |
No | — | 5 |
int | 5 |
No | Mongo | ≥ 0 |
AUTH_ENABLED |
No | — | false |
bool | true |
No | Auth | Bool |
AUTH_CLIENT_ID |
No | When AUTH_ENABLED=true |
empty | string | iqv-standard-integration |
No | Auth | Required if auth on |
AUTH_CLIENT_SECRET |
No | When auth on | empty | string | (secret) | Yes | Auth | ≥32 chars; ≠ JWT secret |
AUTH_JWT_SECRET |
No | When auth on | empty | string | (secret) | Yes | Auth | ≥32 bytes; ≠ client secret |
AUTH_ISSUER |
No | When auth on | iqv-integration-api |
string | … | No | Auth | Required if auth on |
AUTH_AUDIENCE |
No | When auth on | iqv-integration-api |
string | … | No | Auth | Required if auth on |
AUTH_ACCESS_TOKEN_TTL |
No | — | 60m |
duration | 60m |
No | Auth | Duration |
AUTH_TOKEN_MAX_BODY_BYTES |
No | — | 16384 |
int64 | 16384 |
No | Auth | Positive |
INTEGRATION_ACTOR_USER_ID |
Yes | — | empty | ObjectId | 507f… |
No | Inbound audit | 24-hex ObjectId |
DEFAULT_COMPANY_ID |
No | Pair with org | empty | ObjectId | 507f… |
No | Tenant | Both empty or both valid |
DEFAULT_ORGANIZATION_ID |
No | Pair with company | empty | ObjectId | 507f… |
No | Tenant | Both empty or both valid |
IDEMPOTENCY_ENABLED |
No | — | true |
bool | true |
No | Idempotency | Bool |
IDEMPOTENCY_REQUIRED |
No | — | true |
bool | true |
No | Idempotency | Bool |
IDEMPOTENCY_RETENTION_HOURS |
No | — | 720 |
int | 720 |
No | Idempotency | Positive |
IDEMPOTENCY_PROCESSING_LEASE_SECONDS |
No | — | 300 |
int | 300 |
No | Idempotency | 30–3600 |
REQUEST_ARCHIVE_ENABLED |
No | — | true |
bool | true |
No | Archive | Bool |
REQUEST_ARCHIVE_REQUIRED |
No | — | true |
bool | true |
No | Archive | Bool |
REQUEST_ARCHIVE_RETENTION_DAYS |
No | — | 90 |
int | 90 |
No | Archive | Positive |
REQUEST_ARCHIVE_STORE_RAW_BODY |
No | — | true |
bool | true |
No | Archive | Bool |
WORKER_ENABLED |
No | — | false |
bool | false |
No | Worker scaffold | Bool |
WORKER_TIMEZONE |
No | — | UTC |
string | UTC |
No | Worker | — |
OUTBOUND_CRON |
No | — | */5 * * * * |
cron | … | No | Worker | — |
OUTBOUND_BATCH_SIZE |
No | — | 100 |
int | 100 |
No | Worker | — |
OUTBOUND_MAX_RETRY |
No | — | 6 |
int | 6 |
No | Worker | — |
OUTBOUND_TIMEOUT |
No | — | 30s |
duration | 30s |
No | Worker | Duration |
HEALTH_DETAILS_ENABLED |
No | — | false |
bool | false |
No | Health | Bool |
HEALTH_PUSH_ENABLED |
No | — | false |
bool | false |
No | Health push | Bool |
HEALTH_PUSH_URL |
No | When push enabled | empty | URL | … | No | Health push | — |
HEALTH_PUSH_INTERVAL |
No | — | 60s |
duration | 60s |
No | Health push | Duration |
HEALTH_PUSH_TIMEOUT |
No | — | 10s |
duration | 10s |
No | Health push | Duration |
HEALTH_PUSH_BEARER_TOKEN |
No | When push enabled | empty | string | (secret) | Yes | Health push | Redacted in logs |
See also Installer validation matrix and Test strategy.