Skip to main content

Webhook Sources

Overview

Webhook sources let you ingest change events from external tools — GitLab, GitHub, and ArgoCD — into the Proxima Console change events timeline. These events appear alongside agent-detected file changes on the Events Timeline, enabling root cause correlation across your delivery pipeline:

merge → deploy → config change → metric spike

Each webhook source is registered with a unique token-based URL. When the external tool sends a webhook, Proxima normalizes the payload into a structured change event and stores it in the change_events table.

Architecture

Key design decisions:

  • Token-based URL authentication — each webhook source gets a unique token embedded in the URL. Tokens are SHA-256 hashed for storage; the plaintext is shown once at creation.
  • Source-specific normalization — each source type has a dedicated normalizer that extracts structured metadata (git info, CI/CD status, deploy details) into typed JSONB.
  • Same change_events table — webhook events coexist with agent-detected file changes, enabling unified timeline queries.
  • Optional host mapping — map source-specific keys (e.g., repo:org/app or app:frontend) to host UUIDs for host-level correlation.

Supported Sources

GitLab

Handles the following GitLab webhook event types:

GitLab HookEvent TypeSeverityDescription
Push HookpushinfoCode pushed to a branch
Tag Push HooktaginfoTag created or pushed
Merge Request Hook (merged)merge_requestinfoMerge request merged
Pipeline Hook (success)pipeline_completedinfoPipeline finished successfully
Pipeline Hook (failed)pipeline_failedwarningPipeline failed
Job Hookpipeline_completed / pipeline_failedinfo / warningIndividual job completed

Non-merged merge requests and other event types (Note Hook, Issue Hook, etc.) are silently ignored with a 200 OK response.

Authentication: GitLab sends the secret in the X-Gitlab-Token header. A secret is required: Proxima decrypts the stored secret (via Vault Transit) and compares it to the header value with a constant-time comparison. A source with no secret configured has every delivery rejected (404).

GitHub

Handles the following GitHub webhook event types:

GitHub EventEvent TypeSeverityDescription
pushpushinfoCode pushed to a branch
pull_request (merged)pull_requestinfoPull request merged
release (published)releaseinfoRelease published
workflow_run (success)workflow_completedinfoWorkflow run completed
workflow_run (failure)workflow_failedwarningWorkflow run failed
check_suite (success)workflow_completedinfoCheck suite passed
check_suite (failure)workflow_failedwarningCheck suite failed

Non-merged PRs, draft releases, and non-completed workflow runs are silently ignored.

Authentication: GitHub uses HMAC-SHA256 signatures via the X-Hub-Signature-256 header. A secret is required: Proxima validates the signature against the full request body. A source with no secret configured has every delivery rejected (404).

ArgoCD

Handles ArgoCD notification webhook payloads:

ArgoCD EventEvent TypeSeverityDescription
syncsyncinfoApplication synced successfully
health-degradedhealth_degradedwarningApplication health degraded
sync-failedsync_failedcriticalSync operation failed
(empty/unknown)syncinfoDefaults to sync event

Authentication: ArgoCD sends the secret in the X-Argocd-Token header. A secret is required: Proxima compares it to the stored secret with a constant-time comparison. A source with no secret configured has every delivery rejected (404).

info

ArgoCD notifications require explicit template configuration. There is no default webhook payload format. See ArgoCD Setup below for the required notification template.

Event Normalization

Each webhook payload is normalized into structured metadata stored as JSONB in the details column:

Git Events (push, merge_request, tag, release)

FieldDescription
event_typeThe normalized event type
repoRepository full name (e.g., org/repo)
branchTarget branch
commit_shaHead commit SHA
authorCommit or merge author
messageCommit message (first line)
urlLink to the commit/MR/PR

CI/CD Events (pipeline, workflow_run, check_suite)

FieldDescription
event_typeThe normalized event type
pipeline_namePipeline or workflow name
statusConclusion status (success, failure, etc.)
branchSource branch
commit_shaHead commit SHA
duration_secondsPipeline duration in seconds
urlLink to the pipeline/workflow run

Deploy Events (ArgoCD sync)

FieldDescription
event_typeThe normalized event type
app_nameArgoCD application name
namespaceTarget Kubernetes namespace
imageFirst container image from the summary
statusSync/health status
revisionGit revision

All metadata types also include a raw field containing the original webhook payload for debugging.

Setup

1. Register a Webhook Source

Navigate to Admin → Webhook Sources and click Create. Provide:

FieldRequiredDescription
NameYesDisplay name (e.g., "Production GitLab")
Source TypeYesgitlab, github, or argocd
ClientYesClient this webhook belongs to
EnvironmentNoScopes events to an environment
SecretYesShared secret for signature validation
Host MappingNoJSON mapping of source keys to host UUIDs

After creation, the webhook URL and token are displayed once. Copy them immediately.

warning

A secret is required for every webhook source. Proxima fails closed: a source with no secret configured has all deliveries rejected with 404 Not Found, regardless of a valid URL token. Always configure both the URL token and the matching secret in the external tool.

warning

The plaintext token is shown only at creation time. If you lose it, use the Rotate action to generate a new token (the old one is immediately invalidated).

2. Configure the External Tool

GitLab

  1. Go to your GitLab project → Settings → Webhooks
  2. Set the URL to the webhook URL from step 1
  3. Set the Secret token to the secret you configured for the source (required)
  4. Select the event triggers you want: Push events, Tag push events, Merge request events, Pipeline events, Job events
  5. Click Add webhook

GitHub

  1. Go to your GitHub repository → Settings → Webhooks → Add webhook
  2. Set the Payload URL to the webhook URL from step 1
  3. Set Content type to application/json
  4. Set the Secret to the secret you configured for the source (required)
  5. Select individual events: Pushes, Pull requests, Releases, Workflow runs, Check suites
  6. Click Add webhook

ArgoCD

ArgoCD requires a notification template to be configured. Add the following to your ArgoCD notification configuration:

1. Add the webhook service (argocd-notifications-cm ConfigMap):

apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
data:
service.webhook.proxima: |
url: https://your-console.example.com/api/v1/webhooks/argocd/<TOKEN>
headers:
- name: X-Argocd-Token
value: <YOUR_SECRET>

2. Add notification templates:

  template.proxima-sync: |
webhook:
proxima:
method: POST
body: |
{
"app": {{toJson .app}},
"type": "{{.type}}",
"message": "{{.message}}"
}
template.proxima-health-degraded: |
webhook:
proxima:
method: POST
body: |
{
"app": {{toJson .app}},
"type": "health-degraded",
"message": "Application {{.app.metadata.name}} health degraded"
}

3. Add triggers:

  trigger.on-sync-succeeded: |
- when: app.status.operationState.phase in ['Succeeded']
send: [proxima-sync]
trigger.on-health-degraded: |
- when: app.status.health.status == 'Degraded'
send: [proxima-health-degraded]
trigger.on-sync-failed: |
- when: app.status.operationState.phase in ['Error', 'Failed']
send: [proxima-sync]

4. Annotate your ArgoCD Application:

metadata:
annotations:
notifications.argoproj.io/subscribe.on-sync-succeeded.proxima: ""
notifications.argoproj.io/subscribe.on-health-degraded.proxima: ""
notifications.argoproj.io/subscribe.on-sync-failed.proxima: ""

3. Host Mapping (Optional)

Host mapping lets you associate webhook events with specific monitored hosts. The mapping is a JSON object where keys are source-specific identifiers and values are host UUIDs:

{
"repo:org/frontend": "550e8400-e29b-41d4-a716-446655440001",
"app:backend-api": "550e8400-e29b-41d4-a716-446655440002"
}

Key format by source type:

SourceKey FormatExample
GitLabrepo:<path_with_namespace>repo:myorg/myapp
GitHubrepo:<full_name>repo:myorg/myapp
ArgoCDapp:<app_name>app:frontend

When a webhook event matches a key, the resulting change event is linked to the corresponding host, making it visible on that host's timeline.

RBAC

Webhook source management requires the following permissions:

PermissionRequired For
webhooks:readList and view webhook sources
webhooks:writeCreate, update, and rotate webhook sources
webhooks:deleteDelete webhook sources

The webhook receiver endpoints (/api/v1/webhooks/{source}/{token}) are public — they authenticate via the token in the URL rather than JWT/API key.

Management API

MethodPathPermissionDescription
GET/api/v1/webhook-sourceswebhooks:readList webhook sources (paginated)
POST/api/v1/webhook-sourceswebhooks:writeCreate webhook source (returns token once)
GET/api/v1/webhook-sources/{id}webhooks:readGet webhook source
PUT/api/v1/webhook-sources/{id}webhooks:writeUpdate webhook source
DELETE/api/v1/webhook-sources/{id}webhooks:deleteDelete webhook source
POST/api/v1/webhook-sources/{id}/rotatewebhooks:writeRotate token (invalidates old one)

Webhook Receiver Endpoints

These endpoints receive webhook payloads from external tools. No JWT or API key is required — authentication is via the token in the URL.

MethodPathDescription
POST/api/v1/webhooks/gitlab/{token}Receive GitLab webhook
POST/api/v1/webhooks/github/{token}Receive GitHub webhook
POST/api/v1/webhooks/argocd/{token}Receive ArgoCD webhook

Request body limit: the request body is read up to a 1 MB limit; any bytes beyond 1 MB are truncated. A truncated payload that no longer parses is rejected with 400 Bad Request.

Events Timeline

Webhook events appear on the Events Timeline alongside agent-detected file changes. Each event type has a distinct icon and color:

SourceIconColor
GitLab / GitHub (push, merge, tag)Git branchBlue
CI/CD (pipeline, workflow)Play circleCyan
ArgoCD (deploy)RocketOrange

Click on any event to expand its details panel, which shows the normalized metadata and a link to the original event in the source tool.

Troubleshooting

Webhook not received

  1. Verify the webhook source is enabled in Admin → Webhook Sources
  2. Check the token hasn't been rotated (the URL would have changed)
  3. Verify network connectivity from the source tool to the Proxima Console backend
  4. Check backend logs for rejected requests: ./scripts/obs.sh logs 'webhook' 15m

Signature validation failed

  • GitLab: Ensure the X-Gitlab-Token header value matches the secret configured in the webhook source
  • GitHub: Ensure the webhook secret in GitHub settings matches exactly. GitHub uses HMAC-SHA256 to sign the full request body
  • ArgoCD: Ensure the X-Argocd-Token header in the notification template matches the configured secret

Events not appearing on timeline

  • Check that the source filter on the timeline includes the webhook source type
  • If using host mapping, verify the mapping key matches the source's identifier format
  • Events without host mapping appear on the environment-level timeline but not on individual host timelines