Skip to content

Configuration

Pia Server uses standard ASP.NET Core configuration: layered sources with environment variables overriding appsettings.json. Sensitive values (secrets, master key) must come from environment variables in production.

  1. appsettings.json
  2. appsettings.{Environment}.json (e.g. appsettings.Production.json)
  3. Environment variables
  4. Command-line arguments
KeyEnvPurpose
Database:ProviderDatabase__Providersqlite (default in dev) or postgresql
Database:ConnectionStringDatabase__ConnectionStringEF Core connection string for the chosen provider

PostgreSQL example:

Host=postgres;Database=pia;Username=pia;Password=<db-password>

Migrations are applied automatically on startup.

KeyEnvPurpose
Jwt:SecretKeyJWT_SECRET_KEYHMAC signing key, ≥ 32 chars
Jwt:IssuerDefault pia-server
Jwt:AudienceDefault pia-client
Jwt:AccessTokenLifetimeDefault 15 minutes
Jwt:RefreshTokenLifetimeDefault 30 days
{
"OAuth": {
"Google": { "ClientId": "...", "ClientSecret": "..." },
"Microsoft": { "ClientId": "...", "ClientSecret": "..." }
}
}

In production, prefer environment variables: OAUTH_GOOGLE_CLIENT_ID / _SECRET, OAUTH_MICROSOFT_CLIENT_ID / _SECRET. See Microsoft Entra ID OAuth for the full Entra setup.

KeyEnvPurpose
Encryption:MasterKeyENCRYPTION_MASTER_KEY64 hex chars (32 bytes) — used to derive per-user keys via HKDF

The default upstream AI provider, plus optional per-mode overrides selected by the X-Pia-Mode header.

KeyEnvPurpose
Ai:ProviderAI_PROVIDERopenai, azure, anthropic, mistral, …
Ai:ApiKeyAI_API_KEYUpstream API key
Ai:ModelAI_MODELe.g. gpt-4o-mini
Ai:EndpointAI_ENDPOINTUpstream base URL

Per-mode overrides:

VariableMode
AI_ASSISTANT_PROVIDER / _API_KEY / _MODEL / _ENDPOINTAssistant
AI_RESEARCH_PROVIDER / _API_KEY / _MODEL / _ENDPOINTResearch
(default Ai:*)Optimize

If a mode override isn’t set, the default provider is used.

Knowledge, Embeddings, Chunking (knowledge base)

Section titled “Knowledge, Embeddings, Chunking (knowledge base)”

The knowledge base requires both the Knowledge license feature and Knowledge:ConnectionString set — miss either and it stays off. See Admin → Knowledge bases for the full setup flow and Architecture → Knowledge base for how it works.

KeyEnvPurpose
Knowledge:ConnectionStringKnowledge__ConnectionStringpgvector DB connection — enables the KB when set
Knowledge:IngestApiKeyKnowledge__IngestApiKeyInstance-wide REST ingest key (X-Pia-Service-Key); empty disables the REST API
Embeddings:ProviderIdEmbeddings__ProviderIdAn Ai:Providers[].Id resolving the embedding endpoint/key
Embeddings:ModelEmbeddings__ModelEmbedding model (default bge-m3)
Embeddings:DimensionEmbeddings__DimensionMust equal the compiled schema (1024); mismatch disables the KB
Embeddings:TimeoutSecondsEmbeddings__TimeoutSecondsIngestion upstream timeout (default 100)
Chunking:Context:EnabledChunking__Context__EnabledContextual retrieval, on by default (auto-disabled if no provider)
Chunking:Context:ProviderIdChunking__Context__ProviderIdAn Ai:Providers[].Id of a chat model for per-chunk context
Chunking:*Chunking__*Semantic double-pass splitter knobs (buffer size, thresholds, chunk-size bounds)

Per-group quotas (KnowledgeBases, KnowledgeDocuments, KnowledgeStorageBytes, MonthlyEmbeddingTokens) live in GroupSettings.Quotas and are edited in the group editor, not in config.

KeyPurpose
License:PathPath to the licence XML (default licence.xml next to the binary)

See Licensing for how licences are issued.

The keys most commonly set in production:

RequiredVariable
ASPNETCORE_ENVIRONMENT (Production)
Database__Provider and Database__ConnectionString
JWT_SECRET_KEY
ENCRYPTION_MASTER_KEY
✓ (Postgres)POSTGRES_PASSWORD (must match the password embedded in the connection string)
optionalAI_*
optionalOAUTH_*_CLIENT_ID / _SECRET
optionalKnowledge__ConnectionString + Embeddings__ProviderId (enable the knowledge base)

appsettings.json is committed; .env.prod is not (and should be chmod 600).

Most operator-tunable settings are read via IOptionsMonitor<T> and re-bind on file change — for example, rate limit and quota policies on the /admin/limits page apply immediately.

These settings only take effect after a restart:

  • Database:Provider and ConnectionString
  • Jwt:SecretKey (changing it invalidates all outstanding tokens)
  • Encryption:MasterKey (changing it strands all existing ciphertext — see Encryption at rest)

The admin UI surfaces a banner when a change requires a restart, with a Restart button that delegates to RestartCapability. In environments where a process restart isn’t safe (e.g. a single-replica deployment without a supervising orchestrator), the capability is no-op and the operator must restart the container manually.