Skip to content

Commit 84a7aaf

Browse files
committed
fix(security): create public view to prevent access_token exposure
- Add github_connections_public view excluding access_token column - Grant SELECT on view to authenticated users - RLS policy still enforces user_id match - Backend continues using service_role for full table access - Adds defense-in-depth against direct table queries
1 parent 0d17e75 commit 84a7aaf

1 file changed

Lines changed: 30 additions & 9 deletions

File tree

supabase/migrations/003_github_connections.sql

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,34 @@ CREATE INDEX IF NOT EXISTS idx_github_connections_user_id ON github_connections(
2323
-- RLS policies
2424
ALTER TABLE github_connections ENABLE ROW LEVEL SECURITY;
2525

26-
-- Users can only check if they have a connection (not read token)
27-
-- Actual token access is done via service_role in backend
28-
CREATE POLICY "Users can view own connection exists" ON github_connections
29-
FOR SELECT USING (auth.uid() = user_id);
30-
31-
-- Users cannot directly insert/update/delete - backend handles this
26+
-- No direct SELECT access for authenticated users on base table
27+
-- This prevents access_token from being exposed
3228
-- Backend uses service_role key which bypasses RLS
3329

30+
-- Create a secure view that excludes sensitive columns
31+
-- This is what frontend/API queries should use for status checks
32+
CREATE OR REPLACE VIEW github_connections_public AS
33+
SELECT
34+
id,
35+
user_id,
36+
github_user_id,
37+
github_username,
38+
github_avatar_url,
39+
token_scope,
40+
connected_at,
41+
last_used_at,
42+
created_at,
43+
updated_at
44+
FROM github_connections;
45+
46+
-- Grant SELECT on the view to authenticated users
47+
-- View inherits RLS from base table, but we add explicit policy
48+
GRANT SELECT ON github_connections_public TO authenticated;
49+
50+
-- RLS policy for the view (checks user_id match)
51+
CREATE POLICY "Users can view own connection via public view" ON github_connections
52+
FOR SELECT USING (auth.uid() = user_id);
53+
3454
-- Function to update updated_at timestamp
3555
CREATE OR REPLACE FUNCTION update_github_connections_updated_at()
3656
RETURNS TRIGGER AS $$
@@ -45,6 +65,7 @@ CREATE TRIGGER github_connections_updated_at
4565
FOR EACH ROW
4666
EXECUTE FUNCTION update_github_connections_updated_at();
4767

48-
-- Comment for documentation
49-
COMMENT ON TABLE github_connections IS 'Stores GitHub OAuth tokens for repo import feature. Tokens are server-side only.';
50-
COMMENT ON COLUMN github_connections.access_token IS 'GitHub OAuth access token. Never exposed to frontend.';
68+
-- Comments for documentation
69+
COMMENT ON TABLE github_connections IS 'Stores GitHub OAuth tokens for repo import. Tokens are server-side only via service_role.';
70+
COMMENT ON COLUMN github_connections.access_token IS 'GitHub OAuth access token. Never exposed to frontend - use github_connections_public view.';
71+
COMMENT ON VIEW github_connections_public IS 'Safe view excluding access_token. Use this for frontend status checks.';

0 commit comments

Comments
 (0)