Configuration
Configuration Files
| File | Purpose | Git tracked |
|---|---|---|
appsettings.json |
Base configuration (shared across environments) | Yes |
appsettings.Development.json |
Development overrides (API keys, local settings) | No (in .gitignore) |
appsettings.{Environment}.json |
Environment-specific overrides | Depends on environment |
Configuration Keys
Postgres
| Key | Description | Default |
|---|---|---|
ConnectionStrings:Postgres |
Postgres connection string (host, port, database — no credentials) | Host=localhost;Port=5432;Database=nompd;Username=postgres;Password=postgres (fallback when no connection string is configured) |
Postgres:Username |
Optional. Postgres user. Overrides any User ID in the connection string when set |
None |
Postgres:Password |
Optional. Postgres password. Overrides any Password in the connection string when set |
None |
For local development, put the credentials in .Net User Secrets`:
{
"Postgres": {
"Username": "admin",
"Password": "change-me"
}
}
Upstream Sync
| Key | Description | Default |
|---|---|---|
Sync:UpstreamBaseUrl |
Base URL for upstream FHIR APIs | https://legemidler-api-test.azurewebsites.net/api/v1 |
Sync:UpstreamApiKey |
API key for authenticating with upstream APIs | None (required) |
The UpstreamApiKey should be placed in appsettings.Development.json for local development:
{
"Sync": {
"UpstreamApiKey": "your-key-here"
}
}
In production, use environment variables or a secrets manager:
Sync__UpstreamApiKey=your-production-key
API Keys
| Key | Description | Default |
|---|---|---|
ApiKeys |
Array of valid API keys for authenticating consumers | [] |
{
"ApiKeys": [
"client-key-1",
"client-key-2"
]
}
The v1 endpoints require a valid X-API-KEY header matching one of the configured keys. The v2 endpoints are authenticated with HelseID access tokens (DPoP) instead and do not use API keys.
HelseID
| Key | Description | Default |
|---|---|---|
HelseId:Authority |
The HelseID authorization server. Access tokens are validated against its JWKS metadata | https://helseid-sts.test.nhn.no |
The v2 endpoints (/api/v2/*) accept DPoP-bound HelseID access tokens. Requests must send Authorization: DPoP <access-token> plus a DPoP proof header; the access token must have audience nhn:nompd and the nhn:nompd/api scope. Proof replay is guarded by an in-memory replay cache (IDistributedCache via AddDistributedMemoryCache).
{
"HelseId": {
"Authority": "https://helseid.nhn.no"
}
}
HelseID
v2 endpoints (/api/v2/*) are authenticated with HelseID access tokens using DPoP (RFC 9449).
| Key | Description | Default |
|---|---|---|
HelseId:Authority |
HelseID authorization server used to validate access tokens (JWKS metadata) | https://helseid-sts.test.nhn.no (test environment); production is https://helseid-sts.nhn.no |
Set the authority per environment via the helseId.authority Helm value in manifests/apps/backend/ (e.g. values.prod.yaml sets https://helseid-sts.nhn.no). When set, it renders the HelseId__Authority environment variable in the backend Deployment, overriding the default. The audience (nhn:nompd) and required scope (nhn:nompd/api) are fixed in code (Api/HelseId/Constants.cs).
Logging
Logging is handled by Serilog (configured in Program.cs and the Serilog section of appsettings.json). Output goes to stdout — one compact JSON object per line in test/prod (Splunk-searchable), a readable text template in Development.
- Console sink and output format are selected by environment in code (not in
appsettings.json) - Every event is enriched with
Service(nompd-api),Version(theAPP_VERSIONenvironment variable, falling back to the assembly version),MachineName,ThreadId, andRequestId(correlation ID) for request-scoped events - Default levels (
Serilog:MinimumLevel):Default:InformationMicrosoft.AspNetCore:WarningMicrosoft.EntityFrameworkCore:WarningMicrosoft.Hosting.Lifetime:Information
- In NHN k8s, pod stdout is shipped to Splunk via Fluent Bit (default index
kube_MILJØ; a dedicated index can be attached with thenhn.no/splunkIndexpod annotation once one has been ordered from Driftteam Monitorering) - Request logging (
RequestLoggingMiddleware, one line per request; levelInformation,Warningfor 4xx,Errorfor 5xx):- v1 and internal endpoints:
GET /api/v1/treatment-group 200 in 12ms - v2 endpoints additionally log the query string (e.g.
since-versionpolling), the consumer's HelseIDclient_id, and the client IP /api/internal/healthis never logged (kubernetes probe noise)
- v1 and internal endpoints:
CORS
CORS is configured in Program.cs to allow http://localhost:5173 (frontend dev server). Modify the origin list for production deployments.
Forwarded Headers
| Key | Description | Default |
|---|---|---|
FORWARDED_TRUSTED_NETWORKS |
Comma-separated CIDR ranges of trusted source networks that may set X-Forwarded-Proto. When unset, the forwarded-headers middleware is skipped (correct for local development where the app is accessed directly). |
None (middleware skipped) |
This configures the UseForwardedHeaders middleware, which restores the original https scheme behind the TLS-terminating Gateway API. The HelseID DPoP validation requires request.Scheme to match the htu claim in the client's proof (always https://...).
FORWARDED_TRUSTED_NETWORKS=10.244.0.0/16
Set this to the pod CIDR range of the cluster's Gateway API controller in each environment's Helm values (forwardedHeaders.trustedNetworks).
Environment Variables
All configuration keys can be overridden with environment variables using the __ separator:
ConnectionStrings__Postgres=Host=prod-server;Port=5432;Database=nompd-prod
Postgres__Username=api-user
Postgres__Password=secret
Sync__UpstreamBaseUrl=https://legemidler-api.azurewebsites.net/api/v1
Sync__UpstreamApiKey=prod-api-key
ApiKeys__0=client-key-1
ApiKeys__1=client-key-2
HelseId__Authority=https://helseid.nhn.no
FORWARDED_TRUSTED_NETWORKS=10.244.0.0/16
Secrets Handling
Never commit API keys or secrets to source control.
| Secret | Where to configure |
|---|---|
Sync:UpstreamApiKey |
appsettings.Development.json (local), K8s Secret (prod) |
ApiKeys |
appsettings.Development.json (local), K8s Secret (prod) |
Postgres:Username |
appsettings.Development.json (local), postgres-auth in K8s (prod) |
Postgres:Password |
appsettings.Development.json (local), postgres-auth in K8s (prod) |