docs: add TOML config file design
This commit is contained in:
parent
c726ae18d3
commit
edeb036086
1 changed files with 84 additions and 0 deletions
84
docs/plans/2026-02-18-config-file-design.md
Normal file
84
docs/plans/2026-02-18-config-file-design.md
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# TOML Configuration File Design
|
||||
|
||||
**Date:** 2026-02-18
|
||||
**Status:** Approved
|
||||
|
||||
## Goal
|
||||
|
||||
Add a TOML configuration file to Porchlight so that server settings and OIDC
|
||||
client registrations can be defined in a file. Environment variables retain
|
||||
highest priority and override any file-based values.
|
||||
|
||||
## Decisions
|
||||
|
||||
| Decision | Choice | Rationale |
|
||||
|---|---|---|
|
||||
| File format | TOML | Human-friendly, supports comments, stdlib `tomllib` on 3.11+ |
|
||||
| Integration | pydantic-settings `TomlConfigSettingsSource` | Already available in pydantic-settings 2.12, handles precedence natively |
|
||||
| Default path | `porchlight.toml` in CWD | Simple convention, overridable via `OIDC_OP_CONFIG_FILE` |
|
||||
| Missing file | Silently skip | Env vars and defaults still work — file is optional |
|
||||
| Scope | Server settings + client registrations in one file | Single source of truth |
|
||||
|
||||
## Precedence
|
||||
|
||||
```
|
||||
env vars > TOML file > defaults
|
||||
```
|
||||
|
||||
pydantic-settings handles this via `settings_customise_sources()`.
|
||||
|
||||
## Example porchlight.toml
|
||||
|
||||
```toml
|
||||
issuer = "https://auth.example.com"
|
||||
debug = false
|
||||
session_secret = "a-long-random-string"
|
||||
sqlite_path = "data/porchlight.db"
|
||||
signing_key_path = "data/keys"
|
||||
invite_ttl = 86400
|
||||
|
||||
[clients.my-webapp]
|
||||
client_secret = "super-secret-value"
|
||||
redirect_uris = ["https://app.example.com/callback"]
|
||||
response_types = ["code"]
|
||||
scope = ["openid", "profile", "email"]
|
||||
token_endpoint_auth_method = "client_secret_basic"
|
||||
|
||||
[clients.another-app]
|
||||
client_secret = "another-secret"
|
||||
redirect_uris = ["https://other.example.com/oidc/callback"]
|
||||
response_types = ["code"]
|
||||
scope = ["openid", "profile"]
|
||||
token_endpoint_auth_method = "client_secret_basic"
|
||||
```
|
||||
|
||||
## Code Changes
|
||||
|
||||
### config.py
|
||||
|
||||
- Add `ClientConfig(BaseModel)` with fields: `client_secret`, `redirect_uris`,
|
||||
`response_types` (default `["code"]`), `scope` (default `["openid"]`),
|
||||
`token_endpoint_auth_method` (default `"client_secret_basic"`).
|
||||
- Add `config_file: str = "porchlight.toml"` field to `Settings`.
|
||||
- Add `clients: dict[str, ClientConfig] = {}` field to `Settings`.
|
||||
- Override `settings_customise_sources()` to insert `TomlConfigSettingsSource`
|
||||
between env and defaults. Use `config_file` field as the TOML path.
|
||||
|
||||
### app.py
|
||||
|
||||
- After creating the OIDC server, loop over `settings.clients` and register
|
||||
each client in `oidc_server.context.cdb`.
|
||||
- Keep the internal `manage-app` client registration as-is (always registered
|
||||
regardless of config file).
|
||||
|
||||
### cli.py
|
||||
|
||||
- No changes. `Settings()` picks up the TOML file automatically.
|
||||
|
||||
## What Stays the Same
|
||||
|
||||
- All existing `OIDC_OP_*` env vars work identically.
|
||||
- `Settings()` call sites unchanged.
|
||||
- Docker/compose env var configuration unchanged.
|
||||
- No new dependencies (pydantic-settings 2.12 already has TOML support,
|
||||
Python 3.13 has `tomllib` in stdlib).
|
||||
Loading…
Add table
Add a link
Reference in a new issue