
Security model
Scope-driven. Audited. Secure.
Every access — whether via REST API or MCP — runs through the same scope check. No scope, no access. Every action lands in the audit log.
Authentication
Authorization: Bearer <key> header. Every route is mapped to a module and checks the corresponding scope.OAuth MCP clients receive a short-lived access_token (default 30 min) and a rotating refresh_token (default 30 days) on every authorization-code exchange. The refresh token rotates on use; replaying a consumed token revokes the entire token family. Scope widening on refresh is rejected.
Clients that publish a Client ID Metadata Document (CIMD) can pass the document’s HTTPS URL as client_id instead of registering via Dynamic Client Registration. LedgerLou fetches the document once (5 s timeout, 256 KiB cap, SSRF-guarded, validated against a Zod schema), caches it for 24 h, and honors ETag-based conditional re-fetches. The admin superscope and config:* scopes are never granted to CIMD clients — the document’s scope string is intersected with the OAuth-available module scopes.
Scopes
Scopes follow the format module:action. A key carries only the scopes it explicitly needs — no default access to everything.
journal | bank | kreditoren | perioden | auswertungen | config | |
|---|---|---|---|---|---|---|
:read | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
:write | ✓ | ✓ | ✓ | ✓ | — | ✓ |
admin | Global superscope — covers every module/action combination | |||||
✓ REST API and Dashboard only — config:* is not available via MCP.