Nobody fixes a finding they never opened.
So it goes to them.
The second a pentester countersigns one of Lory's findings, it leaves the platform — into the channel your team actually watches, the backlog they actually groom, or your own automation as signed JSON. Eight integrations, every one connected with your keys, every one outbound.
A finding leaves three ways.
Not thirty logos and a filter bar. There are exactly three shapes a security finding takes once it's real — something someone reads, something someone is assigned, and something a machine parses — and the catalogue is organised around those.
Someone reads it
Slack, Teams and Discord get the finding as a native card the moment it's published — severity, asset, and a way back into the report.
4 channels → 02 / ticketSomeone owns it
Jira, GitHub, GitLab and Azure DevOps get a work item with the evidence, the remediation and a priority mapped from the severity.
4 trackers → 03 / dataSomething parses it
A signed JSON envelope to any endpoint you run — or your own AI agents reading the same findings live over MCP.
Read the payload →Eight integrations. All of them real.
Everything on this page is wired end to end and connectable today from Workspace → Marketplace. There is no "coming soon" tier here — if it isn't built, it isn't listed.
Slack
Findings and scan summaries posted as Block Kit messages into whichever channel you point the hook at.
Microsoft Teams
Adaptive Cards rendered full-width in the channel, with the severity, the asset and the timestamp as facts.
Discord
Rich embeds with a colour strip that tracks severity — built for teams whose security channel lives on Discord.
Custom Webhooks
The full event set as signed JSON to any endpoint you control. The one integration that carries all eight events.
Jira
Issues opened in the project you nominate, severity mapped straight onto Jira priority and labelled for filtering.
GitHub
Issues filed on the repository that owns the affected code, carrying the evidence and the remediation steps.
GitLab
Issues on GitLab.com or your self-hosted instance, optionally marked confidential so the detail stays internal.
Azure DevOps
Work items on the board you choose — Bug, Issue or Task — with the area path and severity mapping you set.
Subscribe to the eight things that happen.
Chat channels are opinionated: they carry the two moments a human wants interrupted for. Webhooks carry everything, and you pick which of the eight you want. Nothing fires speculatively — a finding only leaves after a pentester has countersigned it.
| Event | Fires when | Carried by |
|---|---|---|
| finding.created | A countersigned finding is published to your workspace. | channels · trackers · webhook |
| finding.updated | Severity, status or detail on an existing finding changes. | webhook |
| finding.resolved | A finding is closed out, usually after a passing retest. | webhook |
| scan.started | An engagement or scheduled run begins against your scope. | webhook |
| scan.completed | A run finishes, with counts broken out by severity. | channels · webhook |
| asset.discovered | Something new shows up in your asset inventory. | webhook |
| ticket.created | A tracker item is opened from a finding. | webhook |
| ticket.updated | A tracker item raised from a finding changes state. | webhook |
Delivery is attempted once per event, and the result is recorded either way. Successes and failures both land in your integration log with the HTTP status, so a webhook that silently started 500ing is something you can see rather than something you find out about later.
Signed JSON, and nothing you have to open a port for.
Custom webhooks are how you connect the thing we haven't built an integration for — a SOAR platform, an internal dashboard, a ticketing system nobody else uses. We POST out to you. You verify the signature and do whatever you like with it.
- transport
- HTTPS POST, outbound from our infrastructure to yours. 15 second timeout, up to three redirects followed.
- signing
- Set a secret and every body is signed HMAC-SHA256, sent as
X-Webhook-Signature: sha256=…. Compute it over the raw body, before parsing. - auth
- Optionally add an
Authorizationheader value of your own — a bearer token, a shared secret, whatever your endpoint expects. - shape
- Point it at a Slack, Discord or Teams hook URL and it emits that vendor's native format instead. Anything else gets the generic envelope.
- scope
- Payloads carry your company's data only. Credentials are stored per workspace and used for nothing but the calls you enabled.
Content-Type: application/json X-Webhook-Signature: sha256=9f2c1a… { "event": "finding.created", "timestamp": "2026-07-30T14:02:11+00:00", "data": { "finding": { "id": "F-2291", "title": "SSRF in image proxy reaches metadata", "severity": "Critical", "asset": "api.acme.com", "status": "open" } } }
# sign the raw body, not the parsed dict expected = hmac.new( secret.encode(), request.data, hashlib.sha256 ).hexdigest() sent = request.headers["X-Webhook-Signature"].removeprefix("sha256=") if not hmac.compare_digest(sent, expected): abort(401)
Three steps, and none of them involve us.
Every integration is connected with a credential you create, on your side, scoped how you like. We never ask for an OAuth grant over your whole workspace, and there's nothing to install.
Make the credential
An incoming webhook for the channel you want, or an API token scoped to the one project that should receive tickets. Jira wants site + email + token + project key; GitHub wants a PAT and an owner/repo. Nothing broader than that is ever needed.
Paste it in and pick your events
Open the marketplace inside your dashboard, drop the credential into the integration you're connecting, and choose which events it should carry. Webhooks default to finding.created and scan.completed — the two most people actually want.
Send a test, then turn it on
Every integration has a test button that makes a real call and shows you the real response — the connected account, the channel, or the HTTP status your endpoint returned. Once you've seen it land, flip the toggle and it's live.
The credential stays yours. Revoke the token or delete the webhook on your side and delivery stops immediately — there's no second copy of your access sitting anywhere, and nothing of ours outlives the credential you issued.
Or skip the push entirely.
Everything above sends data to a tool. The MCP server does the opposite: it lets the AI tools your team already uses read your findings, assets, compliance posture and knowledge base directly — so "what's still open on the payments API?" is a question you ask in the client you're already in.
Using something that isn't here?
Tell us what it is and how you'd use it. Requests go straight to the people who decide what gets built next — and in the meantime, a custom webhook will almost certainly get you there today.
The things people actually ask.
No. The portal is licensed to your company, not per seat or per connector, so every integration listed here is available to any authenticated user in your workspace. There's no tier that unlocks Jira.
Not for any of this. Every integration on this page is an outbound HTTPS call from our infrastructure to an endpoint you nominate — your Slack hook, your Jira site, your own receiver. Nothing here asks you to open a port or allowlist an inbound source. Internal network testing is a separate thing entirely, and that uses the lk-exporter agent, which also only talks outbound.
No — and that's structural rather than a setting. Everything Lory writes sits in a review queue and is invisible even to you until a Lorikeet pentester has read the evidence and countersigned it. Integrations fire off published findings, so a ticket in your backlog has already passed a human.
Delivery is attempted once and the outcome is written to your integration log with the HTTP status, so a failure is visible rather than silent. There's no queue that replays missed deliveries yet — if you need guaranteed-once semantics today, treat the webhook as a notification and reconcile against the findings API or the MCP server, which are always authoritative.
As little as your tool allows. A chat integration needs one incoming webhook, which can only post to the single channel you created it for. A tracker integration needs a token that can create issues in one project. We never ask for a workspace-wide OAuth grant, and scoping down is always the right call — if a narrower token breaks something, that's a bug worth telling us about.
The clean way to do this today is a custom webhook: subscribe to finding.created, branch on the severity in your own receiver, and fan out from there. Per-severity routing configured natively in the dashboard is a fair request — send it through the form above and it gets counted.
Yes — that's what the MCP server is for. Point Claude, Claude Code or any MCP client at it and it can list, search and open findings, check assets, request retests and read the compliance mapping. Auth is OAuth 2.1 or a workspace token, scopes are per token, and access is hard-limited to your own company's data.
Connect one in the time this took to read.
Grab a webhook URL from the channel your team already watches, paste it in, and the next finding we publish shows up there. If you'd rather see the whole thing working end to end first, we'll walk you through a real engagement and its delivery log.