Documentation

Information, explanations, and more!

We at DarkHorse like to think that everything we’ve done on the platform makes perfect and intuitive sense. However, even when things make perfect sense to us, for people not familiar with the insides of our minds, it’s probably worth explaining how things work, as well as why we do some of the things we do. That’s what this page is for: explaining specific nuances of the DarkHorse model, that may or may not be intuitive otherwise.
Documentation / Definitions / How-To

DarkHorse rates all findings with a Risk score. This score is intended to represent the relative risk that the vulnerability poses to the organization.

DarkHorse believes that risk is informed by two key pieces of information: (1) the technical severity of an issue (e.g. how much damage could this cause, if exploited in the wild); and (2) context. As opposed to rating purely on technical severity, our risk score provides a more complete picture that allows one to be able to more effectively prioritize that which poses the highest risk to the organization.

How the risk score is calculated is shown in the table below. You can also read our comprehensive writeup on the topic here.

Our perspective on managed triage is that it inherently contains a large amount of duplicative (and thereby inefficient) efforts. Of course, your mileage may vary, but this is our general take on the matter (it's also covered in a few places, including our whitepaper on it here):

If you get 100 reports over the course of a year, it's pretty well established in the industry that ~25-30% of those are expected to be valid, unique, in-scope reports.

You will have to replicate and interact with all of those reports.

It's also unlikely that your input won't be needed on other reports – for instance, anyone who has run a program can attest to needing to weigh in during the triage process as to whether a given report is an actual security vulnerability, or if such and such a thing is out of scope, and so on. We'll call that another 5-10% of all reports.

So, out of 100 total reports, you're having to engage on anywhere from 30-45% of what gets submitted. Said, differently, if you were previously operating from a place of "triage costs us $x per report", it's probable that the true cost was being underestimated by as much as nearly 50%.

And that's not yet taking into account that valid reports are the most time consuming category of report. Which is to say that the remaining 55-70% of reports are made up duplicates, not applicable findings, and items that are out of scope – which are non-coincidentally, the easiest finding to triage.

When we put a lower weight those types of reports, relative to valid, unique findings, it becomes clear that while triage may touch 100% of reports, you are also having to touch at least 50% of the work.

At DarkHorse, we're all about efficiency, and duplicating efforts for ~50% of the work is not something we'd consider to be efficient. Which is why we don't offer managed triage by default – because we're here to offer the simplest, most efficient option to the market. Is it economically efficient to fly on a private jet? In most cases, no. But is it convenient? Sure. Sometimes convenience outweighs the economics, especially if economics aren't a significant concern.

We make no argument that paying for managed triage isn't beneficial, and for many organizations it may still be cost-efficient. We're just presenting the facts; what you do with them is up to you.

The same principle applies to providing support – where most support issues require client interaction of some sort, it makes no sense to have a middleman for the sake of being a middleman, and so we simply don't do that.

Overview

DarkHorse supports SAML 2.0-based Single Sign-On (SSO), allowing your organization's users to authenticate using your existing Identity Provider (IdP) such as Okta, Azure AD, Google Workspace, or OneLogin.

Prerequisites
  • Organization Owner access in DarkHorse
  • Administrator access to your Identity Provider
  • Ability to add DNS TXT records for your domain (for domain verification)
Step 1: Access SSO Configuration
  1. Log in to DarkHorse as an Organization Owner
  2. Navigate to your Organization Settings
  3. Click on SSO Configuration
Step 2: Add and Verify Your Domain

Before enabling SSO, you must verify ownership of your email domain:

  1. In the SSO Configuration panel, click Add / Manage Domains
  2. Enter your organization's email domain (e.g., yourcompany.com)
  3. Click Submit / Save
  4. A unique verification token will be displayed
  5. Add a DNS TXT record to your domain: darkhorse=<your-unique-token>
  6. Return to DarkHorse and click Re-check domains
  7. If successful, your domain will show as Validated: True

Note: DNS changes can take up to 48 hours to propagate. Having trouble? Contact us at info@darkhorse.sh for manual verification options.

Step 3: Configure Your Identity Provider

In your Identity Provider, create a new SAML application for DarkHorse. The SSO Configuration page in DarkHorse displays the exact URLs you need to copy into your IdP:

  • ACS URL – Assertion Consumer Service URL (where your IdP sends the SAML response)
  • Single Logout URL (SLO) – For logout functionality
  • SP Entity ID – DarkHorse's unique identifier
  • SP Metadata URL – Import this into your IdP to auto-configure
  • Name ID Format – Use EmailAddress format
  • Required Attribute – Your IdP must send an "Email" attribute

All required URLs are displayed in the SSO Configuration panel – just click to copy.

Step 4: Enter IdP Settings in DarkHorse

From your Identity Provider, collect and enter the following into DarkHorse:

  • Entity ID – Your IdP's unique identifier
  • SSO URL – The Single Sign-On URL from your IdP
  • SLO URL – The Single Logout URL (optional)
  • x509 Certificate – Your IdP's public signing certificate (include BEGIN/END lines)
  • Domain – Select your verified domain

Check SSO Enabled and click Submit / Save.

How SSO Login Works

Once configured, users can log in via SSO in two ways:

Option 1 - Via Login Page:

  1. Users navigate to https://darkhorse.sh/login
  2. They enter their email address
  3. If their email domain matches your SSO domain, they're redirected to your IdP
  4. After authenticating, they're logged into DarkHorse

Option 2 - Direct SSO URL: Users can bookmark the direct SSO login URL (shown in your SSO Configuration panel) which immediately redirects to your IdP.

Important: Organization Owners can still log in with their DarkHorse password (for emergency access). New SSO users are automatically created and linked to your organization, but will need an org owner to grant them access to specific engagements.

SP Metadata

DarkHorse provides a metadata URL (shown in your SSO Configuration panel) that can be imported into most Identity Providers to auto-configure the integration.

Need Help?

Contact us at info@darkhorse.sh for assistance with SSO configuration.

Overview

Connect DarkHorse to your Jira Cloud instance to automatically sync security reports as Jira issues. Track remediation in your existing workflow without switching tools.

Features
  • Automatic sync: Reports are pushed to Jira when they reach a configured state (e.g., "Accepted")
  • Manual push: Push individual reports to Jira on demand
  • Bi-directional updates: Changes in Jira sync back to DarkHorse
  • Custom mappings: Map DarkHorse report states to your Jira workflow statuses
  • Per-engagement settings: Use different Jira projects for different engagements
Step 1: Connect Your Jira Account
  1. Navigate to Integrations in your organization settings
  2. Click Configure on the Jira card
  3. Click Connect to Jira
  4. You'll be redirected to Atlassian to authorize the connection
  5. Select the Jira site you want to connect and click Accept

Note: You need Jira admin permissions to authorize the connection.

Step 2: Configure Default Settings

After connecting, configure your default settings:

  • Default Project: Which Jira project should receive new issues
  • Issue Type: Bug, Task, Story, etc.
  • Push Trigger: When should reports automatically sync (e.g., when accepted)
  • Status Mappings: Map DarkHorse states to your Jira workflow statuses
Step 3: Enable Bi-Directional Sync (Webhook Setup)

To sync changes FROM Jira back to DarkHorse (e.g., status updates), you must configure a webhook in Jira:

  1. In DarkHorse, go to Integrations → Jira Configuration
  2. Copy the Webhook URL and Webhook Secret shown in the configuration
  3. In Jira, go to Settings → System → Webhooks
  4. Click Create a Webhook
  5. Give it a name (e.g., "DarkHorse Sync")
  6. Paste the Webhook URL from DarkHorse
  7. Paste the Webhook Secret from DarkHorse into the "Secret" field
  8. Under Events, check Issue → updated
  9. Click Save

Important: The webhook secret is required for security. Without it, Jira updates will not sync to DarkHorse.

Step 4: Per-Engagement Settings (Optional)

Override default settings for specific engagements:

  1. Go to the engagement's settings page
  2. Click on Jira Configuration
  3. Enable or disable Jira sync for this engagement
  4. Optionally set a different project, issue type, or labels
Using the Integration

Automatic Push: When a report reaches your configured trigger state, it's automatically created in Jira.

Manual Push: On any report, click the Push to Jira button to create or update the linked Jira issue.

View in Jira: Once synced, a link to the Jira issue appears on the report.

What Gets Synced

DarkHorse → Jira (when pushing):

DarkHorse FieldJira Field
Report TitleSummary (with severity prefix, e.g., "[HIGH] XSS in Login")
SeverityPriority
Vulnerability details, steps to reproduce, impactDescription (formatted)
Report StateIssue Status (via your mappings)

Jira → DarkHorse (bi-directional, requires webhook):

Jira FieldDarkHorse Field
Issue StatusReport State (e.g., "Done" → "Remediated")
PrioritySeverity

Note: Only Status and Priority sync from Jira to DarkHorse. Title and description changes in Jira are not synced back.

Default Status Mappings

When syncing from Jira to DarkHorse, these default mappings are used (case-insensitive):

Jira StatusDarkHorse State
Open, To Do, BacklogNew
In Progress, In ReviewProcessing
Done, Resolved, ClosedRemediated
Won't Do, Rejected, CancelledOut of Scope

You can customize these mappings in the Jira Configuration page.

Troubleshooting
  • Can't see projects: Make sure your Jira account has access to the projects you want to use
  • Push fails: Check that the issue type exists in your selected project
  • Status not updating in DarkHorse: Verify the webhook is configured in Jira with the correct URL and secret
  • Webhook returning 401: Ensure the webhook secret in Jira matches the one shown in DarkHorse
  • Status changes not syncing: Make sure "Issue → updated" event is enabled on the Jira webhook
  • Custom statuses not mapping: Add custom status mappings in the Jira Configuration page
Need Help?

Contact us at info@darkhorse.sh for assistance with Jira integration.

Overview

DarkHorse provides a REST API for programmatic access to your security data. Use the API to integrate DarkHorse with your CI/CD pipelines, SIEM systems, or custom workflows.

Step 1: Create an API Key
  1. Go to Integrations in your organization settings
  2. Click Manage API Keys
  3. Click Create API Key
  4. Enter a name (e.g., "CI/CD Pipeline" or "SIEM Integration")
  5. Select the permissions (scopes) the key should have
  6. Optionally restrict to specific engagements or IP addresses
  7. Important: Copy your key immediately - you won't see it again!
Step 2: Authenticate Your Requests

Include your API key in the Authorization header:

Authorization: Bearer darkhorse_api_your_key_here
Example Request
curl -X GET "https://darkhorse.sh/api/v1/reports" \
  -H "Authorization: Bearer darkhorse_api_xxx" \
  -H "Content-Type: application/json"
Available Scopes
ScopeDescription
read:reportsView reports and their details
write:reportsUpdate report state and severity
read:engagementsView engagement information
read:organizationView organization details
full:accessAll permissions
API Endpoints
MethodEndpointDescription
GET/api/v1/healthHealth check (no auth)
GET/api/v1/reportsList all reports
GET/api/v1/reports/{uuid}Get report details
PATCH/api/v1/reports/{uuid}/updateUpdate report
GET/api/v1/engagementsList engagements
GET/api/v1/organizationGet org info
Interactive API Documentation

For interactive documentation with "Try it out" functionality, visit /api/v1/swagger/ (requires login).

Security Features
  • Organization isolation: API keys can only access data from their own organization
  • Engagement scoping: Optionally restrict keys to specific engagements
  • IP restrictions: Whitelist specific IP addresses
  • Expiration: Set automatic expiry dates on keys
  • Audit logging: All API requests are logged
Rate Limits

API keys have a default rate limit of 1,000 requests per hour. Contact us if you need higher limits.

Need Help?

Contact us at info@darkhorse.sh for assistance with API integration.