diff --git a/cmd/server/app/migrate_up.go b/cmd/server/app/migrate_up.go
index 900cf9911e..bd0a309961 100644
--- a/cmd/server/app/migrate_up.go
+++ b/cmd/server/app/migrate_up.go
@@ -31,7 +31,6 @@ import (
 
 	"github.com/stacklok/minder/internal/authz"
 	serverconfig "github.com/stacklok/minder/internal/config/server"
-	"github.com/stacklok/minder/internal/db"
 	"github.com/stacklok/minder/internal/logger"
 )
 
@@ -127,55 +126,10 @@ var upCmd = &cobra.Command{
 			return fmt.Errorf("error preparing authz client: %w", err)
 		}
 
-		store := db.NewStore(dbConn)
-		if err := migratePermsToFGA(ctx, store, authzw, cmd); err != nil {
-			return fmt.Errorf("error while migrating permissions to FGA: %w", err)
-		}
-
 		return nil
 	},
 }
 
-func migratePermsToFGA(ctx context.Context, store db.Store, authzw authz.Client, cmd *cobra.Command) error {
-	cmd.Println("Migrating permissions to FGA...")
-
-	var i int32 = 0
-	for {
-		userList, err := store.ListUsers(ctx, db.ListUsersParams{Limit: 100, Offset: i})
-		if err != nil {
-			return fmt.Errorf("error while listing users: %w", err)
-		}
-		i = i + 100
-		cmd.Printf("Found %d users to migrate\n", len(userList))
-		if len(userList) == 0 {
-			break
-		}
-
-		for _, user := range userList {
-			projs, err := store.GetUserProjects(ctx, user.ID)
-			if err != nil {
-				cmd.Printf("Skipping user %d since getting user projects yielded error: %s\n",
-					user.ID, err)
-				continue
-			}
-
-			for _, proj := range projs {
-				cmd.Printf("Migrating user to FGA for project %s\n", proj.ProjectID)
-				if err := authzw.Write(
-					ctx, user.IdentitySubject, authz.AuthzRoleAdmin, proj.ProjectID,
-				); err != nil {
-					cmd.Printf("Error while writing permission for user %d: %s\n", user.ID, err)
-					continue
-				}
-			}
-		}
-	}
-
-	cmd.Println("Done migrating permissions to FGA")
-
-	return nil
-}
-
 func init() {
 	migrateCmd.AddCommand(upCmd)
 }
diff --git a/database/migrations/000016_remove_user_project.down.sql b/database/migrations/000016_remove_user_project.down.sql
new file mode 100644
index 0000000000..4762dc43d2
--- /dev/null
+++ b/database/migrations/000016_remove_user_project.down.sql
@@ -0,0 +1,20 @@
+-- Copyright 2024 Stacklok, Inc
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--      http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- user/projects
+CREATE TABLE user_projects (
+    id SERIAL PRIMARY KEY,
+    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
+    project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE
+);
\ No newline at end of file
diff --git a/database/migrations/000016_remove_user_project.up.sql b/database/migrations/000016_remove_user_project.up.sql
new file mode 100644
index 0000000000..440149bca4
--- /dev/null
+++ b/database/migrations/000016_remove_user_project.up.sql
@@ -0,0 +1,15 @@
+-- Copyright 2024 Stacklok, Inc
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--      http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP TABLE IF EXISTS user_projects;
\ No newline at end of file
diff --git a/database/mock/store.go b/database/mock/store.go
index 08f58f81c6..83dda02a59 100644
--- a/database/mock/store.go
+++ b/database/mock/store.go
@@ -38,21 +38,6 @@ func (m *MockStore) EXPECT() *MockStoreMockRecorder {
 	return m.recorder
 }
 
-// AddUserProject mocks base method.
-func (m *MockStore) AddUserProject(arg0 context.Context, arg1 db.AddUserProjectParams) (db.UserProject, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AddUserProject", arg0, arg1)
-	ret0, _ := ret[0].(db.UserProject)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// AddUserProject indicates an expected call of AddUserProject.
-func (mr *MockStoreMockRecorder) AddUserProject(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUserProject", reflect.TypeOf((*MockStore)(nil).AddUserProject), arg0, arg1)
-}
-
 // BeginTransaction mocks base method.
 func (m *MockStore) BeginTransaction() (*sql.Tx, error) {
 	m.ctrl.T.Helper()
@@ -1293,21 +1278,6 @@ func (mr *MockStoreMockRecorder) GetUserBySubject(arg0, arg1 interface{}) *gomoc
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserBySubject", reflect.TypeOf((*MockStore)(nil).GetUserBySubject), arg0, arg1)
 }
 
-// GetUserProjects mocks base method.
-func (m *MockStore) GetUserProjects(arg0 context.Context, arg1 int32) ([]db.GetUserProjectsRow, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetUserProjects", arg0, arg1)
-	ret0, _ := ret[0].([]db.GetUserProjectsRow)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetUserProjects indicates an expected call of GetUserProjects.
-func (mr *MockStoreMockRecorder) GetUserProjects(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserProjects", reflect.TypeOf((*MockStore)(nil).GetUserProjects), arg0, arg1)
-}
-
 // GlobalListProviders mocks base method.
 func (m *MockStore) GlobalListProviders(arg0 context.Context) ([]db.Provider, error) {
 	m.ctrl.T.Helper()
@@ -1563,21 +1533,6 @@ func (mr *MockStoreMockRecorder) ListUsersByOrganization(arg0, arg1 interface{})
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListUsersByOrganization", reflect.TypeOf((*MockStore)(nil).ListUsersByOrganization), arg0, arg1)
 }
 
-// ListUsersByProject mocks base method.
-func (m *MockStore) ListUsersByProject(arg0 context.Context, arg1 db.ListUsersByProjectParams) ([]db.User, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ListUsersByProject", arg0, arg1)
-	ret0, _ := ret[0].([]db.User)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ListUsersByProject indicates an expected call of ListUsersByProject.
-func (mr *MockStoreMockRecorder) ListUsersByProject(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListUsersByProject", reflect.TypeOf((*MockStore)(nil).ListUsersByProject), arg0, arg1)
-}
-
 // LockIfThresholdNotExceeded mocks base method.
 func (m *MockStore) LockIfThresholdNotExceeded(arg0 context.Context, arg1 db.LockIfThresholdNotExceededParams) (db.EntityExecutionLock, error) {
 	m.ctrl.T.Helper()
diff --git a/database/query/user_projects.sql b/database/query/user_projects.sql
deleted file mode 100644
index 3341d879a9..0000000000
--- a/database/query/user_projects.sql
+++ /dev/null
@@ -1,10 +0,0 @@
--- name: AddUserProject :one
-INSERT INTO user_projects (
-  user_id,
-  project_id
-    ) VALUES (
-        $1, $2
-) RETURNING *;
-
--- name: GetUserProjects :many
-SELECT * FROM projects INNER JOIN user_projects ON projects.id = user_projects.project_id WHERE user_projects.user_id = $1;
\ No newline at end of file
diff --git a/database/query/users.sql b/database/query/users.sql
index 5d06c56da5..2161542c0a 100644
--- a/database/query/users.sql
+++ b/database/query/users.sql
@@ -23,13 +23,5 @@ ORDER BY id
 LIMIT $2
 OFFSET $3;
 
--- name: ListUsersByProject :many
-SELECT users.* FROM users
-JOIN user_projects ON users.id = user_projects.user_id
-WHERE user_projects.project_id = $1
-ORDER BY users.id
-LIMIT $2
-OFFSET $3;
-
 -- name: CountUsers :one
 SELECT COUNT(*) FROM users;
diff --git a/internal/authz/authz.go b/internal/authz/authz.go
index acacc0efd1..14459aa3d6 100644
--- a/internal/authz/authz.go
+++ b/internal/authz/authz.go
@@ -377,6 +377,53 @@ func (a *ClientWrapper) AssignmentsToProject(ctx context.Context, project uuid.U
 	return assignments, nil
 }
 
+// ProjectsForUser lists the projects that the given user has access to
+func (a *ClientWrapper) ProjectsForUser(ctx context.Context, sub string) ([]uuid.UUID, error) {
+	u := getUserForTuple(sub)
+
+	var pagesize int32 = 50
+	var contTok *string = nil
+
+	projs := map[string]any{}
+	projectObj := "project:"
+
+	for {
+		resp, err := a.cli.Read(ctx).Options(fgaclient.ClientReadOptions{
+			PageSize:          &pagesize,
+			ContinuationToken: contTok,
+		}).Body(fgaclient.ClientReadRequest{
+			User:   &u,
+			Object: &projectObj,
+		}).Execute()
+		if err != nil {
+			return nil, fmt.Errorf("unable to read authorization tuples: %w", err)
+		}
+
+		for _, t := range resp.GetTuples() {
+			k := t.GetKey()
+
+			projs[k.GetObject()] = struct{}{}
+		}
+
+		if resp.GetContinuationToken() == "" {
+			break
+		}
+
+		contTok = &resp.ContinuationToken
+	}
+
+	out := []uuid.UUID{}
+	for proj := range projs {
+		u, err := uuid.Parse(getProjectFromTuple(proj))
+		if err != nil {
+			continue
+		}
+		out = append(out, u)
+	}
+
+	return out, nil
+}
+
 func getUserForTuple(user string) string {
 	return "user:" + user
 }
@@ -388,3 +435,7 @@ func getProjectForTuple(project uuid.UUID) string {
 func getUserFromTuple(user string) string {
 	return strings.TrimPrefix(user, "user:")
 }
+
+func getProjectFromTuple(project string) string {
+	return strings.TrimPrefix(project, "project:")
+}
diff --git a/internal/authz/interface.go b/internal/authz/interface.go
index c2cfad2824..694dfa08ad 100644
--- a/internal/authz/interface.go
+++ b/internal/authz/interface.go
@@ -98,6 +98,9 @@ type Client interface {
 	// AssignmentsToProject outputs the existing role assignments for a given project.
 	AssignmentsToProject(ctx context.Context, project uuid.UUID) ([]*minderv1.RoleAssignment, error)
 
+	// ProjectsForUser outputs the projects a user has access to.
+	ProjectsForUser(ctx context.Context, sub string) ([]uuid.UUID, error)
+
 	// PrepareForRun allows for any preflight configurations to be done before
 	// the server is started.
 	PrepareForRun(ctx context.Context) error
diff --git a/internal/authz/mock/noop_authz.go b/internal/authz/mock/noop_authz.go
index 0e3b45a4cb..45803b3de0 100644
--- a/internal/authz/mock/noop_authz.go
+++ b/internal/authz/mock/noop_authz.go
@@ -64,6 +64,11 @@ func (_ *NoopClient) AssignmentsToProject(_ context.Context, _ uuid.UUID) ([]*mi
 	return nil, nil
 }
 
+// ProjectsForUser implements authz.Client
+func (_ *NoopClient) ProjectsForUser(_ context.Context, _ string) ([]uuid.UUID, error) {
+	return nil, nil
+}
+
 // PrepareForRun implements authz.Client
 func (_ *NoopClient) PrepareForRun(_ context.Context) error {
 	return nil
diff --git a/internal/authz/mock/simple_authz.go b/internal/authz/mock/simple_authz.go
index 865871d962..74ea607585 100644
--- a/internal/authz/mock/simple_authz.go
+++ b/internal/authz/mock/simple_authz.go
@@ -64,7 +64,12 @@ func (_ *SimpleClient) DeleteUser(_ context.Context, _ string) error {
 
 // AssignmentsToProject implements authz.Client
 func (_ *SimpleClient) AssignmentsToProject(_ context.Context, _ uuid.UUID) ([]*minderv1.RoleAssignment, error) {
-	return nil, nil
+	return []*minderv1.RoleAssignment{}, nil
+}
+
+// ProjectsForUser implements authz.Client
+func (n *SimpleClient) ProjectsForUser(_ context.Context, _ string) ([]uuid.UUID, error) {
+	return n.Allowed, nil
 }
 
 // PrepareForRun implements authz.Client
diff --git a/internal/controlplane/handlers_authz.go b/internal/controlplane/handlers_authz.go
index c6fe6df1e0..b97774edf6 100644
--- a/internal/controlplane/handlers_authz.go
+++ b/internal/controlplane/handlers_authz.go
@@ -67,7 +67,7 @@ func EntityContextProjectInterceptor(ctx context.Context, req interface{}, info
 
 	server := info.Server.(*Server)
 
-	ctx, err := populateEntityContext(ctx, server.store, request)
+	ctx, err := populateEntityContext(ctx, server.store, server.authzClient, request)
 	if err != nil {
 		return nil, err
 	}
@@ -112,12 +112,17 @@ func ProjectAuthorizationInterceptor(ctx context.Context, req interface{}, info
 
 // populateEntityContext populates the project in the entity context, by looking at the proto context or
 // fetching the default project
-func populateEntityContext(ctx context.Context, store db.Store, in HasProtoContext) (context.Context, error) {
+func populateEntityContext(
+	ctx context.Context,
+	store db.Store,
+	authzClient authz.Client,
+	in HasProtoContext,
+) (context.Context, error) {
 	if in.GetContext() == nil {
 		return ctx, fmt.Errorf("context cannot be nil")
 	}
 
-	projectID, err := getProjectFromRequestOrDefault(ctx, store, in)
+	projectID, err := getProjectFromRequestOrDefault(ctx, store, authzClient, in)
 	if err != nil {
 		return ctx, err
 	}
@@ -137,7 +142,12 @@ func populateEntityContext(ctx context.Context, store db.Store, in HasProtoConte
 	return engine.WithEntityContext(ctx, entityCtx), nil
 }
 
-func getProjectFromRequestOrDefault(ctx context.Context, store db.Store, in HasProtoContext) (uuid.UUID, error) {
+func getProjectFromRequestOrDefault(
+	ctx context.Context,
+	store db.Store,
+	authzClient authz.Client,
+	in HasProtoContext,
+) (uuid.UUID, error) {
 	// Prefer the context message from the protobuf
 	if in.GetContext().GetProject() != "" {
 		requestedProject := in.GetContext().GetProject()
@@ -152,17 +162,25 @@ func getProjectFromRequestOrDefault(ctx context.Context, store db.Store, in HasP
 
 	userInfo, err := store.GetUserBySubject(ctx, subject)
 	if err != nil {
-		return uuid.UUID{}, status.Errorf(codes.NotFound, "user not found")
+		// Note that we're revealing that the user is not registered in minder
+		// since the caller has a valid token (this is checked in earlier middleware).
+		// Therefore, we assume it's safe output that the user is not found.
+		return uuid.UUID{}, util.UserVisibleError(codes.NotFound, "user not found")
 	}
-	projects, err := store.GetUserProjects(ctx, userInfo.ID)
+	projects, err := authzClient.ProjectsForUser(ctx, userInfo.IdentitySubject)
 	if err != nil {
-		return uuid.UUID{}, status.Errorf(codes.NotFound, "cannot find projects for user")
+		return uuid.UUID{}, status.Errorf(codes.Internal, "cannot find projects for user")
+	}
+
+	if len(projects) == 0 {
+		return uuid.UUID{}, util.UserVisibleError(codes.PermissionDenied, "User has no role grants in projects")
 	}
 
 	if len(projects) != 1 {
-		return uuid.UUID{}, status.Errorf(codes.InvalidArgument, "cannot get default project")
+		return uuid.UUID{}, util.UserVisibleError(codes.PermissionDenied, "Cannot determine default project. Please specify one.")
 	}
-	return projects[0].ID, nil
+
+	return projects[0], nil
 }
 
 // Permissions API
diff --git a/internal/controlplane/handlers_authz_test.go b/internal/controlplane/handlers_authz_test.go
index f9e5b235ef..3f0f9f38da 100644
--- a/internal/controlplane/handlers_authz_test.go
+++ b/internal/controlplane/handlers_authz_test.go
@@ -21,6 +21,7 @@ import (
 	"github.com/golang/mock/gomock"
 	"github.com/google/uuid"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
@@ -64,8 +65,9 @@ func TestEntityContextProjectInterceptor(t *testing.T) {
 		name            string
 		req             any
 		resource        minder.TargetResource
-		buildStubs      func(store *mockdb.MockStore)
+		buildStubs      func(t *testing.T, store *mockdb.MockStore)
 		rpcErr          error
+		defaultProject  bool
 		expectedContext engine.EntityContext // Only if non-error
 	}{
 		{
@@ -102,18 +104,15 @@ func TestEntityContextProjectInterceptor(t *testing.T) {
 			req: &request{
 				Context: &minder.Context{},
 			},
-			resource: minder.TargetResource_TARGET_RESOURCE_PROJECT,
-			buildStubs: func(store *mockdb.MockStore) {
+			resource:       minder.TargetResource_TARGET_RESOURCE_PROJECT,
+			defaultProject: true,
+			buildStubs: func(t *testing.T, store *mockdb.MockStore) {
+				t.Helper()
 				store.EXPECT().
 					GetUserBySubject(gomock.Any(), subject).
 					Return(db.User{
 						ID: 1,
 					}, nil)
-				store.EXPECT().
-					GetUserProjects(gomock.Any(), gomock.Any()).
-					Return([]db.GetUserProjectsRow{{
-						ID: defaultProjectID,
-					}}, nil)
 			},
 			expectedContext: engine.EntityContext{
 				// Uses the default project id
@@ -164,11 +163,21 @@ func TestEntityContextProjectInterceptor(t *testing.T) {
 
 			mockStore := mockdb.NewMockStore(ctrl)
 			if tc.buildStubs != nil {
-				tc.buildStubs(mockStore)
+				tc.buildStubs(t, mockStore)
 			}
 			ctx := auth.WithUserSubjectContext(withRpcOptions(context.Background(), rpcOptions), subject)
+
+			authzClient := &mock.SimpleClient{}
+
+			if tc.defaultProject {
+				authzClient.Allowed = []uuid.UUID{defaultProjectID}
+			} else {
+				authzClient.Allowed = []uuid.UUID{projectID}
+			}
+
 			server := Server{
-				store: mockStore,
+				store:       mockStore,
+				authzClient: authzClient,
 			}
 			reply, err := EntityContextProjectInterceptor(ctx, tc.req, &grpc.UnaryServerInfo{
 				Server: &server,
@@ -177,10 +186,8 @@ func TestEntityContextProjectInterceptor(t *testing.T) {
 				assert.Equal(t, tc.rpcErr, err)
 				return
 			}
-			if err != nil {
-				t.Fatalf("unexpected error: %v", err)
-			}
 
+			require.NoError(t, err, "expected no error")
 			assert.Equal(t, tc.expectedContext, reply.(replyType).Context)
 		})
 	}
diff --git a/internal/controlplane/handlers_user.go b/internal/controlplane/handlers_user.go
index 5871140823..64f2a9738e 100644
--- a/internal/controlplane/handlers_user.go
+++ b/internal/controlplane/handlers_user.go
@@ -101,11 +101,6 @@ func (s *Server) CreateUser(ctx context.Context,
 		return nil, status.Errorf(codes.Internal, "failed to create user: %s", err)
 	}
 
-	_, err = qtx.AddUserProject(ctx, db.AddUserProjectParams{UserID: user.ID, ProjectID: userProject})
-	if err != nil {
-		return nil, status.Errorf(codes.Internal, "failed to add user to project: %s", err)
-	}
-
 	err = s.store.Commit(tx)
 	if err != nil {
 		return nil, status.Errorf(codes.Internal, "failed to commit transaction: %s", err)
@@ -189,20 +184,25 @@ func (s *Server) DeleteUser(ctx context.Context,
 	return &pb.DeleteUserResponse{}, nil
 }
 
-func getUserDependencies(ctx context.Context, store db.Store, user db.User) ([]*pb.Project, error) {
+func (s *Server) getUserDependencies(ctx context.Context, user db.User) ([]*pb.Project, error) {
 	// get all the projects associated with that user
-	projects, err := store.GetUserProjects(ctx, user.ID)
+	projects, err := s.authzClient.ProjectsForUser(ctx, user.IdentitySubject)
 	if err != nil {
 		return nil, err
 	}
 
 	var projectsPB []*pb.Project
 	for _, proj := range projects {
+		pinfo, err := s.store.GetProjectByID(ctx, proj)
+		if err != nil {
+			return nil, err
+		}
+
 		projectsPB = append(projectsPB, &pb.Project{
-			ProjectId: proj.ID.String(),
-			Name:      proj.Name,
-			CreatedAt: timestamppb.New(proj.CreatedAt),
-			UpdatedAt: timestamppb.New(proj.UpdatedAt),
+			ProjectId: proj.String(),
+			Name:      pinfo.Name,
+			CreatedAt: timestamppb.New(pinfo.CreatedAt),
+			UpdatedAt: timestamppb.New(pinfo.UpdatedAt),
 		})
 	}
 
@@ -240,7 +240,7 @@ func (s *Server) GetUser(ctx context.Context, _ *pb.GetUserRequest) (*pb.GetUser
 		UpdatedAt:       timestamppb.New(user.UpdatedAt),
 	}
 
-	projects, err := getUserDependencies(ctx, s.store, user)
+	projects, err := s.getUserDependencies(ctx, user)
 	if err != nil {
 		return nil, status.Errorf(codes.Unknown, "failed to get user dependencies: %s", err)
 	}
diff --git a/internal/controlplane/handlers_user_test.go b/internal/controlplane/handlers_user_test.go
index 1f34055757..c51f3bafd7 100644
--- a/internal/controlplane/handlers_user_test.go
+++ b/internal/controlplane/handlers_user_test.go
@@ -91,7 +91,6 @@ func TestCreateUserDBMock(t *testing.T) {
 					CreateUser(gomock.Any(), db.CreateUserParams{OrganizationID: orgID,
 						IdentitySubject: "subject1"}).
 					Return(returnedUser, nil)
-				store.EXPECT().AddUserProject(gomock.Any(), db.AddUserProjectParams{UserID: 1, ProjectID: projectID})
 				store.EXPECT().Commit(gomock.Any())
 				store.EXPECT().Rollback(gomock.Any())
 				tokenResult, _ := openid.NewBuilder().GivenName("Foo").FamilyName("Bar").Email("test@stacklok.com").Subject("subject1").Build()
@@ -185,7 +184,6 @@ func TestCreateUser_gRPC(t *testing.T) {
 						UpdatedAt:      time.Now(),
 					}, nil).
 					Times(1)
-				store.EXPECT().AddUserProject(gomock.Any(), db.AddUserProjectParams{UserID: 1, ProjectID: projectID})
 				store.EXPECT().Commit(gomock.Any())
 				store.EXPECT().Rollback(gomock.Any())
 				jwt.EXPECT().ParseAndValidate(gomock.Any()).Return(openid.New(), nil)
diff --git a/internal/db/models.go b/internal/db/models.go
index 169a9e8133..839e0cc7eb 100644
--- a/internal/db/models.go
+++ b/internal/db/models.go
@@ -493,9 +493,3 @@ type User struct {
 	CreatedAt       time.Time `json:"created_at"`
 	UpdatedAt       time.Time `json:"updated_at"`
 }
-
-type UserProject struct {
-	ID        int32     `json:"id"`
-	UserID    int32     `json:"user_id"`
-	ProjectID uuid.UUID `json:"project_id"`
-}
diff --git a/internal/db/querier.go b/internal/db/querier.go
index da78332a14..0232f76bd9 100644
--- a/internal/db/querier.go
+++ b/internal/db/querier.go
@@ -12,7 +12,6 @@ import (
 )
 
 type Querier interface {
-	AddUserProject(ctx context.Context, arg AddUserProjectParams) (UserProject, error)
 	CountProfilesByEntityType(ctx context.Context) ([]CountProfilesByEntityTypeRow, error)
 	CountProfilesByName(ctx context.Context, name string) (int64, error)
 	CountRepositories(ctx context.Context) (int64, error)
@@ -96,7 +95,6 @@ type Querier interface {
 	GetSessionStateByProjectID(ctx context.Context, projectID uuid.UUID) (SessionStore, error)
 	GetUserByID(ctx context.Context, id int32) (User, error)
 	GetUserBySubject(ctx context.Context, identitySubject string) (User, error)
-	GetUserProjects(ctx context.Context, userID int32) ([]GetUserProjectsRow, error)
 	GlobalListProviders(ctx context.Context) ([]Provider, error)
 	ListAllRepositories(ctx context.Context, provider string) ([]Repository, error)
 	ListArtifactVersionsByArtifactID(ctx context.Context, arg ListArtifactVersionsByArtifactIDParams) ([]ArtifactVersion, error)
@@ -117,7 +115,6 @@ type Querier interface {
 	ListRuleTypesByProviderAndProject(ctx context.Context, arg ListRuleTypesByProviderAndProjectParams) ([]RuleType, error)
 	ListUsers(ctx context.Context, arg ListUsersParams) ([]User, error)
 	ListUsersByOrganization(ctx context.Context, arg ListUsersByOrganizationParams) ([]User, error)
-	ListUsersByProject(ctx context.Context, arg ListUsersByProjectParams) ([]User, error)
 	// LockIfThresholdNotExceeded is used to lock an entity for execution. It will
 	// attempt to insert or update the entity_execution_lock table only if the
 	// last_lock_time is older than the threshold. If the lock is successful, it
diff --git a/internal/db/user_projects.sql.go b/internal/db/user_projects.sql.go
deleted file mode 100644
index f774def6d9..0000000000
--- a/internal/db/user_projects.sql.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Code generated by sqlc. DO NOT EDIT.
-// versions:
-//   sqlc v1.25.0
-// source: user_projects.sql
-
-package db
-
-import (
-	"context"
-	"encoding/json"
-	"time"
-
-	"github.com/google/uuid"
-)
-
-const addUserProject = `-- name: AddUserProject :one
-INSERT INTO user_projects (
-  user_id,
-  project_id
-    ) VALUES (
-        $1, $2
-) RETURNING id, user_id, project_id
-`
-
-type AddUserProjectParams struct {
-	UserID    int32     `json:"user_id"`
-	ProjectID uuid.UUID `json:"project_id"`
-}
-
-func (q *Queries) AddUserProject(ctx context.Context, arg AddUserProjectParams) (UserProject, error) {
-	row := q.db.QueryRowContext(ctx, addUserProject, arg.UserID, arg.ProjectID)
-	var i UserProject
-	err := row.Scan(&i.ID, &i.UserID, &i.ProjectID)
-	return i, err
-}
-
-const getUserProjects = `-- name: GetUserProjects :many
-SELECT projects.id, name, is_organization, metadata, parent_id, created_at, updated_at, user_projects.id, user_id, project_id FROM projects INNER JOIN user_projects ON projects.id = user_projects.project_id WHERE user_projects.user_id = $1
-`
-
-type GetUserProjectsRow struct {
-	ID             uuid.UUID       `json:"id"`
-	Name           string          `json:"name"`
-	IsOrganization bool            `json:"is_organization"`
-	Metadata       json.RawMessage `json:"metadata"`
-	ParentID       uuid.NullUUID   `json:"parent_id"`
-	CreatedAt      time.Time       `json:"created_at"`
-	UpdatedAt      time.Time       `json:"updated_at"`
-	ID_2           int32           `json:"id_2"`
-	UserID         int32           `json:"user_id"`
-	ProjectID      uuid.UUID       `json:"project_id"`
-}
-
-func (q *Queries) GetUserProjects(ctx context.Context, userID int32) ([]GetUserProjectsRow, error) {
-	rows, err := q.db.QueryContext(ctx, getUserProjects, userID)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	items := []GetUserProjectsRow{}
-	for rows.Next() {
-		var i GetUserProjectsRow
-		if err := rows.Scan(
-			&i.ID,
-			&i.Name,
-			&i.IsOrganization,
-			&i.Metadata,
-			&i.ParentID,
-			&i.CreatedAt,
-			&i.UpdatedAt,
-			&i.ID_2,
-			&i.UserID,
-			&i.ProjectID,
-		); err != nil {
-			return nil, err
-		}
-		items = append(items, i)
-	}
-	if err := rows.Close(); err != nil {
-		return nil, err
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return items, nil
-}
diff --git a/internal/db/users.sql.go b/internal/db/users.sql.go
index 8d9a81dfbd..befa2a569f 100644
--- a/internal/db/users.sql.go
+++ b/internal/db/users.sql.go
@@ -170,47 +170,3 @@ func (q *Queries) ListUsersByOrganization(ctx context.Context, arg ListUsersByOr
 	}
 	return items, nil
 }
-
-const listUsersByProject = `-- name: ListUsersByProject :many
-SELECT users.id, users.organization_id, users.identity_subject, users.created_at, users.updated_at FROM users
-JOIN user_projects ON users.id = user_projects.user_id
-WHERE user_projects.project_id = $1
-ORDER BY users.id
-LIMIT $2
-OFFSET $3
-`
-
-type ListUsersByProjectParams struct {
-	ProjectID uuid.UUID `json:"project_id"`
-	Limit     int32     `json:"limit"`
-	Offset    int32     `json:"offset"`
-}
-
-func (q *Queries) ListUsersByProject(ctx context.Context, arg ListUsersByProjectParams) ([]User, error) {
-	rows, err := q.db.QueryContext(ctx, listUsersByProject, arg.ProjectID, arg.Limit, arg.Offset)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	items := []User{}
-	for rows.Next() {
-		var i User
-		if err := rows.Scan(
-			&i.ID,
-			&i.OrganizationID,
-			&i.IdentitySubject,
-			&i.CreatedAt,
-			&i.UpdatedAt,
-		); err != nil {
-			return nil, err
-		}
-		items = append(items, i)
-	}
-	if err := rows.Close(); err != nil {
-		return nil, err
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return items, nil
-}