feat(webhook): authenticated webhook runner with allowlists, signature verification, idempotent logging
- Rewrite scripts/gitea_webhook_handler.py as HTTP server with HMAC-SHA256 auth - Add config/webhook.yaml defining allowed repos/events/branches/actions - Implement dispatch_push calling ansible/scripts/deploy_on_webhook.sh safely - SQLite logging table with delivery_id dedup for replay safety - Add tests/test_gitea_webhook_handler.py covering push/PR/signature/idempotency - Add docs/webhook-deployment.md with security model, ops, and #288 alignment Closes #436
This commit is contained in:
61
config/webhook.yaml
Normal file
61
config/webhook.yaml
Normal file
@@ -0,0 +1,61 @@
|
||||
# Webhook Handler Configuration
|
||||
# This file defines the allowlists for the authenticated webhook runner.
|
||||
# Secrets MUST be provided via environment variables — never hardcoded.
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# AUTHENTICATION
|
||||
# ---------------------------------------------------------------------------
|
||||
# Gitea sends X-Gitea-Signature header (HMAC-SHA256). The secret must
|
||||
# match the webhook secret configured in Gitea.
|
||||
#
|
||||
# Set in environment: GITEA_WEBHOOK_SECRET
|
||||
# Example: export GITEA_WEBHOOK_SECRET=$(cat ~/.config/gitea/webhook-secret)
|
||||
#
|
||||
# NEVER commit the actual secret. This file documents the key name only.
|
||||
|
||||
webhook_secret_env: "GITEA_WEBHOOK_SECRET"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ALLOWLISTS — explicit, deny-by-default
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Only these repositories will trigger actions
|
||||
allowed_repos:
|
||||
- "timmy-config"
|
||||
# Add other Timmy_Foundation repos as needed
|
||||
|
||||
# Only these event types are processed
|
||||
allowed_events:
|
||||
- "push"
|
||||
- "pull_request"
|
||||
# Note: issue events accepted but no action configured yet
|
||||
|
||||
# Only these branches are deployment targets
|
||||
allowed_branches:
|
||||
- "refs/heads/main"
|
||||
- "refs/heads/master"
|
||||
|
||||
# PR actions that are allowed (push to main is the deploy trigger)
|
||||
allowed_pr_actions:
|
||||
- "opened"
|
||||
- "synchronized"
|
||||
- "reopened"
|
||||
- "closed" # merged PRs also trigger push event
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# OPERATIONAL
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Require valid signature? Set false only for local testing.
|
||||
require_signature: true
|
||||
|
||||
# Where deployment logs are written
|
||||
log_dir: "logs"
|
||||
|
||||
# Path to the ansible deploy script (called on main-branch push)
|
||||
deploy_script: "ansible/scripts/deploy_on_webhook.sh"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# DEPLOYMENT NOTES
|
||||
# - The server runs continuously. Use systemd or cron @reboot.
|
||||
# - Align webhook creation with inf
|
||||
Reference in New Issue
Block a user