-
Notifications
You must be signed in to change notification settings - Fork 0
Concepts Integrations
An Integration connects Piro to an external system — a cloud provider, an issue tracker, or a third-party monitoring tool. Some integrations are outbound (Piro calls out to them, e.g. running a GCP Cloud Run Job check), and some are inbound (the external system calls into Piro, e.g. receiving alerts via a webhook).
This page covers the ThirdParty category of integrations. Notification channels (Email, Telegram, Twilio, etc.) are also modeled as Integrations internally, but are documented separately under Triggers.
| Field | Type | Description |
|---|---|---|
| Id | Guid | Unique identifier. Unlike most other Piro entities (Services, Checks, Alerts), an Integration's ID is a GUID rather than a sequential int — see below |
| Name | string | Display name shown in the admin panel |
| Type | enum | Which integration this is — see Integration types |
| Description | string? | Optional free-text note |
| ConfigJson | string | Provider-specific configuration (credentials, tokens, etc.), stored as a JSON blob and rendered as a typed form in the admin UI |
| EscalationPolicyId | int? | Optional Escalation Policy used for on-call paging on alerts this integration produces that have no Service of their own to inherit a policy from |
Source: Integration.cs
Every other entity in Piro (Service, Check, Alert, Incident, etc.) uses a sequential integer ID. Integration is the one deliberate exception, changed specifically because an Integration's ID can end up embedded in a public-facing webhook URL (see GCP Cloud Monitoring webhook below). A sequential int would let anyone guess or enumerate other integrations' webhook URLs by incrementing a number; a GUID isn't guessable. This scoping is intentional — it does not extend to any other entity.
🔍 If you're upgrading an existing Piro instance from before this change, the database migration remaps existing integer IDs to newly generated GUIDs via a mapping table, preserving all existing relationships (checks, escalation policies) rather than doing a blind column type change.
| Type | Category | Direction | What it does |
|---|---|---|---|
| Google Cloud | ThirdParty | Outbound | Credentials used to run GCP Cloud Run Job checks |
| Jira | ThirdParty | Outbound | Create and track Jira tickets from alerts (not yet dispatched) |
| GCP Cloud Monitoring | ThirdParty | Inbound | Receives alerting-policy notifications from Google Cloud Monitoring as Alerts |
| Email, Telegram, Twilio, Opsgenie, Pushover, Ntfy, PagerDuty | Notification | Outbound | Notification channels — see Triggers |
GcpCloudMonitoringWebhook is currently the only Inbound integration type — every integration before it only ever sent data out to a third party. Direction is tracked per-type so the admin UI knows whether to show a webhook URL/token section (inbound) or a credentials form (outbound).
Source: IntegrationType.cs
This integration lets Piro receive alerting-policy notifications directly from Google Cloud Monitoring, instead of Piro having to poll or pull metrics itself. Google Cloud Monitoring decides when its own alerting policies fire (based on thresholds you've configured in GCP) — Piro simply receives what Cloud Monitoring already decided to send. Piro does not re-implement or evaluate GCP's alerting logic.
🔍 Every alert created this way is currently an External alert — it has no Check or Service automatically associated with it. Correlating an incoming GCP alert to a specific Piro Check/Service is a planned enhancement, not something this integration does today. See External alerts for what that means downstream.
-
In the admin panel, go to Integrations and create a new integration of type GCP Cloud Monitoring.
-
On creation, Piro auto-generates a secret auth token — you never type one in yourself. This token is shown to you exactly once, right after creation, with a copy button and a warning that it won't be shown again (the same one-time-reveal pattern used for API key creation).
-
Open the integration's edit page. It shows a ready-to-paste Webhook URL — it already includes the integration's ID and the auth token as a query parameter:
https://your-piro-instance.example.com/api/v1/webhooks/gcp/3fa85f64-5717-4562-b3fc-2c963f66afa6?auth_token=**************** -
In Google Cloud Monitoring, create a webhook notification channel and paste that URL into its Endpoint URL field. GCP's dialog only accepts a single plain URL with no custom headers or auth options, which is why the token has to travel in the query string rather than a header.
-
(Optional) Assign an Escalation Policy on the integration. Since alerts from this integration have no Service to inherit a policy from, this is the only way to get GCP-sourced alerts to page your on-call rotation.
⚠️ If the token leaks or you lose it, use the Regenerate action on the integration's edit page. It asks for confirmation and warns that the old token stops working immediately. The new token is shown once, unmasked, the same way the original was.
POST /api/v1/webhooks/gcp/{integrationId}?auth_token=...
This endpoint is publicly reachable — Piro never initiates outbound connections to GCP, it only receives inbound calls. The auth_token query parameter is compared in constant time against the integration's stored token. GCP's payload reports each incident's state as:
-
open— creates or updates an Alert, deduplicated by GCP's ownincident_id(stored asAlert.ExternalId) -
closed— resolves the matching Alert byincident_id. Aclosedevent for anincident_idPiro never recorded is treated as a safe no-op, not an error (Piro may not have seen the originalopenevent, e.g. if the integration was created after the incident started)
Severity is mapped from GCP's own reported level:
| GCP severity | Piro impact |
|---|---|
critical |
Down |
anything else (including warning) |
Degraded |
Source: WebhooksController.cs, GcpWebhookIngestionService.cs
The integration's edit page has a Webhook Requests section showing recent inbound request history for that integration — timestamp, outcome, and a link to the Alert it produced, if any. Each row has a View payload action that opens the exact raw JSON GCP sent, pretty-printed.
Every inbound request is logged before authentication or parsing happens, so rejected and malformed requests are visible too, not just successful ones. Possible outcomes:
| Outcome | Meaning |
|---|---|
| Accepted | Produced/updated an Alert |
| AcceptedOrphan | Produced/updated an External alert (no Service/Check to attach to) |
| CorrelationMismatch | Reserved for a future correlation feature — not currently produced by the GCP integration |
| AuthFailed | The auth_token was missing or incorrect |
| ParseError | The request body didn't match the expected GCP payload shape |
| Deduplicated | A resend of an already-processed event — folded into the existing Alert's occurrence count |
Source: WebhookRequestLog.cs
This design (a
Source+ExternalIdpair for dedup, an optionalSourceUrldeep link, a request log independent of the Alert it may or may not produce) is intentionally generic — it's designed to extend to other third-party alert sources later (e.g. Alertmanager, Prometheus) without changing the schema again. Only GCP Cloud Monitoring is implemented today.
- Alerts — what an External/orphan alert is and how it behaves
- Checks — how the Google Cloud integration is used by GCP Cloud Run Job checks
- Escalation Policies — assigning on-call paging to an Integration
- Triggers — outbound notification-channel integrations