Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: Bug report
about: Report a reproducible defect
title: "bug: "
labels: bug
assignees: ''
---

## Describe the bug

A clear, concise description of what is wrong.

## Steps to reproduce

1. ...
2. ...

## Expected behavior

What you expected to happen.

## Actual behavior

What actually happened. Include logs or error messages if available.

## Environment

- Gatekeeper version:
- Deployment method (Docker, Kubernetes, bare metal):
- Go version (if building from source):
- OS / kernel:

## Additional context

Any other context, config snippets (redact secrets), or screenshots.
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: Feature request
about: Propose a new capability or improvement
title: "feat: "
labels: enhancement
assignees: ''
---

## Problem or motivation

What problem does this solve, or what use case does it enable?

## Proposed solution

Describe what you would like to see added or changed.

## Alternatives considered

Any other approaches you thought about, and why you prefer this one.

## Additional context

Links to related issues, specs, or prior art.
18 changes: 18 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Summary

<!-- What does this PR do, and why? Link to an issue if one exists (Fixes #NNN). -->

## Changes

<!-- Bullet-point list of what changed. -->

## Testing

<!-- Describe how you tested this. New tests added? Existing tests updated? Manual steps? -->

## Checklist

- [ ] `make test` passes locally
- [ ] `make lint` passes locally
- [ ] Documentation updated (if behavior or configuration changed)
- [ ] CHANGELOG updated (for user-visible changes)
39 changes: 39 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Code of Conduct

## Our Pledge

We as contributors and maintainers pledge to make participation in this project a
harassment-free experience for everyone, regardless of age, body size, disability,
ethnicity, sex characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race, religion,
or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to a positive environment:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

Examples of unacceptable behavior:

- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
opening a GitHub issue or contacting the maintainers directly. All complaints will be
reviewed and investigated promptly and fairly. Maintainers are obligated to maintain
confidentiality with regard to the reporter of an incident.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
version 2.1.
52 changes: 52 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Contributing to Gatekeeper

Thanks for your interest in contributing. This document covers the essentials;
the full development workflow is in [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md).

## What we welcome

- **New provider implementations** - See [docs/PROVIDER_TODO.md](docs/PROVIDER_TODO.md) for the wishlist
and [docs/PROVIDER_DEVELOPMENT.md](docs/PROVIDER_DEVELOPMENT.md) for a step-by-step guide
- **Bug fixes** - If possible, include a test case that fails before your fix and passes after.
We understand some bugs require a live third-party webhook to trigger; in those cases a
clear reproduction description, or more ideally, a branch with a failing test case that
illustrates the issue, is sufficient.
- **Performance improvements** - Include benchmarks showing the improvement
- **New features** - Open an issue first to discuss the design before writing code

## Before you open a PR

1. Read [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for environment setup and build/test commands
2. Read [docs/CODING_STANDARDS.md](docs/CODING_STANDARDS.md) for code style and testing requirements
3. Run `make test` locally and confirm all tests pass with 100% coverage on changed packages
4. Run `make lint` and resolve any issues
5. Update docs if your change affects configuration, behavior, or the public API

## Pull request checklist

- [ ] Linked to the relevant issue (use `Fixes #NNN` or `Relates to #NNN`)
- [ ] Tests added or updated (where possible)
- [ ] `make test` passes locally
- [ ] `make lint` passes locally
- [ ] Documentation updated if needed

## A note on AI-assisted contributions

We use AI tools in our own development and welcome others who do the same. However,
PRs must demonstrate human understanding of the changes. Include clear motivation
explaining *why* the change is needed, not just what it does. Explain your testing
approach. Low-effort submissions that appear to be unreviewed AI output will be declined.
We value quality over quantity.

## Reporting bugs

Open a [bug report](https://github.com/Tight-Line/gatekeeper/issues/new?template=bug_report.md).

## Suggesting features

Open a [feature request](https://github.com/Tight-Line/gatekeeper/issues/new?template=feature_request.md).

## Security issues

Please do **not** open public issues for security vulnerabilities.
See [SECURITY.md](SECURITY.md) for responsible disclosure instructions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Tight Line LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,15 @@ Supported verifier types:
|------|----------|-----------|
| `slack` | Slack | HMAC-SHA256 of "v0:{timestamp}:{body}" with replay protection |
| `github` | GitHub | HMAC-SHA256 of body, hex encoded |
| `gitlab` | GitLab | X-Gitlab-Token header comparison |
| `shopify` | Shopify | HMAC-SHA256 of body, base64 encoded |
| `sendgrid` | SendGrid Event Webhook | ECDSA P-256 over timestamp+body with replay protection |
| `oidc` | Google Chat, Azure AD, etc. | RS256 JWT bearer token with JWKS auto-discovery |
| `hmac` | Generic | Configurable HMAC (SHA256/SHA512, hex/base64) |
| `api_key` | Google Calendar, etc. | Header token comparison |
| `json_field` | Microsoft Graph, etc. | Token at dot-notation path in JSON body |
| `query_param` | Generic | Token in URL query parameter |
| `header_query_param` | Generic | Key=value pair extracted from a request header |
| `noop` | Testing | Always succeeds (testing only) |

#### Payload Schema Validation
Expand Down
36 changes: 36 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Security Policy

## Supported versions

| Version | Supported |
| ------- | --------- |
| Latest | Yes |
| Older | No |

We support only the current release. Please upgrade before reporting a vulnerability.

## Reporting a vulnerability

**Do not open a public GitHub issue for security vulnerabilities.**

Report vulnerabilities privately via GitHub's
[Security Advisories](https://github.com/Tight-Line/gatekeeper/security/advisories/new)
feature (Settings > Security > Advisories > New draft advisory).

Please include:

- A description of the vulnerability and its potential impact
- Steps to reproduce or a proof-of-concept (if safe to share)
- The version(s) affected
- Any suggested mitigations you are aware of

We aim to acknowledge reports within 3 business days and to provide a resolution
timeline within 10 business days.

## Disclosure policy

Once a fix is available we will:

1. Release a patched version
2. Publish a GitHub Security Advisory crediting the reporter (unless anonymity is requested)
3. Add an entry to [CHANGELOG.md](CHANGELOG.md)
69 changes: 67 additions & 2 deletions agents/configure-route.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ Ask which webhook provider they want to configure. Offer these options:
- **GitHub** - Repository webhooks, organization webhooks
- **GitLab** - Repository/project webhooks, group webhooks
- **Shopify** - Store webhooks (orders, products, customers)
- **SendGrid** - Event Webhook (email delivery/engagement events)
- **Google Calendar** - Calendar push notifications (X-Goog-Channel-Token header)
- **Google Chat** - Chat app webhooks (OIDC JWT bearer token)
- **Microsoft Graph** - Outlook Calendar, OneDrive change notifications (token in JSON body)
- **Azure Event Grid (AAD)** - Azure Event Grid with Azure Active Directory authentication
- **Generic HMAC** - Any provider using HMAC signatures (configurable algorithm/encoding)
- **API Key (Header)** - Providers using simple header token authentication
- **Query Parameter Token** - Providers that send a token in the URL query string
Expand Down Expand Up @@ -268,7 +271,7 @@ verifiers:
secret: "${SHOPIFY_WEBHOOK_SECRET}"
```

#### SendGrid (Event Webhook / Inbound Parse)
#### SendGrid Event Webhook

SendGrid signs Event Webhook deliveries with ECDSA P-256. The signed content is `timestamp + raw_body`, the signature header carries the base64-encoded ASN.1 DER signature, and the timestamp travels in a sibling header.

Expand All @@ -286,7 +289,7 @@ verifiers:
max_timestamp_age: 5m # optional replay-protection window; omit/0 disables
```

IP allowlist: SendGrid does **not** publish stable IP ranges for Event Webhook or Inbound Parse traffic, so omit `ip_allowlist` and rely on signature verification.
IP allowlist: SendGrid does **not** publish stable IP ranges for Event Webhook traffic, so omit `ip_allowlist` and rely on signature verification.

#### Google Calendar

Expand Down Expand Up @@ -349,6 +352,68 @@ ip_allowlists:
- "40.126.0.0/18"
```

#### Google Chat

Google Chat signs webhook requests with an RS256 JWT bearer token. There are two audience modes; ask the user which one their Chat app is configured to use.

**App URL audience mode** (recommended for new apps):

1. In the Google Cloud Console, configure the Chat app with **Authentication Audience: HTTP endpoint URL**
2. Set the environment variables:
- `export GCP_PROJECT_NUMBER="your-project-number"`
- The audience is the exact webhook URL: `https://{hostname}{path}`

Configuration uses:
```yaml
verifiers:
google-chat:
type: oidc
issuer: "https://accounts.google.com"
audience: "https://{hostname}{path}"
# jwks_uri omitted: auto-discovered from Google OIDC discovery document
claims:
email: "service-${GCP_PROJECT_NUMBER}@gcp-sa-gsuiteaddons.iam.gserviceaccount.com"
```

**Project number audience mode** (legacy):

1. Configure the Chat app with **Authentication Audience: Project number**
2. Set the environment variable: `export GCP_PROJECT_NUMBER="your-project-number"`

Configuration uses:
```yaml
verifiers:
google-chat:
type: oidc
issuer: "chat@system.gserviceaccount.com"
audience: "${GCP_PROJECT_NUMBER}"
jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com"
```

IP allowlist: Google Chat does not publish stable webhook source IPs; rely on JWT signature verification.

#### Azure Event Grid (AAD)

Azure Event Grid can deliver webhooks with Azure Active Directory (AAD) authentication. Gatekeeper verifies the RS256 JWT bearer token issued by your AAD tenant.

1. Configure Event Grid to use AAD authentication, specifying your app registration as the target audience
2. Set the environment variables:
- `export AZURE_TENANT_ID="your-tenant-id"`
- `export AZURE_APP_ID_URI="api://your-app-id"` (the audience value you registered)
3. Set the Event Grid subscription endpoint to: `https://{hostname}{path}`

Configuration uses:
```yaml
verifiers:
azure-eventgrid:
type: oidc
issuer: "https://sts.windows.net/${AZURE_TENANT_ID}/"
audience: "${AZURE_APP_ID_URI}"
# jwks_uri omitted: auto-discovered from AAD tenant metadata
```

IP allowlist: Azure publishes IP ranges but they are large and change frequently; rely on JWT signature verification.

#### Generic HMAC

Ask the user for:
Expand Down
4 changes: 4 additions & 0 deletions docs/PROVIDER_TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ Webhook providers we want to support in the future. Contributions welcome.
| Shopify | E-commerce | `shopify` |
| Google Calendar | Productivity | `api_key` |
| Google Chat | Communication | `oidc` |
| Azure Event Grid (AAD) | Cloud | `oidc` |
| Microsoft Graph | Productivity | `json_field` |
| SendGrid | Email | `sendgrid` |
| Generic HMAC | Any | `hmac` |
| Generic API Key | Any | `api_key` |
| Generic Query Param | Any | `query_param` |
| Generic Header Query Param | Any | `header_query_param` |

## Priority 1: High Demand

Expand Down
Loading
Loading