continueops_inbound_webhook (Resource)
An inbound webhook: a URL that an external tool (CrowdStrike Falcon, Veeam, SentinelOne, or anything that signs requests with HMAC) posts events to, optionally opening a ContinueOps incident for each verified event. Give the tool url and signing_secret.
Needs an API key whose owner is a tenant owner or admin, minted in their primary tenant.
url and signing_secret are generated by the platform. signing_secret is returned only when the endpoint is created or its secret is rotated: after terraform import it is null until the next rotation. Increase signing_secret_version to rotate it in place; the old secret stops verifying at once. The URL never changes.
~> Destroying this resource deletes the endpoint and its whole received-event log (the audit trail of what was posted and whether it verified). Senders get 404 from then on. Set active = false to stop accepting events and keep the log, and protect production endpoints with lifecycle { prevent_destroy = true }.
Example Usage
# CrowdStrike Falcon posts detections here; each verified one opens an incident.
# Destroying this resource deletes the endpoint AND its received-event log, so guard it.
resource "continueops_inbound_webhook" "falcon" {
name = "CrowdStrike Falcon - Prod"
source = "crowdstrike" # presets X-Cs-Signature, no prefix
timestamp_header = "X-Cs-Timestamp"
auto_create_incident = true
default_incident_owner = "SecOps"
ip_allowlist = ["203.0.113.10", "203.0.113.11"] # single addresses, not CIDRs
lifecycle {
prevent_destroy = true
}
}
output "falcon_webhook_url" {
value = continueops_inbound_webhook.falcon.url
}
output "falcon_webhook_secret" {
value = continueops_inbound_webhook.falcon.signing_secret
sensitive = true
}Schema
Required
name(String) Display name, 1 to 200 characters. Can be changed in place.
Optional
active(Boolean) Whether the endpoint accepts events; an inactive endpoint answers 404. Defaulttrue.auto_create_incident(Boolean) Open a ContinueOps incident for every verified event. Defaultfalse.default_incident_owner(String) Owner written on incidents this endpoint opens, 1 to 200 characters. DefaultInbound Webhook.ip_allowlist(Set of String) Sender addresses allowed to post; empty or unset accepts any address (the signature is still enforced). Each entry is one address, IPv4 or canonical lower-case IPv6: the receiver compares the caller's address as a string, so CIDR ranges are refused rather than silently matching nothing. At most 200.max_skew_seconds(Number) Withtimestamp_header, how far (seconds, 1-86400) the sender's timestamp may be from now before the event is refused as a replay. Default300.signature_algorithm(String) HMAC used to verify the signature:hmac-sha256orhmac-sha1. Defaulthmac-sha256.signature_header(String) Request header carrying the hex signature. Default depends onsource:X-Cs-Signature(crowdstrike),X-Veeam-Signature(veeam),X-S1-Signature(sentinelone),X-Webhook-Signature(generic).signature_prefix(String) Text before the hex digest in the signature header, such assha256=;""for none. Default depends onsource:""(crowdstrike, sentinelone),sha256=(veeam, generic).signing_secret_version(Number) Rotation counter forsigning_secret, kept only in Terraform state. Increase it to have the platform issue a new secret in place (the old one stops verifying immediately). Default1; set to1on import.source(String) The sending tool:crowdstrike,veeam,sentineloneorgeneric. Labels events and incidents, and picks the defaultsignature_headerandsignature_prefix. Defaultgeneric.timeouts(Attributes) (see below for nested schema)timestamp_header(String) Request header carrying the send time (Unix seconds or milliseconds). When set, events without it, or older thanmax_skew_seconds, are refused, and<timestamp>.<body>is also accepted as the signed text. Unset: no replay check. CrowdStrike sendsX-Cs-Timestamp, SentinelOneX-S1-Timestamp.
Read-Only
created_at(String) When the endpoint was created (RFC 3339, UTC).id(String) Endpoint id (UUID).last_event_at(String) When the endpoint last received an event (RFC 3339, UTC); null before the first. Never causes a plan diff.signing_secret(String, Sensitive) HMAC key the sender signs with (64 hex characters). Returned only on create and on rotation; null after import untilsigning_secret_versionis increased.updated_at(String) When the endpoint last changed (RFC 3339, UTC).url(String) The endpoint's public URL (.../functions/v1/inbound-webhook/<token>). Fixed for the endpoint's life.
Nested Schema for timeouts
Optional:
create(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).delete(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours). Setting a timeout for a Delete operation is only applicable if changes are saved into state before the destroy operation occurs.read(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours). Read operations occur during any refresh or planning operation when refresh is enabled.update(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours).
Import
Import is supported using the following syntax:
In Terraform v1.5.0 and later, the import block can be used with the id attribute, for example:
import {
to = continueops_inbound_webhook.example
id = "00000000-0000-4000-8000-000000000000"
}The terraform import command can be used, for example:
# Import by id (UUID). signing_secret is only returned at creation, so it is null
# after import; increase signing_secret_version to rotate it and get the new one.
terraform import continueops_inbound_webhook.example 00000000-0000-4000-8000-000000000000