Connect ComplianceLayer to ConnectWise Manage
Automatically create service tickets from security findings. Route critical issues to the right board. Keep your PSA in sync with every scan.
From scan finding to service ticket
Three steps to connect ComplianceLayer findings to your ConnectWise service board. No middleware platform required.
In your ComplianceLayer dashboard, create an outbound webhook pointing to your ConnectWise bridge endpoint. Choose which events to send — scan completed, grade changed, or critical finding detected.
The bridge translates ComplianceLayer severity levels to ConnectWise priority IDs. Critical findings become Priority 1 tickets. High becomes Priority 2. You control the mapping.
When a scan completes with critical or high findings, service tickets are created on your chosen ConnectWise board. Each ticket includes the domain, grade, finding details, and remediation steps.
A real ticket, not a notification
Each critical or high finding creates a service ticket on your ConnectWise board with the domain name, security grade, finding summary, severity, remediation steps, and a link to the full ComplianceLayer report. Your techs see exactly what to fix and where to start.
Actionable detail in every ticket
The ticket body includes everything a technician needs to remediate the finding without leaving ConnectWise.
Get connected in 15 minutes
Bridge script — Python or PowerShell
A lightweight script that receives ComplianceLayer webhooks and creates ConnectWise tickets. Full source available in our examples repository.
# bridge.py — receives ComplianceLayer webhooks,
# creates ConnectWise Manage service tickets
from fastapi import FastAPI, Request, HTTPException
import httpx, hashlib, hmac, os
app = FastAPI()
CW_URL = os.environ["CW_URL"] # e.g. https://na.myconnectwise.net/v4_6_release/apis/3.0
CW_COMPANY = os.environ["CW_COMPANY"]
CW_PUBLIC = os.environ["CW_PUBLIC_KEY"]
CW_PRIVATE = os.environ["CW_PRIVATE_KEY"]
CW_BOARD_ID = int(os.environ.get("CW_BOARD_ID", "1"))
WEBHOOK_SECRET = os.environ["WEBHOOK_SECRET"]
SEVERITY_MAP = {
"critical": {"id": 1, "name": "Priority 1 - Critical"},
"high": {"id": 2, "name": "Priority 2 - High"},
"medium": {"id": 3, "name": "Priority 3 - Medium"},
"low": {"id": 4, "name": "Priority 4 - Low"},
}
@app.post("/webhook/compliancelayer")
async def handle_webhook(request: Request):
body = await request.body()
signature = request.headers.get("X-Webhook-Signature", "")
expected = hmac.new(
WEBHOOK_SECRET.encode(), body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
raise HTTPException(401, "Invalid signature")
payload = await request.json()
domain = payload["domain"]
grade = payload["grade"]
for finding in payload.get("findings", []):
severity = finding.get("severity", "low")
if severity not in ("critical", "high"):
continue
await create_ticket(
summary=f"[{grade}] {domain}: {finding['title']}",
body=build_ticket_body(domain, grade, finding),
priority=SEVERITY_MAP[severity],
)
return {"status": "ok"}# bridge.ps1 — PowerShell alternative for Windows MSPs
$webhookBody = Get-Content -Raw -Path $args[0] | ConvertFrom-Json
$cwUrl = $env:CW_URL
$company = $env:CW_COMPANY
$publicKey = $env:CW_PUBLIC_KEY
$privateKey = $env:CW_PRIVATE_KEY
$auth = [Convert]::ToBase64String(
[Text.Encoding]::ASCII.GetBytes(
"$company+$publicKey:$privateKey"
)
)
foreach ($finding in $webhookBody.findings) {
if ($finding.severity -notin @("critical","high")) { continue }
$ticket = @{
summary = "[$($webhookBody.grade)] $($webhookBody.domain): $($finding.title)"
board = @{ id = $env:CW_BOARD_ID }
priority = @{
id = switch ($finding.severity) {
"critical" { 1 } "high" { 2 }
}
}
initialDescription = @"
Domain: $($webhookBody.domain)
Grade: $($webhookBody.grade)
Finding: $($finding.title)
Severity: $($finding.severity)
Remediation:
$($finding.remediation)
"@
} | ConvertTo-Json -Depth 5
Invoke-RestMethod -Uri "$cwUrl/service/tickets" \
-Method Post -Body $ticket \
-ContentType "application/json" \
-Headers @{ Authorization = "Basic $auth" }
}Start routing findings to ConnectWise
Set up webhooks in your dashboard. Deploy the bridge script. Critical findings become service tickets — automatically.
Webhooks available on Professional plan ($249/mo) and above. View pricing →