Add scoped API key permissions - #273
Conversation
|
👋 Thanks for assigning @tankyleo as a reviewer! |
tankyleo
left a comment
There was a problem hiding this comment.
Quick first pass with codex, haven't validated all of them, particularly not sure about the filesystem sync and the shared encoder points. This last point I have thought about: do we want to have some library that contains common logic across ldk-server and ldk-server-cli for example ?
- [P2] Add the four API-key endpoints to MCP _ ldk-server-mcp/src/tools/mod.rs:70, ldk-server-mcp/tests/integration.rs:14
CreateApiKey, ListApiKeys, RevokeApiKey, and GetPermissions still lack schemas, handlers, registry entries, and expected-tool coverage. This contradicts both the documented MCP workflow and the README_s claim that MCP
exposes the unary RPC surface.
- [P2] Preserve PERMISSION_DENIED in the public client error model _ ldk-server-client/src/client.rs:625
Status 7 and status 16 are both converted to AuthError. Callers therefore cannot programmatically distinguish bad/revoked credentials from a valid but under-scoped key, despite the server and API guide distinguishing
them. Add a client-side authorization/permission error variant and update CLI, MCP, and e2e matches.
- [P2] Avoid filesystem synchronization while holding the authentication write lock _ ldk-server/src/api_keys.rs:198, ldk-server/src/api_keys.rs:236
Create and revoke hold std::sync::RwLock across file writes and sync_all. During a slow fsync, every authentication attempt blocks a Tokio worker on the read lock, potentially stalling the server and preventing gRPC
deadlines from being observed promptly. Serialize management separately, perform disk work through spawn_blocking, and keep the key-map write lock limited to the in-memory commit.
## Smaller cleanup opportunities
- authenticate clones the key ID, name, and complete permission BTreeSet on every RPC. Returning an Arc-backed immutable authenticated record would reduce hot-path allocations.
- The authentication preimage construction is duplicated in client and server. A shared encoder or cross-crate golden test would reduce protocol-drift risk.
- Add the MCP integration steps to the root CONTRIBUTING.md, not only the nested MCP instructions; that omission likely enabled the missed surface.
0c9366f to
c10be2f
Compare
The shared API key gave every client full access and required all clients to rotate credentials when one client's access was revoked. Add separate keys with scoped permissions so each client gets only its required access and can be revoked independently. Manage keys through gRPC and the CLI, and bind signatures to key IDs and RPC methods. AI assistance: OpenAI Codex and Claude Fable 5.1 review.
c3660ee to
3c2d441
Compare
|
rebased and addressed those comments https://github.com/benthecarman/ldk-server/compare/c10be2f..3c2d441 |
tnull
left a comment
There was a problem hiding this comment.
At this point, are we still positive we want to roll our own scheme rather than reimplementing/using macaroons or biscuit? Given this adds quite a bit of complexity and 2k LoC, we could at least consider reusing a proven scheme?
Yeah could do macaroons instead, i could have sworn I opened a pr and we decided against it, but can't find it. I can create that too |
|
opened #276 as an alternative |
Closes #140
The shared API key gave every client full access and required all clients to rotate credentials when one client's access was revoked. Add separate keys with scoped permissions so each client gets only its required access and can be revoked independently.
Manage keys through gRPC and the CLI, and bind signatures to key IDs and RPC methods.