Fix/mcp fixes and bugs (#518)
* feat(voucher): add create voucher and correct entry previews; update commit methods * feat: add support for pending operations in API key scopes and OAuth client management - Introduced new API key scopes for reading and approving pending operations. - Updated the scope groups to include pending operations. - Added new tools for listing and managing pending operations. - Implemented OAuth client registration and revocation endpoints. - Created a UI panel for managing OAuth clients, including registration and revocation. - Added tests for pending operations tools and OAuth allowlist functionality. - Implemented a database migration for OAuth client registrations with appropriate policies and constraints. * feat: Implement OAuth client registration rate limiting and enhance security measures - Added IP-based rate limiting to the OAuth client registration endpoint to prevent enumeration attacks. - Introduced a service-role client for allowlist lookups, ensuring trust boundaries are maintained. - Updated error responses to be uniform across different types of redirect URI validation failures. - Enhanced tests to reflect changes in OAuth scope handling, ensuring fallback to read-only scopes when no scopes are provided. - Improved handling of high-risk pending operations, requiring explicit confirmation for approvals. - Added audit logging for OAuth client revocations and pending operation approvals/rejections to maintain a security audit trail. - Refactored API key scope management to include default read-only scopes for OAuth-issued keys and added segregation-of-duties checks.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
-- OAuth dynamic client registration allowlist.
|
||||
--
|
||||
-- The /api/mcp-oauth/{register,authorize} endpoints used to hardcode a
|
||||
-- regex allowlist of redirect URIs (claude.ai/api/*, claude.com/api/*,
|
||||
-- localhost). That blocked self-hosted custom apps from completing OAuth
|
||||
-- against gnubok, even though the rest of the flow (PKCE, refresh
|
||||
-- rotation, AES-256-GCM auth codes) is provider-agnostic.
|
||||
--
|
||||
-- This table lets users register their own redirect URIs through the
|
||||
-- settings UI. The hardcoded patterns remain in code as the built-in
|
||||
-- fallback (so Claude continues to work without seeding rows).
|
||||
--
|
||||
-- Defense against open-redirect abuse:
|
||||
-- * exact URI match only (no regex)
|
||||
-- * registration requires owner/admin role (enforced in API route)
|
||||
-- * unique constraint on redirect_uri so two users can't both claim it
|
||||
-- * revoke flips revoked_at instead of deleting (preserves audit trail)
|
||||
CREATE TABLE public.oauth_client_registrations (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES auth.users ON DELETE CASCADE NOT NULL,
|
||||
client_name TEXT NOT NULL,
|
||||
redirect_uri TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
revoked_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
-- Only one active registration per URI. Allows the same URI to be
|
||||
-- re-registered after revocation (partial unique index).
|
||||
CREATE UNIQUE INDEX oauth_client_registrations_uri_active
|
||||
ON public.oauth_client_registrations (redirect_uri)
|
||||
WHERE revoked_at IS NULL;
|
||||
|
||||
CREATE INDEX oauth_client_registrations_user_id_idx
|
||||
ON public.oauth_client_registrations (user_id);
|
||||
|
||||
ALTER TABLE public.oauth_client_registrations ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Users see and manage only their own registrations.
|
||||
CREATE POLICY "oauth_client_registrations_select_own"
|
||||
ON public.oauth_client_registrations FOR SELECT
|
||||
USING (user_id = auth.uid());
|
||||
|
||||
CREATE POLICY "oauth_client_registrations_insert_own"
|
||||
ON public.oauth_client_registrations FOR INSERT
|
||||
WITH CHECK (user_id = auth.uid());
|
||||
|
||||
CREATE POLICY "oauth_client_registrations_update_own"
|
||||
ON public.oauth_client_registrations FOR UPDATE
|
||||
USING (user_id = auth.uid())
|
||||
WITH CHECK (user_id = auth.uid());
|
||||
|
||||
CREATE POLICY "oauth_client_registrations_delete_own"
|
||||
ON public.oauth_client_registrations FOR DELETE
|
||||
USING (user_id = auth.uid());
|
||||
|
||||
CREATE TRIGGER oauth_client_registrations_set_updated_at
|
||||
BEFORE UPDATE ON public.oauth_client_registrations
|
||||
FOR EACH ROW EXECUTE FUNCTION public.update_updated_at_column();
|
||||
|
||||
NOTIFY pgrst, 'reload schema';
|
||||
Reference in New Issue
Block a user