Skip to content

Commit ccd3cf8

Browse files
authored
Add org filter to webhook. (#476)
We need to test out behavior in the webhook, but we're not 100% confident it's working as intended as is. This adds a configurable filter to enable selective responses to certain orgs. For now, have the default deployment only look at octo-sts and chainguard-dev orgs.
1 parent b091cb2 commit ccd3cf8

File tree

6 files changed

+55
-0
lines changed

6 files changed

+55
-0
lines changed

cmd/webhook/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,18 @@ func main() {
8181
webhookSecrets = [][]byte{[]byte(webhookConfig.WebhookSecret)}
8282
}
8383

84+
var orgs []string
85+
for _, s := range strings.Split(webhookConfig.OrganizationFilter, ",") {
86+
if o := strings.TrimSpace(s); o != "" {
87+
orgs = append(orgs, o)
88+
}
89+
}
90+
8491
mux := http.NewServeMux()
8592
mux.Handle("/", &webhook.Validator{
8693
Transport: atr,
8794
WebhookSecret: webhookSecrets,
95+
Organizations: orgs,
8896
})
8997
srv := &http.Server{
9098
Addr: fmt.Sprintf(":%d", baseCfg.Port),

iac/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ module "app" {
6666
github_app_id = var.github_app_id
6767
github_app_key_version = 1
6868
notification_channels = local.notification_channels
69+
// Testing out behavior, will remove once we confirm things are working.
70+
github_webhook_organization_filter = "octo-sts,chainguard-dev"
6971
}

modules/app/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,9 @@ variable "notification_channels" {
5555
description = "List of notification channels to alert."
5656
type = list(string)
5757
}
58+
59+
variable "github_webhook_organization_filter" {
60+
description = "The organizations to filter webhook events on (comma separated)."
61+
type = string
62+
default = ""
63+
}

modules/app/webhook.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ module "webhook" {
4545
name = "GITHUB_WEBHOOK_SECRET"
4646
value = module.webhook-secret.secret_version_id
4747
},
48+
{
49+
name = "GITHUB_WEBHOOK_ORGANIZATION_FILTER"
50+
value = var.github_webhook_organization_filter
51+
},
4852
{
4953
name = "KMS_KEY"
5054
value = local.kms_key

pkg/envconfig/envconfig.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type EnvConfigApp struct {
2525

2626
type EnvConfigWebhook struct {
2727
WebhookSecret string `envconfig:"WEBHOOK_SECRET" required:"true"`
28+
// If set, only process events from these organizations (comma separated).
29+
OrganizationFilter string `envconfig:"GITHUB_ORGANIZATION_FILTER"`
2830
}
2931

3032
func AppConfig() (*EnvConfigApp, error) {

pkg/webhook/webhook.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"mime"
1313
"net/http"
1414
"path/filepath"
15+
"strings"
1516
"time"
1617

1718
"github.com/bradleyfalzon/ghinstallation/v2"
@@ -41,6 +42,8 @@ type Validator struct {
4142
// Store multiple secrets to allow for rolling updates.
4243
// Only one needs to match for the event to be considered valid.
4344
WebhookSecret [][]byte
45+
46+
Organizations []string
4447
}
4548

4649
func (e *Validator) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -217,6 +220,12 @@ func (e *Validator) handlePush(ctx context.Context, event *github.PushEvent) (*g
217220
sha := event.GetAfter()
218221
installationID := event.GetInstallation().GetID()
219222

223+
// Skip if the organization is not in the list of organizations to validate.
224+
if e.shouldSkipOrganization(owner) {
225+
log.Infof("skipping organization %s", owner)
226+
return nil, nil
227+
}
228+
220229
client := github.NewClient(&http.Client{
221230
Transport: ghinstallation.NewFromAppsTransport(e.Transport, installationID),
222231
})
@@ -256,6 +265,12 @@ func (e *Validator) handlePullRequest(ctx context.Context, pr *github.PullReques
256265
sha := pr.GetPullRequest().GetHead().GetSHA()
257266
installationID := pr.GetInstallation().GetID()
258267

268+
// Skip if the organization is not in the list of organizations to validate.
269+
if e.shouldSkipOrganization(owner) {
270+
log.Infof("skipping organization %s", owner)
271+
return nil, nil
272+
}
273+
259274
client := github.NewClient(&http.Client{
260275
Transport: ghinstallation.NewFromAppsTransport(e.Transport, installationID),
261276
})
@@ -303,6 +318,12 @@ func (e *Validator) handleCheckSuite(ctx context.Context, cs checkSuite) (*githu
303318
sha := cs.GetCheckSuite().GetHeadSHA()
304319
installationID := cs.GetInstallation().GetID()
305320

321+
// Skip if the organization is not in the list of organizations to validate.
322+
if e.shouldSkipOrganization(owner) {
323+
log.Infof("skipping organization %s", owner)
324+
return nil, nil
325+
}
326+
306327
client := github.NewClient(&http.Client{
307328
Transport: ghinstallation.NewFromAppsTransport(e.Transport, installationID),
308329
})
@@ -355,3 +376,15 @@ var _ checkSuite = (*fauxCheckSuite)(nil)
355376
func (f *fauxCheckSuite) GetCheckSuite() *github.CheckSuite {
356377
return f.GetCheckRun().GetCheckSuite()
357378
}
379+
380+
func (e *Validator) shouldSkipOrganization(org string) bool {
381+
if len(e.Organizations) == 0 {
382+
return false
383+
}
384+
for _, o := range e.Organizations {
385+
if strings.EqualFold(o, org) {
386+
return false
387+
}
388+
}
389+
return true
390+
}

0 commit comments

Comments
 (0)