Repository: ConduitIO/conduit-site
Pull request #270: Allowed/denied connectors in registry
Author: login: lovromazgon
Created: 2025-04-22T16:22:43Z | Merged: 2025-04-23T16:18:50Z

Change which connectors get added to the connector registry.

Previously, we added any repository that imported the connector SDK, regardless of the org. Now the process has been improved to give us more control over what we add to the list and prevent malicious actors from adding malicious connectors to our list. Only connectors that are from allowed orgs are added automatically (`conduitio`, `conduitio-labs` and `meroxa`), all others have to be explicitly added to the list.

To make it possible for us to still spot new 3rd party connectors, I added code that exports the denied connectors into `src/connectorgen/denied-connectors.json`. Note that this file is not in the `static` folder, so as not to advertise them on our page (the `src` folder is not included on our page). This file is meant only for us to notice connectors that mistakenly land in the denied list.

Actual changes to the code:

  - The connector list was moved to a `yaml` file, so it's simpler to edit
  - The registry command has a new flag `-d`/`--denied-path` that, if supplied, exports the denied list to a file (otherwise it skips this step)
  - The code was refactored a bit (using `ghdeps.Repository` instead of a `string` for representing a repo)

This PR also contains the regenerated `connectors.json` file, superseding https://github.com/ConduitIO/conduit-site/pull/269.

> [!NOTE]
> I removed all repositories from the list that were forks or ones that were eventually moved to conduitio-labs. I only left 3rd-party connectors, which are actually different from our organization's repositories.


Diff:
diff --git a/docs/1-using/5-connectors/7-list/14-activemq.mdx b/docs/1-using/5-connectors/7-list/15-activemq.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/14-activemq.mdx
rename to docs/1-using/5-connectors/7-list/15-activemq.mdx
diff --git a/docs/1-using/5-connectors/7-list/24-chaos.mdx b/docs/1-using/5-connectors/7-list/25-chaos.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/24-chaos.mdx
rename to docs/1-using/5-connectors/7-list/25-chaos.mdx
diff --git a/docs/1-using/5-connectors/7-list/3-kafka.mdx b/docs/1-using/5-connectors/7-list/3-kafka.mdx
index 6bb3963d..e994b2ec 100644
--- a/docs/1-using/5-connectors/7-list/3-kafka.mdx
+++ b/docs/1-using/5-connectors/7-list/3-kafka.mdx
@@ -60,7 +60,7 @@ import Tooltip from '@mui/material/Tooltip';
   {/* Stars */}
   <Chip
     icon={<StarIcon sx={{ fontSize: '1rem' }} />}
-    label="8"
+    label="9"
     size="small"
     sx={{ height: 24 }}
   />
diff --git a/docs/1-using/5-connectors/7-list/30-dynamodb.mdx b/docs/1-using/5-connectors/7-list/31-dynamodb.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/30-dynamodb.mdx
rename to docs/1-using/5-connectors/7-list/31-dynamodb.mdx
diff --git a/docs/1-using/5-connectors/7-list/46-mongo.mdx b/docs/1-using/5-connectors/7-list/47-mongo.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/46-mongo.mdx
rename to docs/1-using/5-connectors/7-list/47-mongo.mdx
diff --git a/docs/1-using/5-connectors/7-list/47-mysql.mdx b/docs/1-using/5-connectors/7-list/48-mysql.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/47-mysql.mdx
rename to docs/1-using/5-connectors/7-list/48-mysql.mdx
diff --git a/docs/1-using/5-connectors/7-list/56-rabbitmq.mdx b/docs/1-using/5-connectors/7-list/57-rabbitmq.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/56-rabbitmq.mdx
rename to docs/1-using/5-connectors/7-list/57-rabbitmq.mdx
diff --git a/docs/1-using/5-connectors/7-list/6-s3.mdx b/docs/1-using/5-connectors/7-list/6-s3.mdx
index c550c23a..769989ae 100644
--- a/docs/1-using/5-connectors/7-list/6-s3.mdx
+++ b/docs/1-using/5-connectors/7-list/6-s3.mdx
@@ -60,7 +60,7 @@ import Tooltip from '@mui/material/Tooltip';
   {/* Stars */}
   <Chip
     icon={<StarIcon sx={{ fontSize: '1rem' }} />}
-    label="8"
+    label="9"
     size="small"
     sx={{ height: 24 }}
   />
diff --git a/docs/1-using/5-connectors/7-list/63-snowflake.mdx b/docs/1-using/5-connectors/7-list/64-snowflake.mdx
similarity index 100%
rename from docs/1-using/5-connectors/7-list/63-snowflake.mdx
rename to docs/1-using/5-connectors/7-list/64-snowflake.mdx
diff --git a/src/connectorgen/Makefile b/src/connectorgen/Makefile
index ede167dc..6e5e6a9d 100644
--- a/src/connectorgen/Makefile
+++ b/src/connectorgen/Makefile
@@ -7,7 +7,7 @@ clean-pages:
 
 .PHONY: registry
 registry:
-	go run . registry -o ../../static/connectors.json
+	go run . registry -o ../../static/connectors.json -d ./denied-connectors.json
 
 .PHONY: specifications
 specifications:
diff --git a/src/connectorgen/denied-connectors.json b/src/connectorgen/denied-connectors.json
new file mode 100644
index 00000000..6c9c57ea
--- /dev/null
+++ b/src/connectorgen/denied-connectors.json
@@ -0,0 +1,362 @@
+[
+  {
+    "name_with_owner": "ConduitIO/conduit",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ConduitIO/conduit",
+    "stargazer_count": 464,
+    "fork_count": 50,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ConduitIO/conduit-connector-template",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ConduitIO/conduit-connector-template",
+    "stargazer_count": 5,
+    "fork_count": 2,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ConduitIO/conduit-operator",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ConduitIO/conduit-operator",
+    "stargazer_count": 1,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ConduitIO/conduit-site",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ConduitIO/conduit-site",
+    "stargazer_count": 1,
+    "fork_count": 7,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ConduitIO/streaming-benchmarks",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ConduitIO/streaming-benchmarks",
+    "stargazer_count": 4,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "GevorgGal/conduit-connector-influxdb",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/GevorgGal/conduit-connector-influxdb",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ViniciusMiana/conduit-connector-pulsar",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ViniciusMiana/conduit-connector-pulsar",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "WeirdMagician/conduit-connector-google-cloudstorage",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/WeirdMagician/conduit-connector-google-cloudstorage",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ahamidi/conduit-connector-neo4j",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ahamidi/conduit-connector-neo4j",
+    "stargazer_count": 2,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ahamidi/conduit-connector-pulsar",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ahamidi/conduit-connector-pulsar",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ahamidi/conduit-connector-redis",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ahamidi/conduit-connector-redis",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ahamidi/conduit-connector-rockset",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ahamidi/conduit-connector-rockset",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "ahamidi/conduit-connector-template",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/ahamidi/conduit-connector-template",
+    "stargazer_count": 1,
+    "fork_count": 1,
+    "releases": null
+  },
+  {
+    "name_with_owner": "alejandromav/conduit-connector-tinybird",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/alejandromav/conduit-connector-tinybird",
+    "stargazer_count": 1,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "brharrelldev/pulsar-connector",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/brharrelldev/pulsar-connector",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "derElektrobesen/mysql-migrator",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/derElektrobesen/mysql-migrator",
+    "stargazer_count": 1,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "devarismeroxa/conduit-connector-box",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/devarismeroxa/conduit-connector-box",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "devarismeroxa/conduit-connector-influxdb",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/devarismeroxa/conduit-connector-influxdb",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "devarispbrown/conduit-connector-weaviate",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/devarispbrown/conduit-connector-weaviate",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "gopherslab/conduit-connector-google-sheets",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/gopherslab/conduit-connector-google-sheets",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "gopherslab/conduit-connector-redis",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/gopherslab/conduit-connector-redis",
+    "stargazer_count": 1,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "gopherslab/conduit-connector-zendesk",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/gopherslab/conduit-connector-zendesk",
+    "stargazer_count": 1,
+    "fork_count": 1,
+    "releases": null
+  },
+  {
+    "name_with_owner": "hariso/conduit-connector-foo",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/hariso/conduit-connector-foo",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "hariso/conduit-connector-kafka",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/hariso/conduit-connector-kafka",
+    "stargazer_count": 1,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "hariso/conduit-connector-postgres-test",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/hariso/conduit-connector-postgres-test",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "hariso/conduit-connector-s3",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/hariso/conduit-connector-s3",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "hariso/custom-conduit",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/hariso/custom-conduit",
+    "stargazer_count": 0,
+    "fork_count": 1,
+    "releases": null
+  },
+  {
+    "name_with_owner": "maha-hajja/conduit-connector-slack",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/maha-hajja/conduit-connector-slack",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "mer-oscar/conduit-connector-azure-event-hub",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/mer-oscar/conduit-connector-azure-event-hub",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "mer-oscar/conduit-connector-kinesis",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/mer-oscar/conduit-connector-kinesis",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "mer-oscar/conduit-connector-zeromq",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/mer-oscar/conduit-connector-zeromq",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "miwialex/test-connector",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/miwialex/test-connector",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "mtami/conduit-connector-pulsar",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/mtami/conduit-connector-pulsar",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "mvrilo/conduit-connector-pulsar",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/mvrilo/conduit-connector-pulsar",
+    "stargazer_count": 2,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "neha-Gupta1/conduit-connector-bigquery",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/neha-Gupta1/conduit-connector-bigquery",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "neovintage/conduit-connector-redis",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/neovintage/conduit-connector-redis",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "nstehr/conduit-connector-mqtt",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/nstehr/conduit-connector-mqtt",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "raulb/custom-conduit",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/raulb/custom-conduit",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "shubhamdixit863/Conduit-Connector-Apache-pulsar",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/shubhamdixit863/Conduit-Connector-Apache-pulsar",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  },
+  {
+    "name_with_owner": "tomialagbe/conduit-connector-influxdb",
+    "description": "",
+    "created_at": "",
+    "url": "https://github.com/tomialagbe/conduit-connector-influxdb",
+    "stargazer_count": 0,
+    "fork_count": 0,
+    "releases": null
+  }
+]
\ No newline at end of file
diff --git a/src/connectorgen/go.mod b/src/connectorgen/go.mod
index 3f2efcf9..f5d2f27b 100644
--- a/src/connectorgen/go.mod
+++ b/src/connectorgen/go.mod
@@ -10,6 +10,7 @@ require (
 	github.com/gofri/go-github-ratelimit v1.1.0
 	github.com/google/go-github/v67 v67.0.0
 	github.com/otiai10/gh-dependents v0.3.0
+	gopkg.in/yaml.v3 v3.0.1
 )
 
 require (
diff --git a/src/connectorgen/main.go b/src/connectorgen/main.go
index f19760bb..d0dab649 100644
--- a/src/connectorgen/main.go
+++ b/src/connectorgen/main.go
@@ -42,11 +42,13 @@ func main() {
 			}
 
 			outputPath := cmd.Flag("output-path").Value.String()
+			deniedPath := cmd.Flag("denied-path").Value.String()
 
-			return NewCommandRegistry(githubClient, outputPath).Execute(cmd.Context())
+			return NewCommandRegistry(githubClient, outputPath, deniedPath).Execute(cmd.Context())
 		},
 	}
 	cmdRegistry.Flags().StringP("output-path", "o", "./connectors.json", "path where the output file will be written")
+	cmdRegistry.Flags().StringP("denied-path", "d", "", "path where the denied connectors file will be written (skipped by default)")
 
 	cmdSpecifications := &cobra.Command{
 		Use:   "specifications",
diff --git a/src/connectorgen/registry-config.yaml b/src/connectorgen/registry-config.yaml
new file mode 100644
index 00000000..94044bc3
--- /dev/null
+++ b/src/connectorgen/registry-config.yaml
@@ -0,0 +1,23 @@
+# Only repositories on the allow list will be added to the registry.
+# The allow list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+allow:
+  # Allow Meroxa and Conduit organizations
+  - ConduitIO/conduit-connector-*
+  - conduitio-labs/conduit-connector-*
+  - meroxa/conduit-connector-*
+
+  # Individual repositories
+  - derElektrobesen/conduit-connector-tarantool
+  - lovromazgon/conduit-connector-kafka-broker
+  - nickchomey/conduit-connector-surrealdb
+
+# The deny list is used to exclude specific repositories from the allow list.
+# The deny list takes precedence over the allow list.
+# The deny list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+deny:
+  # Deny specific repositories that are allowed in the orgs above
+  - ConduitIO/conduit-connector-template
diff --git a/src/connectorgen/registry.go b/src/connectorgen/registry.go
index bfa1d125..0cee3a57 100644
--- a/src/connectorgen/registry.go
+++ b/src/connectorgen/registry.go
@@ -16,9 +16,11 @@ package main
 
 import (
 	"context"
+	_ "embed"
 	"encoding/json"
 	"fmt"
 	"os"
+	"regexp"
 	"slices"
 	"sort"
 	"strings"
@@ -26,43 +28,13 @@ import (
 
 	"github.com/google/go-github/v67/github"
 	"github.com/otiai10/gh-dependents/ghdeps"
+	"gopkg.in/yaml.v3"
 )
 
-var connectorSdkRepoOwnerWithName = "conduitio/conduit-connector-sdk"
+//go:embed registry-config.yaml
+var registryConfigYaml []byte
 
-var excludedRepositories = []string{
-	"ConduitIO/conduit",
-	"ConduitIO/streaming-benchmarks",
-	"ConduitIO/conduit-connector-template",
-	"ConduitIO/conduit-operator",
-	"ConduitIO/conduit-site",
-	// Test modules within the SDK use SDK as a dependency,
-	// so the SDK is included as a dependent of itself.
-	"ConduitIO/conduit-connector-sdk",
-
-	"ahamidi/conduit-connector-template",
-	"gopherslab/conduit-connector-google-sheets",
-	"gopherslab/conduit-connector-zendesk",
-	"gopherslab/conduit-connector-redis",
-	"hariso/conduit-connector-s3",
-	"hariso/conduit-connector-kafka",
-	"hariso/conduit-connector-foo",
-	"hariso/foobar",
-	"neha-Gupta1/conduit-connector-bigquery",
-	"neovintage/conduit-connector-redis",
-	"tsinghgill/conduit-connector-notion",
-	"WeirdMagician/conduit-connector-google-cloudstorage",
-	"GevorgGal/conduit-connector-influxdb",
-	"EnigmaForLife/shared",
-	"frillyrequi/conduit-connector-sdk",
-	"hariso/crispy-octo-system",
-	"hariso/cuddly-chainsaw",
-	"hariso/reimagined-octo-umbrella",
-	"derElektrobesen/mysql-migrator",
-	"lovromazgon/conduit-connector-playground",
-	"raulb/custom-conduit",
-	"stupidraid/conduit-connector-postgres",
-}
+var connectorSdkRepoOwnerWithName = "conduitio/conduit-connector-sdk"
 
 // maps architectures found in asset names to GOARCH
 var assetArchToGOARCH = map[string]string{
@@ -157,27 +129,109 @@ type Asset struct {
 	Size            int       `json:"size"`
 }
 
+type registryConfig struct {
+	Allow []filterExpr `yaml:"allow"`
+	Deny  []filterExpr `yaml:"deny"`
+}
+
+type filterExpr struct {
+	org  *regexp.Regexp
+	repo *regexp.Regexp
+}
+
+func newFilterExpr(expr string) (filterExpr, error) {
+	expr = strings.TrimSpace(expr)
+	expr = strings.ToLower(expr)
+	parts := strings.Split(expr, "/")
+	if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
+		return filterExpr{}, fmt.Errorf("invalid filter expression, expected <org>/<repo>")
+	}
+
+	org, repo := parts[0], parts[1]
+
+	wildcardToRegex := func(pattern string) (*regexp.Regexp, error) {
+		// Escape all special regex characters
+		pattern = regexp.QuoteMeta(pattern)
+		// Replace escaped asterisks (\*) with .*
+		pattern = strings.ReplaceAll(pattern, "\\*", ".*")
+		// Anchor regular expression to match the entire string
+		pattern = "^" + pattern + "$"
+
+		return regexp.Compile(pattern)
+	}
+
+	orgRegex, err := wildcardToRegex(org)
+	if err != nil {
+		return filterExpr{}, fmt.Errorf("failed to compile org regex: %w", err)
+	}
+
+	repoRegex, err := wildcardToRegex(repo)
+	if err != nil {
+		return filterExpr{}, fmt.Errorf("failed to compile repo regex: %w", err)
+	}
+
+	return filterExpr{
+		org:  orgRegex,
+		repo: repoRegex,
+	}, nil
+}
+
+func (f filterExpr) Match(org, repo string) bool {
+	org = strings.ToLower(org)
+	repo = strings.ToLower(repo)
+	return f.org.MatchString(org) && f.repo.MatchString(repo)
+}
+
 type CommandRegistry struct {
-	client     *github.Client
-	outputFile string
+	client      *github.Client
+	allowedFile string
+	deniedFile  string
+
+	config registryConfig
 }
 
-func NewCommandRegistry(client *github.Client, outputFile string) *CommandRegistry {
+func NewCommandRegistry(client *github.Client, allowedFile, deniedFile string) *CommandRegistry {
 	return &CommandRegistry{
-		client:     client,
-		outputFile: outputFile,
+		client:      client,
+		allowedFile: allowedFile,
+		deniedFile:  deniedFile,
 	}
 }
 
 func (cmd *CommandRegistry) Execute(ctx context.Context) error {
+	var err error
+	cmd.config, err = cmd.parseConfig()
+	if err != nil {
+		return err
+	}
+
 	reposList, err := cmd.fetchDependents(connectorSdkRepoOwnerWithName)
 	if err != nil {
 		return fmt.Errorf("failed to fetch dependent repositories: %w", err)
 	}
 
-	var repositories []Repository
-	for _, repo := range reposList {
-		fmt.Printf("\n🕵  Processing repository %v\n", repo)
+	allowed, denied := cmd.filterRepos(reposList)
+
+	if err = cmd.processAllowedRepositories(ctx, allowed); err != nil {
+		return fmt.Errorf("failed to process allowed repositories: %w", err)
+	}
+
+	if cmd.deniedFile != "" {
+		if err = cmd.processDeniedRepositories(ctx, denied); err != nil {
+			return fmt.Errorf("failed to process denied repositories: %w", err)
+		}
+	} else {
+		fmt.Println("⏭️ Skipping denied repositories")
+	}
+
+	fmt.Println("✅ Done")
+	return nil
+}
+
+func (cmd *CommandRegistry) processAllowedRepositories(ctx context.Context, repos []ghdeps.Repository) error {
+	repositories := make([]Repository, len(repos))
+	for i, repo := range repos {
+		fmt.Printf("\n🕵  Processing repository %v/%v\n", repo.User, repo.Repo)
 
 		repoInfo, err := cmd.fetchRepoInfo(ctx, repo)
 		if err != nil {
@@ -190,10 +244,10 @@ func (cmd *CommandRegistry) Execute(ctx context.Context) error {
 		}
 
 		repoInfo.Releases = releases
-		repositories = append(repositories, repoInfo)
+		repositories[i] = repoInfo
 	}
 
-	fmt.Printf("\n🪚 Building %s ...\n", cmd.outputFile)
+	fmt.Printf("\n🪚 Building %s ...\n", cmd.allowedFile)
 	slices.SortFunc(repositories, func(a, b Repository) int {
 		return strings.Compare(a.URL, b.URL)
 	})
@@ -202,16 +256,71 @@ func (cmd *CommandRegistry) Execute(ctx context.Context) error {
 		return fmt.Errorf("failed to marshal repositories to JSON: %w", err)
 	}
 
-	err = os.WriteFile(cmd.outputFile, connectorsJSON, 0644)
+	err = os.WriteFile(cmd.allowedFile, connectorsJSON, 0644)
 	if err != nil {
-		return fmt.Errorf("failed to write %s: %w", cmd.outputFile, err)
+		return fmt.Errorf("failed to write %s: %w", cmd.allowedFile, err)
+	}
+
+	return nil
+}
+
+func (cmd *CommandRegistry) processDeniedRepositories(ctx context.Context, repos []ghdeps.Repository) error {
+	repositories := make([]Repository, len(repos))
+	for i, repo := range repos {
+		repositories[i] = Repository{
+			NameWithOwner: repo.User + "/" + repo.Repo,
+			URL:           fmt.Sprintf("https://github.com/%s/%s", repo.User, repo.Repo),
+			Stargazers:    repo.Stars,
+			Forks:         repo.Forks,
+		}
+	}
+
+	fmt.Printf("\n🪚 Building denied connectors file %s ...\n", cmd.deniedFile)
+	slices.SortFunc(repositories, func(a, b Repository) int {
+		return strings.Compare(a.URL, b.URL)
+	})
+	connectorsJSON, err := json.MarshalIndent(repositories, "", "  ")
+	if err != nil {
+		return fmt.Errorf("failed to marshal repositories to JSON: %w", err)
+	}
+
+	err = os.WriteFile(cmd.deniedFile, connectorsJSON, 0644)
+	if err != nil {
+		return fmt.Errorf("failed to write %s: %w", cmd.deniedFile, err)
 	}
 
-	fmt.Println("✅ Done")
 	return nil
 }
 
-func (cmd *CommandRegistry) fetchDependents(repo string) ([]string, error) {
+func (cmd *CommandRegistry) parseConfig() (registryConfig, error) {
+	var tmp struct {
+		Allow []string `yaml:"allow"`
+		Deny  []string `yaml:"deny"`
+	}
+	if err := yaml.Unmarshal(registryConfigYaml, &tmp); err != nil {
+		return registryConfig{}, fmt.Errorf("failed to parse registry-config.yaml: %w", err)
+	}
+
+	var cfg registryConfig
+	for _, expr := range tmp.Allow {
+		fe, err := newFilterExpr(expr)
+		if err != nil {
+			return registryConfig{}, fmt.Errorf("failed to parse allow expression %q: %w", expr, err)
+		}
+		cfg.Allow = append(cfg.Allow, fe)
+	}
+	for _, expr := range tmp.Deny {
+		fe, err := newFilterExpr(expr)
+		if err != nil {
+			return registryConfig{}, fmt.Errorf("failed to parse deny expression %q: %w", expr, err)
+		}
+		cfg.Deny = append(cfg.Deny, fe)
+	}
+
+	return cfg, nil
+}
+
+func (cmd *CommandRegistry) fetchDependents(repo string) ([]ghdeps.Repository, error) {
 	fmt.Println("📥 Fetching dependents ...")
 
 	c := ghdeps.NewCrawler(repo)
@@ -219,23 +328,41 @@ func (cmd *CommandRegistry) fetchDependents(repo string) ([]string, error) {
 		return nil, err
 	}
 
-	var reposList []string
-	for _, dependent := range c.Dependents {
-		name := dependent.User + "/" + dependent.Repo
-		if !slices.Contains(excludedRepositories, name) {
-			reposList = append(reposList, name)
+	sort.Slice(c.Dependents, func(i, j int) bool {
+		return strings.Compare(c.Dependents[i].User+"/"+c.Dependents[i].Repo, c.Dependents[j].User+"/"+c.Dependents[j].Repo) < 0
+	})
+
+	return c.Dependents, nil
+}
+
+// filterRepos filters the repositories based on the allow and deny lists in
+// the config.
+func (cmd *CommandRegistry) filterRepos(repos []ghdeps.Repository) (allowed []ghdeps.Repository, denied []ghdeps.Repository) {
+REPOS:
+	for _, repo := range repos {
+		for _, denyExpr := range cmd.config.Deny {
+			if denyExpr.Match(repo.User, repo.Repo) {
+				denied = append(denied, repo)
+				continue REPOS
+			}
 		}
+		for _, allowExpr := range cmd.config.Allow {
+			if allowExpr.Match(repo.User, repo.Repo) {
+				allowed = append(allowed, repo)
+				continue REPOS
+			}
+		}
+		// If no allow or deny expression matched, add to denied list
+		denied = append(denied, repo)
 	}
 
-	sort.Strings(reposList)
-
-	return reposList, nil
+	return allowed, denied
 }
 
-func (cmd *CommandRegistry) fetchRepoInfo(ctx context.Context, repo string) (Repository, error) {
+func (cmd *CommandRegistry) fetchRepoInfo(ctx context.Context, repo ghdeps.Repository) (Repository, error) {
 	fmt.Println("  📥 Fetching repository information ...")
 
-	repoInfo, _, err := cmd.client.Repositories.Get(ctx, strings.Split(repo, "/")[0], strings.Split(repo, "/")[1])
+	repoInfo, _, err := cmd.client.Repositories.Get(ctx, repo.User, repo.Repo)
 	if err != nil {
 		return Repository{}, err
 	}
@@ -250,16 +377,10 @@ func (cmd *CommandRegistry) fetchRepoInfo(ctx context.Context, repo string) (Rep
 	}, nil
 }
 
-func (cmd *CommandRegistry) fetchReleases(ctx context.Context, ownerRepo string) ([]Release, error) {
+func (cmd *CommandRegistry) fetchReleases(ctx context.Context, repo ghdeps.Repository) ([]Release, error) {
 	fmt.Println("  📥 Fetching releases ...")
 
-	owner, repoName := strings.Split(ownerRepo, "/")[0], strings.Split(ownerRepo, "/")[1]
-	ghReleases, _, err := cmd.client.Repositories.ListReleases(
-		ctx,
-		owner,
-		repoName,
-		nil,
-	)
+	ghReleases, _, err := cmd.client.Repositories.ListReleases(ctx, repo.User, repo.Repo, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -269,7 +390,7 @@ func (cmd *CommandRegistry) fetchReleases(ctx context.Context, ownerRepo string)
 	}
 
 	// Fetch the latest release
-	latestRel, _, err := cmd.client.Repositories.GetLatestRelease(ctx, owner, repoName)
+	latestRel, _, err := cmd.client.Repositories.GetLatestRelease(ctx, repo.User, repo.Repo)
 	if err != nil && !is404Error(err) {
 		return nil, fmt.Errorf("failed to fetch latest release: %w", err)
 	}
@@ -288,7 +409,7 @@ func (cmd *CommandRegistry) fetchReleases(ctx context.Context, ownerRepo string)
 			IsLatest:    isLatest,
 		}
 
-		releaseAssets, err := cmd.fetchReleaseAssets(ctx, ownerRepo, ghRel)
+		releaseAssets, err := cmd.fetchReleaseAssets(ctx, repo, ghRel)
 		if err != nil {
 			return nil, fmt.Errorf("failed fetching assets for release %v: %w", ghRel.GetTagName(), err)
 		}
@@ -300,16 +421,10 @@ func (cmd *CommandRegistry) fetchReleases(ctx context.Context, ownerRepo string)
 	return releasesList, nil
 }
 
-func (cmd *CommandRegistry) fetchReleaseAssets(ctx context.Context, repo string, release *github.RepositoryRelease) ([]Asset, error) {
+func (cmd *CommandRegistry) fetchReleaseAssets(ctx context.Context, repo ghdeps.Repository, release *github.RepositoryRelease) ([]Asset, error) {
 	fmt.Printf("    📥 Fetching release assets for %v ...\n", release.GetTagName())
 
-	assets, _, err := cmd.client.Repositories.ListReleaseAssets(
-		ctx,
-		strings.Split(repo, "/")[0],
-		strings.Split(repo, "/")[1],
-		release.GetID(),
-		nil,
-	)
+	assets, _, err := cmd.client.Repositories.ListReleaseAssets(ctx, repo.User, repo.Repo, release.GetID(), nil)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/connectorgen/registry_test.go b/src/connectorgen/registry_test.go
new file mode 100644
index 00000000..4aa1b391
--- /dev/null
+++ b/src/connectorgen/registry_test.go
@@ -0,0 +1,223 @@
+// Copyright © 2025 Meroxa, 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.
+
+package main
+
+import "testing"
+
+func TestNewFilterExpr(t *testing.T) {
+	tests := []struct {
+		name        string
+		filterStr   string
+		shouldError bool
+	}{
+		{
+			name:        "valid filter",
+			filterStr:   "org/repo",
+			shouldError: false,
+		},
+		{
+			name:        "valid filter with wildcards",
+			filterStr:   "org*/repo*",
+			shouldError: false,
+		},
+		{
+			name:        "missing repo",
+			filterStr:   "org/",
+			shouldError: true,
+		},
+		{
+			name:        "missing org",
+			filterStr:   "/repo",
+			shouldError: true,
+		},
+		{
+			name:        "no separator",
+			filterStr:   "orgrepo",
+			shouldError: true,
+		},
+		{
+			name:        "empty string",
+			filterStr:   "",
+			shouldError: true,
+		},
+		{
+			name:        "just a slash",
+			filterStr:   "/",
+			shouldError: true,
+		},
+		{
+			name:        "spaces should be trimmed",
+			filterStr:   "  org/repo  ",
+			shouldError: false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			_, err := newFilterExpr(tt.filterStr)
+			if (err != nil) != tt.shouldError {
+				t.Errorf("newFilterExpr(%q) error = %v, shouldError %v", tt.filterStr, err, tt.shouldError)
+			}
+		})
+	}
+}
+
+func TestFilterExprMatch(t *testing.T) {
+	tests := []struct {
+		name      string
+		filterStr string
+		matches   []struct {
+			org      string
+			repo     string
+			expected bool
+		}
+	}{
+		{
+			name:      "exact match",
+			filterStr: "kubernetes/kubernetes",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"kubernetes", "kubernetes", true},
+				{"kubernetes", "k8s", false},
+				{"k8s", "kubernetes", false},
+				{"fookubernetes", "kubernetes", false},
+				{"kubernetesfoo", "kubernetes", false},
+				{"kubernetes", "fookubernetes", false},
+				{"kubernetes", "kubernetesfoo", false},
+			},
+		},
+		{
+			name:      "org wildcard",
+			filterStr: "kube*/kubernetes",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"kubernetes", "kubernetes", true},
+				{"kubeflow", "kubernetes", true},
+				{"kube", "kubernetes", true},
+				{"k8s", "kubernetes", false},
+			},
+		},
+		{
+			name:      "repo wildcard",
+			filterStr: "kubernetes/*flow",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"kubernetes", "kubeflow", true},
+				{"kubernetes", "tensorflow", true},
+				{"kubernetes", "flow", true},
+				{"kubernetes", "kubernetes", false},
+				{"k8s", "kubeflow", false},
+			},
+		},
+		{
+			name:      "both wildcards",
+			filterStr: "kube*/*flow",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"kubernetes", "kubeflow", true},
+				{"kubeflow", "tensorflow", true},
+				{"kube", "flow", true},
+				{"google", "tensorflow", false},
+				{"kube", "test", false},
+			},
+		},
+		{
+			name:      "wildcard in middle",
+			filterStr: "k*s/te*st",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"k8s", "test", true},
+				{"kubernetes", "te-st", true},
+				{"kbs", "terwest", true},
+				{"kas", "test", true},
+				{"k8s", "tst", false},
+			},
+		},
+		{
+			name:      "multiple wildcards",
+			filterStr: "*hub/*-*",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"github", "test-repo", true},
+				{"githubhub", "my-project", true},
+				{"hub", "a-b", true},
+				{"github", "repo", false},
+				{"gitlab", "test-repo", false},
+			},
+		},
+		{
+			name:      "special regex characters",
+			filterStr: "org.name/repo+name",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"org.name", "repo+name", true},
+				{"orgxname", "repo+name", false},
+				{"org.name", "reponame", false},
+			},
+		},
+		{
+			name:      "conduit use case",
+			filterStr: "conduitio/conduit-connector-*",
+			matches: []struct {
+				org      string
+				repo     string
+				expected bool
+			}{
+				{"conduitio", "conduit-connector-file", true},
+				{"ConduitIO", "conduit-connector-foo", true},
+				{"conduitio", "conduit", false},
+				{"conduitio", "streaming-benchmarks", false},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			filter, err := newFilterExpr(tt.filterStr)
+			if err != nil {
+				t.Fatalf("Failed to create filter expression: %v", err)
+			}
+
+			for _, m := range tt.matches {
+				got := filter.Match(m.org, m.repo)
+				if got != m.expected {
+					t.Errorf("filter %q.Match(%q, %q) = %v, want %v",
+						tt.filterStr, m.org, m.repo, got, m.expected)
+				}
+			}
+		})
+	}
+}
diff --git a/src/connectorgen/specifications.go b/src/connectorgen/specifications.go
index fcadb169..2ae75225 100644
--- a/src/connectorgen/specifications.go
+++ b/src/connectorgen/specifications.go
@@ -97,7 +97,7 @@ func (cmd *CommandSpecifications) Execute(ctx context.Context) error {
 			// Check if connector.yaml already exists
 			commitSHA, err := cmd.getCommitForTag(ctx, owner, repoName, release.TagName)
 			if err != nil {
-				fmt.Printf("  ❌ Error: failed to get commit for tag %s: %w\n", release.TagName, err)
+				fmt.Printf("  ❌ Error: failed to get commit for tag %s: %v\n", release.TagName, err)
 				continue
 			}
 
@@ -114,7 +114,7 @@ func (cmd *CommandSpecifications) Execute(ctx context.Context) error {
 					repo.NameWithOwner, release.TagName)
 				// Still write the metadata file
 			} else if err != nil {
-				fmt.Printf("  ❌ Error: failed to fetch connector.yaml for %s@%s: %w\n",
+				fmt.Printf("  ❌ Error: failed to fetch connector.yaml for %s@%s: %v\n",
 					repo.NameWithOwner, release.TagName, err)
 				continue
 			}
@@ -179,7 +179,7 @@ func (cmd *CommandSpecifications) getCommitForTag(ctx context.Context, owner, re
 	// Get the reference to the specific tag
 	ref, _, err := cmd.client.Git.GetRef(ctx, owner, repo, refName)
 	if err != nil {
-		log.Fatalf("failed to fetch reference for tag %s: %w", tag, err)
+		log.Fatalf("failed to fetch reference for tag %s: %v", tag, err)
 	}
 
 	// Determine the commit SHA
@@ -188,7 +188,7 @@ func (cmd *CommandSpecifications) getCommitForTag(ctx context.Context, owner, re
 		// Resolve the object the tag refers to
 		object, _, err := cmd.client.Git.GetTag(ctx, owner, repo, *ref.Object.SHA)
 		if err != nil {
-			log.Fatalf("failed to fetch annotated tag object for %s: %w", tag, err)
+			log.Fatalf("failed to fetch annotated tag object for %s: %v", tag, err)
 		}
 
 		commitSHA = *object.Object.SHA
diff --git a/static/connectors.json b/static/connectors.json
index 1a33da5f..7194344a 100644
--- a/static/connectors.json
+++ b/static/connectors.json
@@ -2124,7 +2124,7 @@
     "description": "Conduit connector for Apache Kafka",
     "created_at": "2022-02-22 13:02:13 +0000 UTC",
     "url": "https://github.com/ConduitIO/conduit-connector-kafka",
-    "stargazer_count": 8,
+    "stargazer_count": 9,
     "fork_count": 4,
     "releases": [
       {
@@ -6754,7 +6754,7 @@
     "description": "Conduit connector for Amazon S3",
     "created_at": "2022-02-17 14:40:01 +0000 UTC",
     "url": "https://github.com/ConduitIO/conduit-connector-s3",
-    "stargazer_count": 8,
+    "stargazer_count": 9,
     "fork_count": 4,
     "releases": [
       {
@@ -7759,69 +7759,6 @@
       }
     ]
   },
-  {
-    "name_with_owner": "ViniciusMiana/conduit-connector-pulsar",
-    "description": "Provides a source and a destination Pulsar connector, for Conduit.",
-    "created_at": "2023-12-07 00:47:43 +0000 UTC",
-    "url": "https://github.com/ViniciusMiana/conduit-connector-pulsar",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "ahamidi/conduit-connector-neo4j",
-    "description": "Conduit Connector Plugin for Neo4j",
-    "created_at": "2022-02-28 18:10:29 +0000 UTC",
-    "url": "https://github.com/ahamidi/conduit-connector-neo4j",
-    "stargazer_count": 2,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "ahamidi/conduit-connector-pulsar",
-    "description": "",
-    "created_at": "2022-10-14 15:37:25 +0000 UTC",
-    "url": "https://github.com/ahamidi/conduit-connector-pulsar",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "ahamidi/conduit-connector-redis",
-    "description": "",
-    "created_at": "2022-03-03 20:54:43 +0000 UTC",
-    "url": "https://github.com/ahamidi/conduit-connector-redis",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "ahamidi/conduit-connector-rockset",
-    "description": "Rockset connector for Conduit",
-    "created_at": "2023-05-09 21:06:24 +0000 UTC",
-    "url": "https://github.com/ahamidi/conduit-connector-rockset",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "alejandromav/conduit-connector-tinybird",
-    "description": "Tinybird Conduit Connector",
-    "created_at": "2022-10-24 19:33:56 +0000 UTC",
-    "url": "https://github.com/alejandromav/conduit-connector-tinybird",
-    "stargazer_count": 1,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "brharrelldev/pulsar-connector",
-    "description": "Testing out ConduitIO framework for fun",
-    "created_at": "2023-12-18 06:01:07 +0000 UTC",
-    "url": "https://github.com/brharrelldev/pulsar-connector",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
   {
     "name_with_owner": "conduitio-labs/conduit-connector-activemq-artemis",
     "description": "Conduit connector for ActiveMQ Artemis",
@@ -8600,7 +8537,7 @@
   },
   {
     "name_with_owner": "conduitio-labs/conduit-connector-box",
-    "description": "Conduit connector for the box content management system",
+    "description": "Conduit connector for the Box content management system",
     "created_at": "2025-04-01 05:26:17 +0000 UTC",
     "url": "https://github.com/conduitio-labs/conduit-connector-box",
     "stargazer_count": 0,
@@ -16339,42 +16276,6 @@
     "fork_count": 0,
     "releases": []
   },
-  {
-    "name_with_owner": "devarismeroxa/conduit-connector-box",
-    "description": "Conduit Connector for the Box API",
-    "created_at": "2025-03-24 20:47:18 +0000 UTC",
-    "url": "https://github.com/devarismeroxa/conduit-connector-box",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "devarismeroxa/conduit-connector-influxdb",
-    "description": "Conduit Connector for InfluxDB",
-    "created_at": "2025-03-18 22:57:56 +0000 UTC",
-    "url": "https://github.com/devarismeroxa/conduit-connector-influxdb",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "devarispbrown/conduit-connector-weaviate",
-    "description": "Conduit connector for Weaviate",
-    "created_at": "2023-07-13 07:27:26 +0000 UTC",
-    "url": "https://github.com/devarispbrown/conduit-connector-weaviate",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "hariso/custom-conduit",
-    "description": "",
-    "created_at": "2025-02-11 13:19:33 +0000 UTC",
-    "url": "https://github.com/hariso/custom-conduit",
-    "stargazer_count": 0,
-    "fork_count": 1,
-    "releases": []
-  },
   {
     "name_with_owner": "lovromazgon/conduit-connector-kafka-broker",
     "description": "Experimental connector that acts as a Kafka broker and accepts data produced by Kafka producers.",
@@ -16384,42 +16285,6 @@
     "fork_count": 0,
     "releases": []
   },
-  {
-    "name_with_owner": "maha-hajja/conduit-connector-slack",
-    "description": "destination for slack",
-    "created_at": "2023-05-12 10:30:43 +0000 UTC",
-    "url": "https://github.com/maha-hajja/conduit-connector-slack",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "mer-oscar/conduit-connector-azure-event-hub",
-    "description": "",
-    "created_at": "2024-02-16 18:07:18 +0000 UTC",
-    "url": "https://github.com/mer-oscar/conduit-connector-azure-event-hub",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "mer-oscar/conduit-connector-kinesis",
-    "description": "conduit connector for kinesis",
-    "created_at": "2024-02-05 07:21:55 +0000 UTC",
-    "url": "https://github.com/mer-oscar/conduit-connector-kinesis",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "mer-oscar/conduit-connector-zeromq",
-    "description": "",
-    "created_at": "2024-03-11 06:31:36 +0000 UTC",
-    "url": "https://github.com/mer-oscar/conduit-connector-zeromq",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
   {
     "name_with_owner": "meroxa/conduit-connector-spire-ais-public",
     "description": "",
@@ -16438,33 +16303,6 @@
     "fork_count": 0,
     "releases": []
   },
-  {
-    "name_with_owner": "miwialex/test-connector",
-    "description": "",
-    "created_at": "2025-03-26 15:23:41 +0000 UTC",
-    "url": "https://github.com/miwialex/test-connector",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "mtami/conduit-connector-pulsar",
-    "description": "Conduit connector for Apache Pulsar",
-    "created_at": "2023-11-18 13:44:37 +0000 UTC",
-    "url": "https://github.com/mtami/conduit-connector-pulsar",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "mvrilo/conduit-connector-pulsar",
-    "description": "",
-    "created_at": "2023-12-04 12:10:45 +0000 UTC",
-    "url": "https://github.com/mvrilo/conduit-connector-pulsar",
-    "stargazer_count": 2,
-    "fork_count": 0,
-    "releases": []
-  },
   {
     "name_with_owner": "nickchomey/conduit-connector-surrealdb",
     "description": "",
@@ -16473,32 +16311,5 @@
     "stargazer_count": 1,
     "fork_count": 1,
     "releases": []
-  },
-  {
-    "name_with_owner": "nstehr/conduit-connector-mqtt",
-    "description": "",
-    "created_at": "2024-12-09 16:39:17 +0000 UTC",
-    "url": "https://github.com/nstehr/conduit-connector-mqtt",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "shubhamdixit863/Conduit-Connector-Apache-pulsar",
-    "description": "",
-    "created_at": "2023-11-28 12:37:27 +0000 UTC",
-    "url": "https://github.com/shubhamdixit863/Conduit-Connector-Apache-pulsar",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
-  },
-  {
-    "name_with_owner": "tomialagbe/conduit-connector-influxdb",
-    "description": "Influxdb destination connector for conduit",
-    "created_at": "2024-06-05 09:08:38 +0000 UTC",
-    "url": "https://github.com/tomialagbe/conduit-connector-influxdb",
-    "stargazer_count": 0,
-    "fork_count": 0,
-    "releases": []
   }
 ]
\ No newline at end of file


Reviews:
user: login: raulb
body: Thanks @lovromazgon for taking care of this.

Left a comment below which is related to something else I thought when I looked at the denied-connectors.json. I think we should update the criteria to _what's considered a connector_ (which I think we should standardize as `conduit-connector-*`) to make our lives easier. 

It seems like we we have exceptions to make on repositories that don't look like a connector (e.g.: `raulb/custom-conduit`). 

What I was thinking was:

**Allow list:**

- ConduitIO/conduit-connector-*
- conduitio-labs/conduit-connector-*
- meroxa/conduit-connector-*

Individual exceptions (added manually)

_Everything else is denied_

What do you think?
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T08:58:20Z
user: login: lovromazgon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T10:29:05Z
user: login: lovromazgon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T12:14:37Z
user: login: raulb
body: @lovromazgon looks great!

Only one comment before approving. It is my understanding that with the recent changes, technically speaking, we would only need to add to the list of `defined-connectors.json` `ConduitIO/conduit-connector-template`, right?

If we want to explicitly call out some contributors we could, but I don't think that's needed? We could also remove other owned repositories such as `ConduitIO/conduit`, `ConduitIO/conduit-operator`...
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T14:21:58Z
user: login: raulb
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:14:46Z

Review comments:
diff_hunk: @@ -0,0 +1,27 @@
+# Only repositories on the allow list will be added to the registry.
+# The allow list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+allow:
+  # Allow Meroxa and Conduit organizations
+  - ConduitIO/*
+  - conduitio-labs/*
+  - meroxa/*
+
+  # Individual repositories
+  - derElektrobesen/conduit-connector-tarantool
+  - lovromazgon/conduit-connector-kafka-broker
+  - nickchomey/conduit-connector-surrealdb
+
+# The deny list is used to exclude specific repositories from the allow list.
+# The deny list takes precedence over the allow list.
+# The deny list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+deny:
+  # Deny specific repositories that are allowed in the orgs above
path: src/connectorgen/registry-config.yaml
user: login: raulb
body: Could we, instead of individually denying specific repositories, maybe only allow those that follow the format:

  - ConduitIO/conduit-connector-*
  - conduitio-labs/conduit-connector-*
  - meroxa/conduit-connector-*

This way, we wouldn't need to worry about manually updating this list on any other repository we might (we will) create in the future on any of these orgs.
created_at: 2025-04-23T08:53:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,27 @@
+# Only repositories on the allow list will be added to the registry.
+# The allow list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+allow:
+  # Allow Meroxa and Conduit organizations
+  - ConduitIO/*
+  - conduitio-labs/*
+  - meroxa/*
+
+  # Individual repositories
+  - derElektrobesen/conduit-connector-tarantool
+  - lovromazgon/conduit-connector-kafka-broker
+  - nickchomey/conduit-connector-surrealdb
+
+# The deny list is used to exclude specific repositories from the allow list.
+# The deny list takes precedence over the allow list.
+# The deny list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+deny:
+  # Deny specific repositories that are allowed in the orgs above
path: src/connectorgen/registry-config.yaml
user: login: lovromazgon
body: Good idea! I'll add the change 👍
created_at: 2025-04-23T10:29:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,27 @@
+# Only repositories on the allow list will be added to the registry.
+# The allow list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+allow:
+  # Allow Meroxa and Conduit organizations
+  - ConduitIO/*
+  - conduitio-labs/*
+  - meroxa/*
+
+  # Individual repositories
+  - derElektrobesen/conduit-connector-tarantool
+  - lovromazgon/conduit-connector-kafka-broker
+  - nickchomey/conduit-connector-surrealdb
+
+# The deny list is used to exclude specific repositories from the allow list.
+# The deny list takes precedence over the allow list.
+# The deny list can either contain a string that matches the repository name
+# or an organization name with a wildcard (*) as the repository name.
+# The comparison will be case-insensitive.
+deny:
+  # Deny specific repositories that are allowed in the orgs above
path: src/connectorgen/registry-config.yaml
user: login: lovromazgon
body: See https://github.com/ConduitIO/conduit-site/pull/270/commits/debb06d465c86599d070a758f794b6b7913a484d 👍 
created_at: 2025-04-23T12:14:37Z
author_association: CONTRIBUTOR

PR comments:
user: login: cloudflare-workers-and-pages[bot]
created_at: 2025-04-23T12:13:55Z
body: ## Deploying conduit-site with &nbsp;<a href="https://pages.dev"><img alt="Cloudflare Pages" src="https://user-images.githubusercontent.com/23264/106598434-9e719e00-654f-11eb-9e59-6167043cfa01.png" width="16"></a> &nbsp;Cloudflare Pages

<table><tr><td><strong>Latest commit:</strong> </td><td>
<code>debb06d</code>
</td></tr>
<tr><td><strong>Status:</strong></td><td>&nbsp;✅&nbsp; Deploy successful!</td></tr>
<tr><td><strong>Preview URL:</strong></td><td>
<a href='https://f19d84b8.conduit-site.pages.dev'>https://f19d84b8.conduit-site.pages.dev</a>
</td></tr>
<tr><td><strong>Branch Preview URL:</strong></td><td>
<a href='https://lovro-allowed-denied-connect.conduit-site.pages.dev'>https://lovro-allowed-denied-connect.conduit-site.pages.dev</a>
</td></tr>
</table>

[View logs](https://dash.cloudflare.com/55feb54bc16a3c38121da3038f86bfe7/pages/view/conduit-site/f19d84b8-962d-4737-acee-8904889e218d)

author_association: NONE
user: login: raulb
created_at: 2025-04-23T16:15:22Z
body: > @lovromazgon looks great!
> 
> Only one comment before approving. It is my understanding that with the recent changes, technically speaking, we would only need to add to the list of `defined-connectors.json` `ConduitIO/conduit-connector-template`, right?
> 
> If we want to explicitly call out some contributors we could, but I don't think that's needed? We could also remove other owned repositories such as `ConduitIO/conduit`, `ConduitIO/conduit-operator`...

Update: @lovromazgon and I talked about this today after standup, and clarified my comments. Approved 🚀 
author_association: CONTRIBUTOR