From 2b2a5c963a5b7f7bbaa869b31eafb5892b2cf4df Mon Sep 17 00:00:00 2001 From: Atif Ali Date: Tue, 21 Jul 2026 21:17:27 +0500 Subject: [PATCH] Revert "fix(coderd): explain default GitHub app org visibility on login rejection" (#27388) --- cli/server.go | 14 ++------ coderd/userauth.go | 27 ---------------- coderd/userauth_test.go | 57 --------------------------------- docs/admin/users/github-auth.md | 5 --- 4 files changed, 2 insertions(+), 101 deletions(-) diff --git a/cli/server.go b/cli/server.go index 1002966e1f..dfd2db1dca 100644 --- a/cli/server.go +++ b/cli/server.go @@ -1006,7 +1006,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. } options.WebPushDispatcher = webpusher - githubOAuth2ConfigParams, err := getGithubOAuth2ConfigParams(ctx, options.Logger, options.Database, vals) + githubOAuth2ConfigParams, err := getGithubOAuth2ConfigParams(ctx, options.Database, vals) if err != nil { return xerrors.Errorf("get github oauth2 config params: %w", err) } @@ -2213,7 +2213,7 @@ func maybeAppendDefaultGithubExternalAuthProvider( }), nil } -func getGithubOAuth2ConfigParams(ctx context.Context, logger slog.Logger, db database.Store, vals *codersdk.DeploymentValues) (*githubOAuth2ConfigParams, error) { +func getGithubOAuth2ConfigParams(ctx context.Context, db database.Store, vals *codersdk.DeploymentValues) (*githubOAuth2ConfigParams, error) { params := githubOAuth2ConfigParams{ accessURL: vals.AccessURL.Value(), clientID: vals.OAuth2.Github.ClientID.String(), @@ -2250,16 +2250,6 @@ func getGithubOAuth2ConfigParams(ctx context.Context, logger slog.Logger, db dat params.deviceFlow = GithubOAuth2DefaultProviderDeviceFlow if len(params.allowOrgs) == 0 { params.allowEveryone = GithubOAuth2DefaultProviderAllowEveryone - } else { - // The default provider is a GitHub App, which can only see memberships - // in organizations that have installed it. If the app isn't installed - // in an allowed organization, every login from that organization is - // rejected as "not a member". - logger.Warn(ctx, "the default GitHub OAuth provider can only see memberships in organizations that have installed the Coder GitHub app; "+ - "users cannot log in until the app is installed in each allowed organization, or a custom GitHub OAuth app is configured", - slog.F("allowed_orgs", params.allowOrgs), - slog.F("install_url", coderd.GithubOAuth2DefaultProviderInstallURL), - ) } return ¶ms, nil diff --git a/coderd/userauth.go b/coderd/userauth.go index 24bb95b744..4babef1be8 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -772,20 +772,6 @@ type GithubOAuth2Config struct { DefaultProviderConfigured bool } -const ( - // GithubOAuth2DefaultProviderInstallURL is where admins install the - // default Coder GitHub app so it can see organization and team - // memberships. - GithubOAuth2DefaultProviderInstallURL = "https://github.com/apps/coder/installations/select_target" - - // githubOAuth2DefaultProviderRemediation explains why the default GitHub - // app can fail org and team membership checks, and how to fix it. It is - // appended to login rejection messages and mirrored by the server startup - // warning and the GitHub auth docs, so keep those in sync. - githubOAuth2DefaultProviderRemediation = "The default GitHub OAuth provider can only see organizations and teams that have installed the Coder GitHub app. " + - "Install it from " + GithubOAuth2DefaultProviderInstallURL + " for each authorized organization, or configure a custom GitHub OAuth app." -) - func (*GithubOAuth2Config) PKCESupported() []promoauth.Oauth2PKCEChallengeMethod { return []promoauth.Oauth2PKCEChallengeMethod{promoauth.PKCEChallengeMethodSha256} } @@ -945,13 +931,6 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) { if len(selectedMemberships) == 0 { status := http.StatusUnauthorized msg := "You aren't a member of the authorized Github organizations!" - if api.GithubOAuth2Config.DefaultProviderConfigured { - // The default provider is a GitHub App, so it can only report - // memberships in organizations that have installed it. Without - // this hint, users in an allowed organization see a confusing - // rejection with no way to discover the missing installation. - msg += " " + githubOAuth2DefaultProviderRemediation - } if api.GithubOAuth2Config.DeviceFlowEnabled { // In the device flow, the error is rendered client-side. httpapi.Write(ctx, rw, status, codersdk.Response{ @@ -998,12 +977,6 @@ func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) { } if allowedTeam == nil { msg := fmt.Sprintf("You aren't a member of an authorized team in the %v Github organization(s)!", organizationNames) - if api.GithubOAuth2Config.DefaultProviderConfigured { - // Team visibility has the same limitation as org visibility: - // the default GitHub App cannot see teams in organizations - // where it isn't installed. - msg += " " + githubOAuth2DefaultProviderRemediation - } status := http.StatusUnauthorized if api.GithubOAuth2Config.DeviceFlowEnabled { // In the device flow, the error is rendered client-side. diff --git a/coderd/userauth_test.go b/coderd/userauth_test.go index bba1f93e10..463ce83651 100644 --- a/coderd/userauth_test.go +++ b/coderd/userauth_test.go @@ -221,63 +221,6 @@ func TestUserOAuth2Github(t *testing.T) { resp := oauth2Callback(t, client) require.Equal(t, http.StatusUnauthorized, resp.StatusCode) - location, err := resp.Location() - require.NoError(t, err) - require.NotContains(t, location.Query().Get("message"), "Coder GitHub app") - }) - t.Run("NotInAllowedOrganizationDefaultProvider", func(t *testing.T) { - t.Parallel() - client := coderdtest.New(t, &coderdtest.Options{ - GithubOAuth2Config: &coderd.GithubOAuth2Config{ - OAuth2Config: &testutil.OAuth2Config{}, - DefaultProviderConfigured: true, - AllowOrganizations: []string{"coder"}, - ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { - // The default provider is a GitHub App, so it reports no - // memberships for organizations it isn't installed in. - return []*github.Membership{}, nil - }, - }, - }) - - resp := oauth2Callback(t, client) - require.Equal(t, http.StatusUnauthorized, resp.StatusCode) - // The error must tell the user how to fix the likely cause: the Coder - // GitHub app isn't installed in the allowed organization. - location, err := resp.Location() - require.NoError(t, err) - require.Contains(t, location.Query().Get("message"), "Coder GitHub app") - require.Contains(t, location.Query().Get("message"), "https://github.com/apps/coder") - }) - t.Run("NotInAllowedOrganizationDefaultProviderDeviceFlow", func(t *testing.T) { - t.Parallel() - client := coderdtest.New(t, &coderdtest.Options{ - GithubOAuth2Config: &coderd.GithubOAuth2Config{ - OAuth2Config: &testutil.OAuth2Config{}, - DefaultProviderConfigured: true, - AllowOrganizations: []string{"coder"}, - ListOrganizationMemberships: func(ctx context.Context, client *http.Client) ([]*github.Membership, error) { - return []*github.Membership{}, nil - }, - DeviceFlowEnabled: true, - ExchangeDeviceCode: func(_ context.Context, _ string) (*oauth2.Token, error) { - return &oauth2.Token{ - AccessToken: "access_token", - RefreshToken: "refresh_token", - Expiry: time.Now().Add(time.Hour), - }, nil - }, - }, - }) - - resp := oauth2Callback(t, client) - require.Equal(t, http.StatusUnauthorized, resp.StatusCode) - // In the device flow the error is rendered client-side, so the hint - // must arrive in the response body Detail rather than the redirect. - var apiErr codersdk.Response - require.NoError(t, json.NewDecoder(resp.Body).Decode(&apiErr)) - require.Contains(t, apiErr.Detail, "Coder GitHub app") - require.Contains(t, apiErr.Detail, "https://github.com/apps/coder") }) t.Run("NotInAllowedTeam", func(t *testing.T) { t.Parallel() diff --git a/docs/admin/users/github-auth.md b/docs/admin/users/github-auth.md index 9125c6217b..4d07abb1e2 100644 --- a/docs/admin/users/github-auth.md +++ b/docs/admin/users/github-auth.md @@ -44,11 +44,6 @@ To use the default configuration: CODER_OAUTH2_GITHUB_ALLOWED_ORGS="your-org" ``` - > [!IMPORTANT] - > The default GitHub app can only see memberships in organizations where it is installed. - > If you set `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` without installing the app in each allowed organization, all logins fail with "You aren't a member of the authorized Github organizations!", including the first admin login on a fresh deployment. - > Install the app for each organization at the [Coder app on GitHub](https://github.com/apps/coder/installations/select_target). - ## Disable the Default GitHub App You can disable the default GitHub app by [configuring your own app](#step-1-configure-the-oauth-application-in-github)