πŸ›‘ Pentestas β€Ί help

Webhooks (integrations)

For HTTPS endpoints that consume JSON events, see the full protocol + signing rules at API β†’ Webhooks.

Common patterns:

  • Jira β€” on finding.created, POST to Jira's issue-create API. Use the finding's title / description / CVSS as the issue body. Label with severity. Close the Jira issue when you receive finding.status_changed β†’ fixed.
  • PagerDuty β€” on scan.completed with any CRITICAL, trigger a PagerDuty incident via their events API.
  • ServiceNow β€” same shape as Jira; map severity β†’ ServiceNow priority (CRITICAL β†’ P1).
  • GitHub code-scanning β€” on scan.completed, pull the SARIF export and upload via the GitHub REST API. Findings appear in the Security tab of your repo.
  • Internal dashboards β€” aggregate events into your BI tool (Looker, Tableau, Grafana). Pentestas includes tenant_id + scan_id on every event so joins are straightforward.

Minimal handler (Python)

python
import hmac, hashlib, json
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = "your-webhook-secret"

@app.post("/pentestas")
def handle():
    sig = request.headers.get("X-Pentestas-Signature", "")
    expected = hmac.new(SECRET.encode(), request.data, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, sig.split("=", 1)[1]):
        abort(401)
    event = request.get_json(force=True)
    print(event["event"], event.get("scan_id"))
    return "ok", 200

Minimal handler (Node)

js
const crypto = require("crypto");
const express = require("express");
const app = express();

app.post("/pentestas", express.raw({type: "application/json"}), (req, res) => {
    const sig = req.header("X-Pentestas-Signature") || "";
    const expected = crypto.createHmac("sha256", process.env.SECRET)
        .update(req.body).digest("hex");
    if (!crypto.timingSafeEqual(Buffer.from(sig.split("=")[1]), Buffer.from(expected))) {
        return res.status(401).end();
    }
    const event = JSON.parse(req.body);
    console.log(event.event, event.scan_id);
    res.status(200).end();
});

See also