Automation · IT and security
How to build vulnerability to ticket routing
The scanner reports eleven thousand findings and the team fixes the ones at the top of the list. Here is how ranking that reflects real risk actually works, the prompts that build it, and what running it demands.
Built with Tray Headless
- System Scanner
- Step Resolve asset
- Step Rank on exploitability
- Step Group by fix
- System Jira
Findings are grouped by the fix instead of by the finding, so one dependency bump closes forty items instead of opening forty tickets.
The short answer
What is vulnerability to ticket routing?
Vulnerability routing breaks into four parts: ranking on exploitability and exposure rather than on CVSS alone, grouping findings by the fix instead of by the finding, routing to the team that ships the patch instead of to security, and tracking remediation against an agreed target. The mistake that costs most is ranking on severity. A critical on an internal test box outranks nothing, and a medium on an internet-facing service with a known exploit outranks everything.
What matters here
- Rank on exploitability and exposure, not CVSS. A critical on a test box is not a critical.
- Group by the fix. One dependency bump closing forty findings is one ticket, not forty.
- Route to whoever deploys the fix. Security raising a ticket for security is a queue that never empties.
- Set targets by risk band and report the ones about to breach, not the ones that already have.
- Track accepted risks with an expiry. A permanent acceptance is a decision nobody revisits.
Who this is for
You run security engineering or platform. Scanners produce more findings than anybody can action, and the backlog grows faster than remediation.
How it works in practice
The path from a scanner firing to a fix shipping.
- 1
Findings are resolved to an asset and an owner
A finding on an unidentified host cannot be ranked or routed, so that is the first problem to solve.
- 2
Ranking uses exploitability and exposure
Known exploited, internet-facing, data classification, and whether a fix exists.
- 3
Findings are grouped by the fix
Forty findings resolved by one dependency upgrade is one piece of work.
- 4
Work routes to the team that ships
The service owner, in their tracker, with the fix already identified.
- 5
Targets are set by band and warned before breach
A warning is actionable and a breach report is an apology.
- 6
Accepted risks carry an expiry
So an acceptance made under pressure is revisited rather than becoming permanent.
What vulnerability routing is made of
Four parts, though the second is what makes the backlog tractable.
Exploitability ranking
Known exploited, internet-facing, data held, fix available. CVSS describes the flaw and says nothing about your exposure to it.
Grouping by fix
One upgrade that closes forty findings is one ticket. Grouping by finding is why backlogs look unfixable.
Routing to the shipping team
Whoever deploys the service, in the tracker they already use. Security cannot patch what it does not deploy.
Targets with expiring acceptances
Remediation targets by band, and any accepted risk carrying an expiry so it comes back for a decision.
The Tray Headless prompts
Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.
Once per project, run
/tray-workflows:set-workspace
to pick the workspace these build in. Point it at a sandbox first.
- 1
Set up, then resolve findings to owners
An unattributed finding cannot be ranked or routed.
Headless skills
build-workflowUse build-workflow. The systems in play are Datadog, GitHub, Jira, Okta, Slack, Vanta and Snowflake, or whatever we run in those seats. Before you plan anything, tell me which of them are already authenticated in the workspace, because I do not want a connector stubbed that I have not authenticated. The detail that matters most is the scanners and our asset inventory. I need findings with their CVE, affected component and host, plus the asset register with owner, environment, exposure and data classification. Report findings that cannot be resolved to a known asset. That number is usually large and it is the first thing to fix, because an unattributed finding cannot be ranked, routed or closed. It just sits in the count making the backlog look worse than it is.
- 2
Rank on exploitability, not severity
CVSS describes the flaw and says nothing about your exposure.
Headless skills
build-workflowUse build-workflow. Compute a rank from: Is it on a known exploited vulnerabilities list, which outweighs everything else Is the affected asset internet-facing What data classification does that asset hold Is it in production Does a fix actually exist yet, because a finding with no patch is a mitigation task instead of a patch task Is the vulnerable code path reachable, where the scanner can tell Then band into fix-now, fix-this-sprint, fix-this-quarter and accept. A critical on an internal test instance outranks nothing. A medium on an internet-facing service with a published exploit outranks everything, and severity alone gets that exactly backwards.
Known-exploited should dominate the ranking. A vulnerability being actively used is a different category from one that is theoretically severe.
- 3
Group by the fix, not by the finding
Forty findings closed by one upgrade is one ticket.
Group before creating any ticket: Same package upgrade across many services Same base image across many containers Same CVE across many hosts Same configuration change across an environment Create one ticket per fix, listing every finding it closes, with the specific version to upgrade to. This is the difference between a backlog that looks impossible and one that is a fortnight of work. Eleven thousand findings is frequently a few hundred actual fixes, and presenting the raw count is why nobody starts.
- 4
Route to whoever ships the fix
Security raising tickets for security is a queue that never empties.
Headless skills
tray-gotchasUse tray-gotchas, then route each grouped fix to the team that owns and deploys the affected service, in the tracker they already work in, with the target version and the affected services listed. Do not route to a central security queue. Security cannot patch a service it does not deploy, and a queue of tickets waiting to be handed on is a queue that only grows. Handle: a service with no owner, which is an ownership problem to escalate rather than a ticket to file; a finding in a third-party component with no available fix, which becomes a tracked mitigation; a false positive, which needs suppressing with an expiry so it does not hide a real finding later; and a fix that requires a breaking upgrade, which is a planning conversation rather than a patch.
- 5
Warn before a target breaches, and expire acceptances
A breach report is an apology and a warning is an action.
Set remediation targets per band and alert before they breach instead of after: fix-now: 7 days, alert at day 4 fix-this-sprint: 30 days, alert at day 21 fix-this-quarter: 90 days, alert at day 70 Accepted risks always carry an expiry, maximum 90 days, with an owner and a written reason. On expiry the acceptance lapses and the finding returns for a decision. A permanent acceptance is a decision nobody revisits, usually made under release pressure by somebody who has since changed team. Report: findings by band, grouped fixes open and their age, time to remediate by band, acceptances expiring, and findings with no owner.
- 6
Test it, then hand the ranking to security
Because the risk model changes with the estate.
Run the per-step schema checks and the whole-workflow audit before this touches production. Run it read-only for a fortnight and compare the ranking against what the team actually chose to fix. Then open the same workflow in Tray Build so security engineering can adjust the ranking weights, the targets and the grouping rules in the visual canvas.
What it connects to
Findings come from scanners and fixes ship from engineering, and the asset register connects them.
ServiceNow
Read the CMDB to resolve an affected host to its configuration item and owner, then raise the remediation record against it.
Reads and writes
GitHub
Read dependency findings and the services affected, and open the pull request where the fix is a version bump.
Reads and writes
Jira
Create one ticket per grouped fix in the team's own tracker, with every finding it closes listed.
Writes
Okta
Resolve service owners to real people, so a fix routes to somebody rather than a team name.
Reads
Vanta
Push remediation evidence in, so the vulnerability management control is answerable from where audits are.
Writes
Same build, other stacks
The design does not change if you run something else in one of these seats. The same prompts build it against Google BigQuery, Microsoft Teams, Azure Active Directory, Jira Service Desk, Databricks or Google Chat.
Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.
Running it in production
This is a security control an auditor tests and an attacker benefits from you neglecting.
This runs as infrastructure, not as a script
Scanner ingestion, grouping and target warnings run continuously on the same engine, including for the finding published on a Friday night.
Every decision is recorded
Which ranking produced which band, who accepted a risk and until when. That record is the vulnerability management control an audit asks to see.
Credentials are managed, never written into the build
Scanner and asset inventory access describes every weakness in your estate. Read-only, scoped, and held in your workspace.
Security engineering own the ranking
Weights, targets and grouping rules open in Tray Build, tuned against what the team actually prioritises, not against a formula.
Acceptances always expire
Maximum 90 days with an owner and a reason. A permanent acceptance is a decision made under pressure that nobody ever revisits.
Questions people ask
Why not rank on CVSS?
Because CVSS describes the flaw and says nothing about your exposure to it. A critical on an internal test box outranks nothing; a medium on an internet-facing service with a published exploit outranks everything.
Why group by fix?
Because eleven thousand findings is frequently a few hundred actual fixes. One dependency upgrade closing forty findings is one piece of work, and presenting the raw count is why nobody starts.
Why route to engineering, not security?
Because security cannot patch a service it does not deploy. A central security queue is a place tickets wait to be handed on, and it only ever grows.
Why must accepted risks expire?
Because a permanent acceptance is a decision nobody revisits, usually made under release pressure by somebody who has since changed team. Ninety days maximum, with an owner and a reason.
What is the first thing to fix?
Findings that cannot be resolved to a known asset. They cannot be ranked, routed or closed, and they inflate the backlog while contributing nothing to it.
Vibe-coding app guides
Vibe-code an entire app with Helix
This moves the data between systems. It does not give anybody a screen to work in. Build that app in Claude Code, Codex or Cursor, then deploy and run it governed on Tray Helix. Same kind of guide, same kind of prompts.
How to build a bug triage queue (opens helix.tray.ai in a new tab)
Related guides
IT and security
How to build security alert triage
Enrich before a human sees it, suppress the known-benign, escalate on asset value, and measure what you closed rather than what fired. The prompts.
IT and security
How to build incident to resolution
Declare fast, assemble the channel and the timeline automatically, keep customers informed on a cadence, and make the postmortem unavoidable. The prompts.
Last reviewed September 2026.