Jira Integration

Connect DryRun Security to Jira using automation middleware for automated ticket creation and deduplication.

Overview

DryRun Security does not have a native Jira integration today, but admins can connect DryRun Security to Jira using an automation middleware tool, either Tines or Zapier. DryRun Security sends a webhook when a finding is detected on a PR scan. The middleware receives the webhook, unpacks the finding details, checks Jira for an existing ticket for that finding, and either creates a new ticket or updates the existing one.

When a PR is scanned and a finding is returned, DryRun Security sends a POST request with a JSON payload containing the event type, timestamp, repository, pull request number, and a finding object with id, severity, category, title, file, line, and description. See the Webhook Integration page for the full payload structure and configuration details.

Prerequisites

  • DryRun Security webhook configured (see Webhook Integration)
  • A Jira project with API access (Jira API token and project key)
  • A Tines or Zapier account

Jira Field Mapping

Map DryRun Security finding fields to Jira ticket fields as follows:

Jira FieldValue from DryRun
Summary[DryRun] {finding.title} in {finding.file}:{finding.line}
DescriptionFull finding description, repository, PR number, severity, file path, finding ID
Labelsdryrun-security, {finding.severity}, {finding.category}, {finding.id} (used for deduplication)
PriorityCritical → Highest, High → High, Medium → Medium, Low → Low

Note: The finding.id label is used as the deduplication key to check whether a ticket already exists.

Tines Workflow

Tines is a security automation platform. Use it to receive DryRun Security webhooks and automate Jira ticket creation with deduplication logic.

  1. Create a Webhook action in Tines: Add a “Webhook” action as the trigger. Tines will generate a unique URL. Copy this URL and use it as the DryRun Security webhook destination in Settings > Integrations.
  2. Add a Filter action: Filter on event == "new_finding" to ensure the workflow only runs for new findings (not scan completions or resolved findings).
  3. Search Jira for an existing ticket: Add an HTTP Request action to call the Jira REST API:
    GET {JIRA_BASE_URL}/rest/api/3/search
      ?jql=project={PROJECT_KEY} AND labels="{finding.id}" AND statusCategory != Done
    Authorization: Basic {base64(email:api_token)}

    This checks whether a ticket already exists for this specific finding by searching for its unique ID in labels.

  4. Add a Branch (condition) action: Check the issues array in the Jira search response:
    • If issues.length > 0 → ticket exists → go to Step 5
    • If issues.length == 0 → no ticket → go to Step 6
  5. Add a comment to the existing Jira ticket. HTTP Request action:
    POST {JIRA_BASE_URL}/rest/api/3/issue/{issues[0].id}/comment
    Body:
    {
      "body": "DryRun Security flagged this finding again on PR #{pull_request} in {repository} at {timestamp}."
    }
  6. Create a new Jira ticket. HTTP Request action:
    POST {JIRA_BASE_URL}/rest/api/3/issue
    Body:
    {
      "fields": {
        "project": { "key": "{PROJECT_KEY}" },
        "summary": "[DryRun] {finding.title} in {finding.file}:{finding.line}",
        "description": {
          "type": "doc", "version": 1,
          "content": [
            { "type": "paragraph", "content": [{ "type": "text", "text": "PR: #{pull_request} | Repository: {repository}" }] },
            { "type": "paragraph", "content": [{ "type": "text", "text": "Severity: {finding.severity} | Category: {finding.category}" }] },
            { "type": "paragraph", "content": [{ "type": "text", "text": "File: {finding.file}:{finding.line}" }] },
            { "type": "paragraph", "content": [{ "type": "text", "text": "Finding ID: {finding.id}" }] },
            { "type": "paragraph", "content": [{ "type": "text", "text": "{finding.description}" }] }
          ]
        },
        "issuetype": { "name": "Bug" },
        "labels": ["dryrun-security", "{finding.severity}", "{finding.id}"],
        "priority": { "name": "{mapped priority}" }
      }
    }

Workflow diagram: Webhook → Filter (new_finding) → Search Jira → Branch → [Comment on existing ticket | Create new ticket]

Zapier Workflow

Zapier is a no-code automation platform. Use it to build the same DryRun Security → Jira workflow without writing code.

  1. Create a new Zap and choose “Webhooks by Zapier” as the trigger: Select “Catch Hook” as the trigger event. Zapier generates a webhook URL. Copy it and configure it as the DryRun Security webhook destination in Settings > Integrations.
  2. Test the trigger: Use DryRun Security’s Test button in the webhook configuration to send a sample payload. This lets Zapier detect the field structure from the finding payload.
  3. Add a Filter step: Insert a “Filter” action and set the condition: event (exactly) new_finding. This ensures the Zap only continues for new findings.
  4. Add a “Find Issue” Jira action: Choose the Jira Cloud app and select “Find Issue.” Configure the search using JQL:
    project = {PROJECT_KEY} AND labels = "{finding.id}" AND statusCategory != Done

    Map finding.id from the DryRun Security payload as the label value.

  5. Add a “Paths” step (two branches):
    • Path A: Ticket exists (Find Issue returned a result):
      • Add a Jira “Add Comment to Issue” action.
      • Set the Issue ID from the Find Issue result.
      • Comment body: DryRun Security flagged this finding again on PR #{pull_request} in {repository}.
    • Path B: No ticket (Find Issue returned no result):
      • Add a Jira “Create Issue” action.
      • Map fields from the DryRun Security payload:
        • Summary: [DryRun] {finding.title} in {finding.file}:{finding.line}
        • Description: PR: #{pull_request} | Repository: {repository} | Severity: {finding.severity} | File: {finding.file}:{finding.line} | Finding ID: {finding.id} | {finding.description}
        • Labels: dryrun-security, severity value, finding ID
        • Priority: map from severity
        • Issue Type: Bug
  6. Turn on the Zap: Once all steps are configured and tested, enable the Zap.