From 3170ff45949786703a67e57cee77f62db875606a Mon Sep 17 00:00:00 2001 From: Justin Hines Date: Thu, 1 Aug 2019 13:55:24 -0400 Subject: [PATCH 1/2] proxy: move domains/address to upstream config --- internal/proxy/options.go | 8 -------- internal/proxy/options_test.go | 2 -- internal/proxy/proxy.go | 12 ++++++------ internal/proxy/proxy_config.go | 6 ++++++ 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/internal/proxy/options.go b/internal/proxy/options.go index a62a06ea..8f5c6841 100644 --- a/internal/proxy/options.go +++ b/internal/proxy/options.go @@ -24,8 +24,6 @@ import ( // Cluster - the cluster in which this is running, used for upstream configs // Scheme - the default scheme, used for upstream configs // SkipAuthPreflight - will skip authentication for OPTIONS requests, default false -// EmailDomains - csv list of emails with the specified domain to authenticate. Use * to authenticate any email -// EmailAddresses - []string - authenticate emails with the specified email address (may be given multiple times). Use * to authenticate any email // DefaultAllowedGroups - csv list of default allowed groups that are applied to authorize access to upstreams. Will be overridden by groups specified in upstream configs. // ClientID - the OAuth Client ID: ie: "123456.apps.googleusercontent.com" // ClientSecret - The OAuth Client Secret @@ -60,8 +58,6 @@ type Options struct { SkipAuthPreflight bool `envconfig:"SKIP_AUTH_PREFLIGHT"` - EmailDomains []string `envconfig:"EMAIL_DOMAIN"` - EmailAddresses []string `envconfig:"EMAIL_ADDRESSES"` DefaultAllowedGroups []string `envconfig:"DEFAULT_ALLOWED_GROUPS"` ClientID string `envconfig:"CLIENT_ID"` @@ -147,10 +143,6 @@ func (o *Options) Validate() error { if o.ClientSecret == "" { msgs = append(msgs, "missing setting: client-secret") } - if len(o.EmailDomains) == 0 && len(o.EmailAddresses) == 0 { - msgs = append(msgs, "missing setting: email-domain or email-address") - } - if o.StatsdHost == "" { msgs = append(msgs, "missing setting: statsd-host") } diff --git a/internal/proxy/options_test.go b/internal/proxy/options_test.go index 57065459..35ca0c89 100644 --- a/internal/proxy/options_test.go +++ b/internal/proxy/options_test.go @@ -16,7 +16,6 @@ func testOptions() *Options { o.CookieSecret = testEncodedCookieSecret o.ClientID = "bazquux" o.ClientSecret = "xyzzyplugh" - o.EmailDomains = []string{"*"} o.DefaultProviderSlug = "idp" o.ProviderURLString = "https://www.example.com" o.UpstreamConfigsFile = "testdata/upstream_configs.yml" @@ -41,7 +40,6 @@ func errorMsg(msgs []string) string { func TestNewOptions(t *testing.T) { o := NewOptions() - o.EmailDomains = []string{"*"} err := o.Validate() testutil.NotEqual(t, nil, err) diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index 64062a7c..fc1013a4 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -25,12 +25,6 @@ func New(opts *Options) (*SSOProxy, error) { optFuncs = append(optFuncs, SetRequestSigner(requestSigner)) } - if len(opts.EmailAddresses) != 0 { - optFuncs = append(optFuncs, SetValidator(options.NewEmailAddressValidator(opts.EmailAddresses))) - } else { - optFuncs = append(optFuncs, SetValidator(options.NewEmailDomainValidator(opts.EmailDomains))) - } - hostRouter := hostmux.NewRouter() for _, upstreamConfig := range opts.upstreamConfigs { provider, err := newProvider(opts, upstreamConfig) @@ -38,6 +32,12 @@ func New(opts *Options) (*SSOProxy, error) { return nil, err } + if len(upstreamConfig.EmailAddresses) != 0 { + optFuncs = append(optFuncs, SetValidator(options.NewEmailAddressValidator(upstreamConfig.EmailAddresses))) + } else if len(upstreamConfig.EmailDomains) != 0 { + optFuncs = append(optFuncs, SetValidator(options.NewEmailDomainValidator(upstreamConfig.EmailDomains))) + } + handler, err := NewUpstreamReverseProxy(upstreamConfig, requestSigner) if err != nil { return nil, err diff --git a/internal/proxy/proxy_config.go b/internal/proxy/proxy_config.go index 120eb1f9..6e50182b 100644 --- a/internal/proxy/proxy_config.go +++ b/internal/proxy/proxy_config.go @@ -62,6 +62,8 @@ type UpstreamConfig struct { SkipRequestSigning bool CookieName string ProviderSlug string + EmailDomains []string + EmailAddresses []string } // RouteConfig maps to the yaml config fields, @@ -97,6 +99,8 @@ type OptionsConfig struct { FlushInterval time.Duration `yaml:"flush_interval"` SkipRequestSigning bool `yaml:"skip_request_signing"` ProviderSlug string `yaml:"provider_slug"` + EmailDomains []string `yaml:"email_domains"` + EmailAddresses []string `yaml:"email_addresses"` // CookieName is still set globally, so we do not provide override behavior CookieName string @@ -403,6 +407,8 @@ func parseOptionsConfig(proxy *UpstreamConfig, defaultOpts *OptionsConfig) error proxy.SkipRequestSigning = dst.SkipRequestSigning proxy.CookieName = dst.CookieName proxy.ProviderSlug = dst.ProviderSlug + proxy.EmailDomains = dst.EmailDomains + proxy.EmailAddresses = dst.EmailAddresses proxy.RouteConfig.Options = nil From 55bf4486549af125ba616c42f6b2a3749962b66d Mon Sep 17 00:00:00 2001 From: Justin Hines Date: Thu, 1 Aug 2019 15:08:11 -0400 Subject: [PATCH 2/2] auth: remove email_domains/email_addresses --- docs/sso_config.md | 6 ++- internal/auth/authenticator.go | 21 --------- internal/auth/authenticator_test.go | 73 ++--------------------------- internal/auth/configuration.go | 27 ----------- internal/auth/configuration_test.go | 15 ------ internal/auth/mux.go | 9 ---- internal/auth/options.go | 8 ---- internal/proxy/proxy_config.go | 4 +- 8 files changed, 9 insertions(+), 154 deletions(-) diff --git a/docs/sso_config.md b/docs/sso_config.md index 21d7720b..772a78e3 100644 --- a/docs/sso_config.md +++ b/docs/sso_config.md @@ -30,7 +30,9 @@ For example, the following config would have the following environment variables * **to** is the cname of the proxied service (this tells sso proxy where to proxy requests that come in on the from field) * **type** declares the type of route to use, right now there is just *simple* and *rewrite*. * **options** are a set of options that can be added to your configuration. - * **allowed groups** optional list of authorized google groups that can access the service. If not specified, anyone within an email domain is allowed to access the service. *Note*: We do not support nested group authentication at this time. Groups must be made up of email addresses associated with individual's accounts. See [#133](https://github.com/buzzfeed/sso/issues/133). + * **allowed groups** optional list of authorized google groups that can access the service. + * **allowed_email_domains** options list of authorized email domains that can access the service. + * **allowed_email_addresses** optional list of authorized email addresses that can access the service. * **skip_auth_regex** skips authentication for paths matching these regular expressions. NOTE: Use with extreme caution. * **header_overrides** overrides any heads set either by SSO proxy itself or upstream applications. Useful for modifying browser security headers. * **timeout** sets the amount of time that SSO Proxy will wait for the upstream to complete its request. @@ -189,4 +191,4 @@ share the same paths. ![sso_request_flow](https://user-images.githubusercontent.com/10510566/44476373-8ae34e80-a605-11e8-93da-d876f7e48d84.png) - \ No newline at end of file + diff --git a/internal/auth/authenticator.go b/internal/auth/authenticator.go index dc2c4d37..65f750b3 100644 --- a/internal/auth/authenticator.go +++ b/internal/auth/authenticator.go @@ -20,8 +20,6 @@ import ( // Authenticator stores all the information associated with proxying the request. type Authenticator struct { - Validator func(string) bool - EmailDomains []string ProxyRootDomains []string Host string Scheme string @@ -80,7 +78,6 @@ func NewAuthenticator(config Configuration, optionFuncs ...func(*Authenticator) p := &Authenticator{ ProxyClientID: config.ClientConfigs["proxy"].ID, ProxyClientSecret: config.ClientConfigs["proxy"].Secret, - EmailDomains: config.AuthorizeConfig.EmailConfig.Domains, Host: config.ServerConfig.Host, Scheme: config.ServerConfig.Scheme, @@ -127,7 +124,6 @@ func (p *Authenticator) GetRedirectURI(host string) string { type signInResp struct { ProviderSlug string ProviderName string - EmailDomains []string Redirect string Destination string Version string @@ -155,7 +151,6 @@ func (p *Authenticator) SignInPage(rw http.ResponseWriter, req *http.Request, co t := signInResp{ ProviderName: p.provider.Data().ProviderName, ProviderSlug: p.provider.Data().ProviderSlug, - EmailDomains: p.EmailDomains, Redirect: redirectURL.String(), Destination: destinationURL.Host, Version: VERSION, @@ -225,11 +220,6 @@ func (p *Authenticator) authenticate(rw http.ResponseWriter, req *http.Request) } } - if !p.Validator(session.Email) { - logger.WithUser(session.Email).Error("invalid email user") - return nil, ErrUserNotAuthorized - } - return session, nil } @@ -569,17 +559,6 @@ func (p *Authenticator) getOAuthCallback(rw http.ResponseWriter, req *http.Reque return "", HTTPError{Code: http.StatusForbidden, Message: "Invalid Redirect URI"} } - // Set cookie, or deny: The authenticator validates the session email and group - // - for p.Validator see validator.go#newValidatorImpl for more info - // - for p.provider.ValidateGroup see providers/google.go#ValidateGroup for more info - if !p.Validator(session.Email) { - tags := append(tags, "error:invalid_email") - p.StatsdClient.Incr("application_error", tags, 1.0) - logger.WithRemoteAddress(remoteAddr).WithUser(session.Email).Error( - "invalid_email", "permission denied; unauthorized user") - return "", HTTPError{Code: http.StatusForbidden, Message: "Invalid Account"} - } - logger.WithRemoteAddress(remoteAddr).WithUser(session.Email).Info("authentication complete") err = p.sessionStore.SaveSession(rw, req, session) if err != nil { diff --git a/internal/auth/authenticator_test.go b/internal/auth/authenticator_test.go index e07af141..b18cb5b3 100644 --- a/internal/auth/authenticator_test.go +++ b/internal/auth/authenticator_test.go @@ -66,13 +66,6 @@ func setTestProvider(provider *providers.TestProvider) func(*Authenticator) erro } } -func setMockValidator(response bool) func(*Authenticator) error { - return func(a *Authenticator) error { - a.Validator = func(string) bool { return response } - return nil - } -} - func setRedirectURL(redirectURL *url.URL) func(*Authenticator) error { return func(a *Authenticator) error { a.redirectURL = redirectURL @@ -139,7 +132,6 @@ func TestSignIn(t *testing.T) { mockAuthCodeCipher *aead.MockCipher refreshResponse providerRefreshResponse providerValidToken bool - validEmail bool expectedSignInPage bool expectedDestinationURL string expectedCode int @@ -242,23 +234,6 @@ func TestSignIn(t *testing.T) { expectedCode: http.StatusInternalServerError, expectedErrorResponse: &errResponse{"save error"}, }, - { - name: "refresh period expired, successful refresh, invalid email", - mockSessionStore: &sessions.MockSessionStore{ - Session: &sessions.SessionState{ - Email: "email", - AccessToken: "accesstoken", - RefreshToken: "refresh", - LifetimeDeadline: time.Now().Add(time.Hour), - RefreshDeadline: time.Now().Add(-time.Hour), - }, - }, - refreshResponse: providerRefreshResponse{ - OK: true, - }, - expectedCode: http.StatusUnauthorized, - expectedErrorResponse: &errResponse{ErrUserNotAuthorized.Error()}, - }, { name: "valid session state, save session error", mockSessionStore: &sessions.MockSessionStore{ @@ -276,7 +251,7 @@ func TestSignIn(t *testing.T) { expectedErrorResponse: &errResponse{"save error"}, }, { - name: "invalid session state, invalid email", + name: "invalid session state", mockSessionStore: &sessions.MockSessionStore{ Session: &sessions.SessionState{ Email: "email", @@ -303,7 +278,6 @@ func TestSignIn(t *testing.T) { refreshResponse: providerRefreshResponse{ OK: true, }, - validEmail: true, expectedCode: http.StatusForbidden, expectedErrorResponse: &errResponse{"no state parameter supplied"}, }, @@ -324,7 +298,6 @@ func TestSignIn(t *testing.T) { refreshResponse: providerRefreshResponse{ OK: true, }, - validEmail: true, expectedCode: http.StatusForbidden, expectedErrorResponse: &errResponse{"no redirect_uri parameter supplied"}, }, @@ -346,7 +319,6 @@ func TestSignIn(t *testing.T) { refreshResponse: providerRefreshResponse{ OK: true, }, - validEmail: true, expectedCode: http.StatusBadRequest, expectedErrorResponse: &errResponse{"malformed redirect_uri parameter passed"}, }, @@ -371,7 +343,6 @@ func TestSignIn(t *testing.T) { mockAuthCodeCipher: &aead.MockCipher{ MarshalError: fmt.Errorf("error marshal"), }, - validEmail: true, expectedCode: http.StatusInternalServerError, expectedErrorResponse: &errResponse{"error marshal"}, }, @@ -396,7 +367,6 @@ func TestSignIn(t *testing.T) { mockAuthCodeCipher: &aead.MockCipher{ MarshalString: "abcdefg", }, - validEmail: true, expectedCode: http.StatusFound, }, { @@ -414,7 +384,6 @@ func TestSignIn(t *testing.T) { "state": "state", "redirect_uri": "http://foo.example.com", }, - validEmail: true, providerValidToken: true, mockAuthCodeCipher: &aead.MockCipher{ MarshalString: "abcdefg", @@ -428,7 +397,6 @@ func TestSignIn(t *testing.T) { t.Run(tc.name, func(t *testing.T) { config := testConfiguration(t) auth, err := NewAuthenticator(config, - setMockValidator(tc.validEmail), setMockSessionStore(tc.mockSessionStore), setMockTempl(), setMockRedirectURL(), @@ -463,7 +431,6 @@ func TestSignIn(t *testing.T) { expectedSignInResp := &signInResp{ ProviderName: provider.Data().ProviderName, ProviderSlug: "test", - EmailDomains: auth.EmailDomains, Redirect: u.String(), Destination: tc.expectedDestinationURL, Version: VERSION, @@ -575,7 +542,6 @@ func TestSignOutPage(t *testing.T) { provider.RevokeError = tc.RevokeError p, _ := NewAuthenticator(config, - setMockValidator(true), setMockSessionStore(tc.mockSessionStore), setMockTempl(), setTestProvider(provider), @@ -951,9 +917,7 @@ func TestGetProfile(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { config := testConfiguration(t) - p, _ := NewAuthenticator(config, - setMockValidator(true), - ) + p, _ := NewAuthenticator(config) u, _ := url.Parse("http://example.com") testProvider := providers.NewTestProvider(u) testProvider.Groups = tc.groupEmails @@ -1053,9 +1017,7 @@ func TestRedeemCode(t *testing.T) { t.Run(tc.name, func(t *testing.T) { config := testConfiguration(t) - proxy, _ := NewAuthenticator(config, - setMockValidator(true), - ) + proxy, _ := NewAuthenticator(config) testURL, err := url.Parse("example.com") if err != nil { @@ -1224,7 +1186,6 @@ func TestOAuthCallback(t *testing.T) { paramsMap map[string]string expectedError error testRedeemResponse testRedeemResponse - validEmail bool csrfResp *sessions.MockCSRFStore sessionStore *sessions.MockSessionStore expectedRedirect string @@ -1340,29 +1301,6 @@ func TestOAuthCallback(t *testing.T) { }, expectedError: HTTPError{Code: http.StatusForbidden, Message: "csrf failed"}, }, - - { - name: "invalid email address", - paramsMap: map[string]string{ - "code": "authCode", - "state": base64.URLEncoding.EncodeToString([]byte("state:http://www.example.com/something")), - }, - testRedeemResponse: testRedeemResponse{ - SessionState: &sessions.SessionState{ - Email: "example@email.com", - AccessToken: "accessToken", - RefreshDeadline: time.Now().Add(time.Hour), - RefreshToken: "refresh", - }, - }, - csrfResp: &sessions.MockCSRFStore{ - Cookie: &http.Cookie{ - Name: "something_csrf", - Value: "state", - }, - }, - expectedError: HTTPError{Code: http.StatusForbidden, Message: "Invalid Account"}, - }, { name: "valid email, invalid redirect", paramsMap: map[string]string{ @@ -1383,7 +1321,6 @@ func TestOAuthCallback(t *testing.T) { Value: "state", }, }, - validEmail: true, expectedError: HTTPError{Code: http.StatusForbidden, Message: "Invalid Redirect URI"}, }, { @@ -1409,7 +1346,6 @@ func TestOAuthCallback(t *testing.T) { sessionStore: &sessions.MockSessionStore{ SaveError: fmt.Errorf("saveError"), }, - validEmail: true, expectedError: HTTPError{Code: http.StatusInternalServerError, Message: "Internal Error"}, }, { @@ -1433,7 +1369,6 @@ func TestOAuthCallback(t *testing.T) { }, }, sessionStore: &sessions.MockSessionStore{}, - validEmail: true, expectedRedirect: "http://www.example.com/something", }, } @@ -1442,7 +1377,6 @@ func TestOAuthCallback(t *testing.T) { t.Run(tc.name, func(t *testing.T) { config := testConfiguration(t) proxy, _ := NewAuthenticator(config, - setMockValidator(tc.validEmail), setMockCSRFStore(tc.csrfResp), setMockSessionStore(tc.sessionStore), ) @@ -1563,7 +1497,6 @@ func TestOAuthStart(t *testing.T) { provider := providers.NewTestProvider(nil) proxy, _ := NewAuthenticator(config, setTestProvider(provider), - setMockValidator(true), setMockRedirectURL(), setMockCSRFStore(&sessions.MockCSRFStore{}), ) diff --git a/internal/auth/configuration.go b/internal/auth/configuration.go index c36334e5..f0b5cd69 100644 --- a/internal/auth/configuration.go +++ b/internal/auth/configuration.go @@ -99,10 +99,6 @@ func DefaultAuthConfig() Configuration { }, // we provide no defaults for these right now AuthorizeConfig: AuthorizeConfig{ - EmailConfig: EmailConfig{ - Domains: []string{}, - Addresses: []string{}, - }, ProxyConfig: ProxyConfig{ Domains: []string{}, }, @@ -120,7 +116,6 @@ var ( _ Validator = ProviderConfig{} _ Validator = ClientConfig{} _ Validator = AuthorizeConfig{} - _ Validator = EmailConfig{} _ Validator = ProxyConfig{} _ Validator = ServerConfig{} _ Validator = MetricsConfig{} @@ -402,15 +397,10 @@ func (cc ClientConfig) Validate() error { } type AuthorizeConfig struct { - EmailConfig EmailConfig `mapstructure:"email"` ProxyConfig ProxyConfig `mapstructure:"proxy"` } func (ac AuthorizeConfig) Validate() error { - if err := ac.EmailConfig.Validate(); err != nil { - return xerrors.Errorf("invalid authorize.email config: %w", err) - } - if err := ac.ProxyConfig.Validate(); err != nil { return xerrors.Errorf("invalid authorize.proxy config: %w", err) } @@ -418,23 +408,6 @@ func (ac AuthorizeConfig) Validate() error { return nil } -type EmailConfig struct { - Domains []string `mapstructure:"domains"` - Addresses []string `mapstructure:"addresses"` -} - -func (ec EmailConfig) Validate() error { - if len(ec.Domains) > 0 && len(ec.Addresses) > 0 { - return xerrors.New("can not specify both email.domains and email.addesses") - } - - if len(ec.Domains) == 0 && len(ec.Addresses) == 0 { - return xerrors.New("must specify either email.domains or email.addresses") - } - - return nil -} - type ProxyConfig struct { Domains []string `mapstructure:"domains"` } diff --git a/internal/auth/configuration_test.go b/internal/auth/configuration_test.go index 0ce8a95b..91e6df6e 100644 --- a/internal/auth/configuration_test.go +++ b/internal/auth/configuration_test.go @@ -61,9 +61,6 @@ func testConfiguration(t *testing.T) Configuration { ProxyConfig: ProxyConfig{ Domains: []string{"proxy.local", "root.local", "example.com"}, }, - EmailConfig: EmailConfig{ - Domains: []string{"proxy.local"}, - }, }, } err := c.Validate() @@ -163,15 +160,6 @@ func TestEnvironmentOverridesConfiguration(t *testing.T) { assertEq("baz-client-id", baz.ClientConfig.ID, t) }, }, - { - Name: "Test ENV CSV Lists", - EnvOverrides: map[string]string{ - "AUTHORIZE_EMAIL_DOMAINS": "proxy.local,root.local", - }, - CheckFunc: func(c Configuration, t *testing.T) { - assertEq([]string{"proxy.local", "root.local"}, c.AuthorizeConfig.EmailConfig.Domains, t) - }, - }, } for _, tc := range testCases { t.Run(tc.Name, func(t *testing.T) { @@ -247,9 +235,6 @@ func TestConfigValidate(t *testing.T) { ProxyConfig: ProxyConfig{ Domains: []string{"proxy.local", "root.local"}, }, - EmailConfig: EmailConfig{ - Domains: []string{"proxy.local"}, - }, }, }, ExpectedErr: nil, diff --git a/internal/auth/mux.go b/internal/auth/mux.go index 270315a7..fece9d8d 100644 --- a/internal/auth/mux.go +++ b/internal/auth/mux.go @@ -6,7 +6,6 @@ import ( "github.com/buzzfeed/sso/internal/pkg/hostmux" log "github.com/buzzfeed/sso/internal/pkg/logging" - "github.com/buzzfeed/sso/internal/pkg/options" "github.com/datadog/datadog-go/statsd" ) @@ -19,13 +18,6 @@ type AuthenticatorMux struct { func NewAuthenticatorMux(config Configuration, statsdClient *statsd.Client) (*AuthenticatorMux, error) { logger := log.NewLogEntry() - var validator func(string) bool - if len(config.AuthorizeConfig.EmailConfig.Addresses) != 0 { - validator = options.NewEmailAddressValidator(config.AuthorizeConfig.EmailConfig.Addresses) - } else { - validator = options.NewEmailDomainValidator(config.AuthorizeConfig.EmailConfig.Domains) - } - authenticators := []*Authenticator{} idpMux := http.NewServeMux() @@ -38,7 +30,6 @@ func NewAuthenticatorMux(config Configuration, statsdClient *statsd.Client) (*Au idpSlug := idp.Data().ProviderSlug authenticator, err := NewAuthenticator(config, - SetValidator(validator), SetProvider(idp), SetCookieStore(config.SessionConfig, idpSlug), SetStatsdClient(statsdClient), diff --git a/internal/auth/options.go b/internal/auth/options.go index 5d15130e..ad82ca36 100644 --- a/internal/auth/options.go +++ b/internal/auth/options.go @@ -95,14 +95,6 @@ func SetRedirectURL(serverConfig ServerConfig, slug string) func(*Authenticator) } } -// SetValidator sets the email validator -func SetValidator(validator func(string) bool) func(*Authenticator) error { - return func(a *Authenticator) error { - a.Validator = validator - return nil - } -} - // SetCookieStore sets the cookie store to use a miscreant cipher func SetCookieStore(sessionConfig SessionConfig, providerSlug string) func(*Authenticator) error { return func(a *Authenticator) error { diff --git a/internal/proxy/proxy_config.go b/internal/proxy/proxy_config.go index 6e50182b..7f07d29c 100644 --- a/internal/proxy/proxy_config.go +++ b/internal/proxy/proxy_config.go @@ -92,6 +92,8 @@ type OptionsConfig struct { HeaderOverrides map[string]string `yaml:"header_overrides"` SkipAuthRegex []string `yaml:"skip_auth_regex"` AllowedGroups []string `yaml:"allowed_groups"` + EmailDomains []string `yaml:"allowed_email_domains"` + EmailAddresses []string `yaml:"allowed_email_addresses"` TLSSkipVerify bool `yaml:"tls_skip_verify"` PreserveHost bool `yaml:"preserve_host"` Timeout time.Duration `yaml:"timeout"` @@ -99,8 +101,6 @@ type OptionsConfig struct { FlushInterval time.Duration `yaml:"flush_interval"` SkipRequestSigning bool `yaml:"skip_request_signing"` ProviderSlug string `yaml:"provider_slug"` - EmailDomains []string `yaml:"email_domains"` - EmailAddresses []string `yaml:"email_addresses"` // CookieName is still set globally, so we do not provide override behavior CookieName string