Open
Conversation
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
Member
Author
POC patchdiff --git a/cmd/dex/config.go b/cmd/dex/config.go
index 8861ddef..7971d957 100644
--- a/cmd/dex/config.go
+++ b/cmd/dex/config.go
@@ -12,6 +12,7 @@ import (
"golang.org/x/crypto/bcrypt"
+ "github.com/dexidp/dex/connector"
"github.com/dexidp/dex/pkg/featureflags"
"github.com/dexidp/dex/server"
"github.com/dexidp/dex/server/signer"
@@ -465,7 +466,7 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &conn); err != nil {
return fmt.Errorf("parse connector: %v", err)
}
- f, ok := server.ConnectorsConfig[conn.Type]
+ f, ok := connector.Get(conn.Type)
if !ok {
return fmt.Errorf("unknown connector type %q", conn.Type)
}
diff --git a/cmd/dex/main.go b/cmd/dex/main.go
index 06ab7d0f..bfb853c1 100644
--- a/cmd/dex/main.go
+++ b/cmd/dex/main.go
@@ -1 +1,10 @@
package main
+
+import (
+ _ "github.com/dexidp/dex/connector/mock"
+ _ "github.com/dexidp/dex/connector/openshift"
+)
+
+func main() {
+ Main()
+}
diff --git a/cmd/dex/run.go b/cmd/dex/run.go
index be334d92..81685173 100644
--- a/cmd/dex/run.go
+++ b/cmd/dex/run.go
@@ -20,7 +20,7 @@ func commandRoot() *cobra.Command {
return rootCmd
}
-func main() {
+func Main() {
if err := commandRoot().Execute(); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(2)
diff --git a/connector/mock/connectortest.go b/connector/mock/connectortest.go
index be44bfd1..bb21b12b 100644
--- a/connector/mock/connectortest.go
+++ b/connector/mock/connectortest.go
@@ -12,6 +12,15 @@ import (
"github.com/dexidp/dex/connector"
)
+func init() {
+ connector.Register("mockPassword", func() connector.Config {
+ return new(PasswordConfig)
+ })
+ connector.Register("mockCallback", func() connector.Config {
+ return new(CallbackConfig)
+ })
+}
+
// NewCallbackConnector returns a mock connector which requires no user interaction. It always returns
// the same (fake) identity.
func NewCallbackConnector(logger *slog.Logger) connector.Connector {
diff --git a/connector/openshift/openshift.go b/connector/openshift/openshift.go
index 3d4408c5..822c2d31 100644
--- a/connector/openshift/openshift.go
+++ b/connector/openshift/openshift.go
@@ -22,6 +22,12 @@ const (
usersURLPath = "/apis/user.openshift.io/v1/users/~"
)
+func init() {
+ connector.Register("openshift", func() connector.Config {
+ return new(Config)
+ })
+}
+
// Config holds configuration options for OpenShift login
type Config struct {
Issuer string `json:"issuer"`
diff --git a/connector/registry.go b/connector/registry.go
index d7cfddd5..e06a6ff1 100644
--- a/connector/registry.go
+++ b/connector/registry.go
@@ -1 +1,41 @@
package connector
+
+import (
+ "fmt"
+ "log/slog"
+)
+
+// Config is a configuration that can open a connector.
+type Config interface {
+ Open(id string, logger *slog.Logger) (Connector, error)
+}
+
+// registry is the internal map of registered connector types.
+// It is not exported — access is only through Register() and Get().
+var registry = map[string]func() Config{}
+
+// Register registers a connector type that can be used in Dex configuration.
+// It is intended to be called from init() functions of connector packages.
+// Calling Register with an already registered type name will panic.
+func Register(typeName string, factory func() Config) {
+ if _, exists := registry[typeName]; exists {
+ panic(fmt.Sprintf("connector type %q already registered", typeName))
+ }
+ registry[typeName] = factory
+}
+
+// Get returns the config factory for the given connector type name.
+// Returns nil if the type is not registered.
+func Get(typeName string) (func() Config, bool) {
+ f, ok := registry[typeName]
+ return f, ok
+}
+
+// RegisteredTypes returns a list of all registered connector type names.
+func RegisteredTypes() []string {
+ types := make([]string, 0, len(registry))
+ for t := range registry {
+ types = append(types, t)
+ }
+ return types
+}
diff --git a/server/server.go b/server/server.go
index e923e3e0..f1d4b5b5 100644
--- a/server/server.go
+++ b/server/server.go
@@ -699,7 +699,7 @@ var ConnectorsConfig = map[string]func() ConnectorConfig{
func openConnector(logger *slog.Logger, conn storage.Connector) (connector.Connector, error) {
var c connector.Connector
- f, ok := ConnectorsConfig[conn.Type]
+ f, ok := connector.Get(conn.Type)
if !ok {
return c, fmt.Errorf("unknown connector type %q", conn.Type)
}
|
This was referenced Feb 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
DEP (Dex Enhancement Proposal) for introducing external connectors support — an official way to build custom Dex distributions with user-provided connectors compiled in, following the OpenTelemetry Collector Builder pattern.
What this PR does / why we need it
This PR adds a proposal document that describes splitting Dex connectors into core (LDAP, OIDC, OAuth2, SAML, AuthProxy) and external (GitHub, GitLab, Google, Microsoft, LinkedIn, Bitbucket, OpenShift, Gitea, Atlassian Crowd, Keystone).
Problem: Dex ships ~15 connectors in-tree. This increases binary size, dependency bloat, and maintenance burden. Community members who want to add new connectors must submit PRs to the core repo, making maintainers responsible for code they don't use.
Solution:
dexidp/dex-connectors(each as an independent Go module)connector.Register()API so connectors self-register viainit()dexbuilderCLI tool that generates a custom Dex binary from abuilder.yamlmanifest (list of Go modules to include)Key design decisions:
excludeCoreConnectorsregistrymap is unexported; access only throughRegister()/Get()Special notes for your reviewer