{"id":37210921,"url":"https://github.com/brigadecore/brigade-acr-gateway","last_synced_at":"2026-01-15T00:01:25.612Z","repository":{"id":39790278,"uuid":"397316278","full_name":"brigadecore/brigade-acr-gateway","owner":"brigadecore","description":"A Brigade 2 compatible gateway for events originating from Azure Container Registry","archived":true,"fork":false,"pushed_at":"2022-05-25T19:53:22.000Z","size":190,"stargazers_count":1,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-19T19:44:51.610Z","etag":null,"topics":["brigade","brigade-gateway","v2"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brigadecore.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null}},"created_at":"2021-08-17T16:04:36.000Z","updated_at":"2023-01-28T00:29:28.000Z","dependencies_parsed_at":"2022-08-25T19:02:42.846Z","dependency_job_id":null,"html_url":"https://github.com/brigadecore/brigade-acr-gateway","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/brigadecore/brigade-acr-gateway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brigadecore%2Fbrigade-acr-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brigadecore%2Fbrigade-acr-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brigadecore%2Fbrigade-acr-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brigadecore%2Fbrigade-acr-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brigadecore","download_url":"https://codeload.github.com/brigadecore/brigade-acr-gateway/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brigadecore%2Fbrigade-acr-gateway/sbom","scorecard":{"id":253672,"data":{"date":"2025-08-11","repo":{"name":"github.com/brigadecore/brigade-acr-gateway","commit":"dac46cd320a532d8f40e529d250b6dba2832fcc5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:20","Info:   0 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.4.1 not signed: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/63317847","Warn: release artifact v0.4.0 not signed: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/63087906","Warn: release artifact v0.4.0-rc.4 not signed: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/62693816","Warn: release artifact v0.4.0-rc.2 not signed: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/62628570","Warn: release artifact v0.4.1 does not have provenance: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/63317847","Warn: release artifact v0.4.0 does not have provenance: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/63087906","Warn: release artifact v0.4.0-rc.4 does not have provenance: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/62693816","Warn: release artifact v0.4.0-rc.2 does not have provenance: https://api.github.com/repos/brigadecore/brigade-acr-gateway/releases/62628570"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2024-2947 / GHSA-v6v8-xj6m-xwqh","Warn: Project is vulnerable to: GO-2022-0603 / GHSA-hp87-p4gw-j4gq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T09:05:07.602Z","repository_id":39790278,"created_at":"2025-08-17T09:05:07.603Z","updated_at":"2025-08-17T09:05:07.603Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28439605,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T22:37:52.437Z","status":"ssl_error","status_checked_at":"2026-01-14T22:37:31.496Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brigade","brigade-gateway","v2"],"created_at":"2026-01-15T00:01:24.946Z","updated_at":"2026-01-15T00:01:25.600Z","avatar_url":"https://github.com/brigadecore.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e ⚠️\u0026nbsp;\u0026nbsp;Most Azure resources, including Azure Container Registries, can\n\u003e be configured to deliver events to Brigade through the combination of\n\u003e [Azure Event Grid](https://docs.microsoft.com/en-us/azure/event-grid/overview),\n\u003e which is a CloudEvents 1.0-compliant event producer, and the\n\u003e [Brigade CloudEvents Gateway](https://github.com/brigadecore/brigade-cloudevents-gateway).\n\u003e\n\u003e With the CloudEvents Gateway supporting the same use cases as this one -- plus\n\u003e many more -- this gateway has been archived.\n\n# Brigade ACR Gateway\n\n![build](https://badgr.brigade2.io/v1/github/checks/brigadecore/brigade-acr-gateway/badge.svg?appID=99005)\n[![codecov](https://codecov.io/gh/brigadecore/brigade-acr-gateway/branch/main/graph/badge.svg?token=9J6ZWN52PI)](https://codecov.io/gh/brigadecore/brigade-acr-gateway)\n[![Go Report Card](https://goreportcard.com/badge/github.com/brigadecore/brigade-acr-gateway)](https://goreportcard.com/report/github.com/brigadecore/brigade-acr-gateway)\n[![slack](https://img.shields.io/badge/slack-brigade-brightgreen.svg?logo=slack)](https://kubernetes.slack.com/messages/C87MF1RFD)\n\n\u003cimg width=\"100\" align=\"left\" src=\"logo.png\"\u003e\n\nThis is a work-in-progress\n[Brigade 2](https://github.com/brigadecore/brigade/tree/v2)\ncompatible gateway that receives events (webhooks) from Azure Container Registry\nand propagates them into Brigade 2's event bus.\n\n\u003cbr clear=\"left\"/\u003e\n\n## Installation\n\nPrerequisites:\n\n* A Kubernetes cluster:\n    * For which you have the `admin` cluster role\n    * That is already running Brigade 2\n    * Capable of provisioning a _public IP address_ for a service of type\n      `LoadBalancer`. (This means you won't have much luck running the gateway\n      locally in the likes of kind or minikube unless you're able and willing to\n      mess with port forwarding settings on your router, which we won't be\n      covering here.)\n\n* `kubectl`, `helm` (commands below require Helm 3.7.0+), and `brig` (the\n  Brigade 2 CLI)\n\n### 1. Create a Service Account for the Gateway\n\n__Note:__ To proceed beyond this point, you'll need to be logged into Brigade 2\nas the \"root\" user (not recommended) or (preferably) as a user with the `ADMIN`\nrole. Further discussion of this is beyond the scope of this documentation.\nPlease refer to Brigade's own documentation.\n\nUsing Brigade 2's `brig` CLI, create a service account for the gateway to use:\n\n```shell\n$ brig service-account create \\\n    --id brigade-acr-gateway \\\n    --description brigade-acr-gateway\n```\n\nMake note of the __token__ returned. This value will be used in another step.\n_It is your only opportunity to access this value, as Brigade does not save it._\n\nAuthorize this service account to create new events:\n\n```shell\n$ brig role grant EVENT_CREATOR \\\n    --service-account brigade-acr-gateway \\\n    --source brigade.sh/acr\n```\n\n__Note:__ The `--source brigade.sh/acr` option specifies that\nthis service account can be used _only_ to create events having a value of\n`brigade.sh/acr` in the event's `source` field. _This is a\nsecurity measure that prevents the gateway from using this token for\nimpersonating other gateways._\n\n### 2. Install the ACR Gateway\n\nFor now, we're using the [GitHub Container Registry](https://ghcr.io) (which is\nan [OCI registry](https://helm.sh/docs/topics/registries/)) to host our Helm\nchart. Helm 3.7 has _experimental_ support for OCI registries. In the event that\nthe Helm 3.7 dependency proves troublesome for users, or in the event that this\nexperimental feature goes away, or isn't working like we'd hope, we will revisit\nthis choice before going GA.\n\nFirst, be sure you are using\n[Helm 3.7.0](https://github.com/helm/helm/releases/tag/v3.7.0) or greater and\nenable experimental OCI support:\n\n```shell\n$ export HELM_EXPERIMENTAL_OCI=1\n```\n\nAs this chart requires custom configuration as described above to function\nproperly, we'll need to create a chart values file with said config.\n\nUse the following command to extract the full set of configuration options into\na file you can modify:\n\n```shell\n$ helm inspect values oci://ghcr.io/brigadecore/brigade-acr-gateway \\\n    --version v0.4.1 \u003e ~/brigade-acr-gateway-values.yaml\n```\n\nEdit `~/brigade-acr-gateway-values.yaml`, making the following changes:\n\n* `host`: Set this to the host name where you'd like the gateway to be\n  accessible.\n\n* `brigade.apiAddress`: Address of the Brigade API server, beginning with\n  `https://`\n\n* `brigade.apiToken`: Service account token from step 2\n\n* `service.type`: If you plan to enable ingress (advanced), you can leave this\n  as its default -- `ClusterIP`. If you do not plan to enable ingress, you\n  probably will want to change this value to `LoadBalancer`.\n\n* `tokens`: This field should define tokens that can be used by clients to send\n  events (webhooks) to this gateway. Note that keys are completely ignored by\n  the gateway and only the values (tokens) matter. The keys only serve as\n  recognizable token identifiers for human operators.\n\nSave your changes to `~/brigade-acr-gateway-values.yaml` and use the following command to install\nthe gateway using the above customizations:\n\n```shell\n$ helm install brigade-acr-gateway \\\n    oci://ghcr.io/brigadecore/brigade-acr-gateway \\\n    --version v0.4.1 \\\n    --create-namespace \\\n    --namespace brigade-acr-gateway \\\n    --values ~/brigade-acr-gateway-values.yaml \\\n    --wait \\\n    --timeout 300s\n```\n\n### 3. (RECOMMENDED) Create a DNS Entry\n\nIf you overrode defaults and set `service.type` to `LoadBalancer`, use this\ncommand to find the gateway's public IP address:\n\n```shell\n$ kubectl get svc brigade-acr-gateway \\\n    --namespace brigade-acr-gateway \\\n    --output jsonpath='{.status.loadBalancer.ingress[0].ip}'\n```\n\nIf you overrode defaults and enabled support for an ingress controller, you\nprobably know what you're doing well enough to track down the correct IP without\nour help. 😉\n\nWith this public IP in hand, edit your name servers and add an `A` record\npointing your domain to the public IP.\n\n### 4. Create Webhooks\n\nIn your browser, visit the Azure Portal and navigate to the Azure Container\nRegistry for which you'd like to send webhooks to this gateway. From the\n__Services__ section, select __Webhooks__ and click __Add__.\n\nHere, you can add webhooks for the entire registry or for specific repositories\nwithin the registry.\n\n* In the __Webhook name__ field, add a meaningful name for the webhook.\n\n* If your registry is replicated across regions, select the applicable\n  __Location__.\n\n* In the __Service URI__ field, use a value of the form \n  `https://\u003cDNS hostname or publicIP\u003e/events`.\n\n* In the __Custom headers__ field, add `Authorization: Bearer \u003ctoken\u003e`, where\n  `\u003ctoken\u003e` is any of the tokens that were specified in `my-values.yaml` at the\n  time of gateway installation. This will enable authentication to this gateway.\n\n* In the __Actions__ field, select the actions that should trigger a webhook.\n  Note that `chart_push` and `chart_delete` are not supported by this gateway.\n\n* The __Status__ field can be used to enable or disable the webhook. It is\n  enabled by default.\n\n* The __Scope__ field can be used to make this webhook be triggered only by the\n  selected action (__Actions__ field) on a _specific repository within the\n  registry_. If __Scope__ is left blank, selected actions on _any repository\n  within the registry_ will trigger the webhook.\n\n* Click __Create__\n\n### 5. Add a Brigade Project\n\nYou can create any number of Brigade projects (or modify an existing one) to\nlisten for events that were sent from an ACR repository to your gateway and, in\nturn, emitted into Brigade's event bus. You can subscribe to all event types\nemitted by the gateway, or just specific ones.\n\nIn the example project definition below, we subscribe to all events emitted by\nthe gateway, provided they've originated from the fictitious\n`example.azurecr.io` ACR registry and the fictitious `example-repo` repository\n(see the `registry` qualifier and `repo` label).\n\n```yaml\napiVersion: brigade.sh/v2\nkind: Project\nmetadata:\n  id: acr-demo\ndescription: A project that demonstrates integration with ACR\nspec:\n  eventSubscriptions:\n  - source: brigade.sh/acr\n    types:\n    - *\n    qualifiers:\n      registry: example.azurecr.io\n    labels:\n      repo: example-repo\n  workerTemplate:\n    defaultConfigFiles:\n      brigade.js: |-\n        const { events } = require(\"@brigadecore/brigadier\");\n\n        events.on(\"brigade.sh/acr\", \"push\", () =\u003e {\n          console.log(\"Someone pushed an image to example.azurecr.io/example-repo!\");\n        });\n\n        events.process();\n```\n\nIn the alternative example below, we subscribe _only_ to `push` events:\n\n```yaml\napiVersion: brigade.sh/v2\nkind: Project\nmetadata:\n  id: acr-demo\ndescription: A project that demonstrates integration with ACR\nspec:\n  eventSubscriptions:\n  - source: brigade.sh/acr\n    types:\n    - push\n    qualifiers:\n      registry: example.azurecr.io\n    labels:\n      repo: example-repo\n  workerTemplate:\n    defaultConfigFiles:\n      brigade.js: |-\n        const { events } = require(\"@brigadecore/brigadier\");\n\n        events.on(\"brigade.sh/acr\", \"push\", () =\u003e {\n          console.log(\"Someone pushed an image to example.azurecr.io/example-repo!\");\n        });\n\n        events.process();\n```\n\nAssuming this file were named `project.yaml`, you can create the project like\nso:\n\n```shell\n$ brig project create --file project.yaml\n```\n\nPush an image to the ACR repo for which you configured webhooks to send an event\n(webhook) to your gateway. The gateway, in turn, will emit the event into\nBrigade's event bus. Brigade should initialize a worker (containerized event\nhandler) for every project that has subscribed to the event, and the worker\nshould execute the `brigade.js` script that was embedded in the example project\ndefinition.\n\nList the events for the `acr-demo` project to confirm this:\n\n```shell\n$ brig event list --project acr-demo\n```\n\nFull coverage of `brig` commands is beyond the scope of this documentation, but\nat this point, additional `brig` commands can be applied to monitor the event's\nstatus and view logs produced in the course of handling the event.\n\n## Events Received and Emitted by this Gateway\n\n_A subset of events_ received by this gateway from ACR are, in turn, emitted\ninto Brigade's event bus.\n\nACR supports the following events:\n\n* `push`\n* `delete`\n* `chart_push`\n* `chart_delete`\n\nAccording to ACR documentation, `push` and `delete` are triggered when OCI\nimages are, respectively, pushed to or deleted from a repository in ACR. Again,\naccording to ACR documentation, `chart_push` and `chart_delete` are triggered\nwhen Helm charts are, respectively, pushed to or delete from a repository in\nACR. _However_ `chart_push` and `chart_delete` are only triggered when using the\nAzure CLI's `az acr` commands to push and delete charts from ACR and these\ncommands are _deprecated_ in favor of Helm 3's built in support. When pushing or\ndeleting via `helm` commands, regular `push` and `delete` webhooks are\ntriggered.\n\nMoreover, `chart_push` and `chart_delete` webhook payloads lack critical\ninformation (namely the affected registry) that is present in the `push` and\n`delete` webhook payloads. This makes it impossible for this gateway to\neffectively qualify and label events emitted into Brigade in a manner that is\ncompatible with Brigade's event subscription model.\n\n__Due to these constraints, only `push` and `delete` webhooks are supported.__\n\nAll `push` and `delete` events emitted into Brigade's event bus will be\nqualified by the registry of origin (`registry` qualifier) and labeled with the\nrepository of origin (`repo` label). Subscribers _must_ match on the `registry`\nqualifier to receive events originating from a given registry and _may\noptionally_ match on the `repo` label to narrow their subscription to only\noriginating from a specific repository. Refer back to examples in previous\nsections to see this in action.\n\n## Examples Projects\n\nSee `examples/` for complete Brigade projects that demonstrate various\nscenarios.\n\n## Contributing\n\nThe Brigade project accepts contributions via GitHub pull requests. The\n[Contributing](CONTRIBUTING.md) document outlines the process to help get your\ncontribution accepted.\n\n## Support \u0026 Feedback\n\nWe have a slack channel!\n[Kubernetes/#brigade](https://kubernetes.slack.com/messages/C87MF1RFD) Feel free\nto join for any support questions or feedback, we are happy to help. To report\nan issue or to request a feature open an issue\n[here](https://github.com/brigadecore/brigade-acr-gateway/issues)\n\n## Code of Conduct\n\nParticipation in the Brigade project is governed by the\n[CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrigadecore%2Fbrigade-acr-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrigadecore%2Fbrigade-acr-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrigadecore%2Fbrigade-acr-gateway/lists"}