Safeguard
Developer Tools•

How do you stop automation from creating duplicate security tickets?

Give each finding a stable key, search for it before creating a ticket, and plan for search lag. A dedupe recipe for Jira style trackers and CI jobs.

Safeguard Security Team
4 min read

Build a stable key for each finding, such as repository plus package plus advisory id, store it on the ticket, and search for that key before you create anything. If a ticket exists, update it. Expect that search results can lag behind writes, so add a second guard.

Why duplicates happen

A scheduled scan finds the same vulnerable package every night. A webhook is retried and delivers twice. Two jobs overlap. Each of these runs the same create step again, and by Friday the backlog holds six copies of one issue and nobody trusts it. People then stop reading automation tickets at all, which defeats the point.

Step 1: define the key

The key should identify the unit of work, not the occurrence. For a dependency finding, a good key is the repository name, the package name and the advisory identifier. Leave out the scan date, the commit hash and the severity, since those change between runs while the work stays the same.

If two repositories carry the same vulnerable package, decide whether they are one ticket or two. Often one ticket per owning team is right. See one vulnerability, forty repos.

Step 2: store the key where you can search it

Put the key in a label, a dedicated custom field or the first line of the description. A field is better than free text because search on it is exact. In Jira, the issue search endpoint takes a JQL query, so a lookup such as one filtering on the project, the label and the status category works well.

Step 3: search, then decide

Search resultAction
No ticketCreate one with the key
Open ticketAdd a comment only if something material changed, such as a new fixed version
Closed as fixed, finding is backReopen or create a linked regression ticket
Closed as accepted risk with a valid expiryDo nothing
Closed as accepted risk, expiry passedReopen with a note

The last two rows connect to exceptions. Our post on what should automatically revoke a vulnerability exception covers expiry rules.

Step 4: expect search lag

Atlassian's documentation for the enhanced JQL search endpoint warns that recent updates might not be immediately visible in the results, and offers a reconcileIssues parameter when you need read after write consistency. In a dedupe flow that matters: a retry that fires two seconds after the first create may search, find nothing and create a second ticket.

Defences that do not depend on the search index:

Step 5: clean up the existing mess

Run the search once without creating anything, group results by key, and close duplicates with a link to the survivor. Do it in report only mode first so you can check the grouping.

Try it yourself

Click through it at your own pace, or open it full screen.

Look at how findings are grouped and imagine which field would serve as the key.

Safeguard groups and tracks dependency findings across repositories. Try the free scan at gold.safeguard.sh/scan.

Quick check

Why not use the scan date in the key?

Because the date changes every run, so every run would look like a new finding and create a new ticket.

Is searching enough to prevent duplicates?

No. Search results can lag behind writes, so combine it with concurrency control and idempotent handling.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.