Skip to content

[hackerone] Initial release of HackerOne with Report data streams#18662

Closed
clement-fouque wants to merge 26 commits into
elastic:mainfrom
clement-fouque:hackerone-new-integration
Closed

[hackerone] Initial release of HackerOne with Report data streams#18662
clement-fouque wants to merge 26 commits into
elastic:mainfrom
clement-fouque:hackerone-new-integration

Conversation

@clement-fouque
Copy link
Copy Markdown
Contributor

@clement-fouque clement-fouque commented Apr 27, 2026

Proposed commit message

This pull request introduces the initial release of the HackerOne integration for Elastic, providing the ability to collect bug bounty and vulnerability disclosure reports from the HackerOne Customer API into Elasticsearch.

Checklist

  • I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • I have verified that Kibana version constraints are current according to guidelines.
  • I have verified that any added dashboard complies with Kibana's Dashboard good practices

Author's Checklist

  • [ ]

How to test this PR locally

Related issues

Screenshots

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Vale Linting Results

Summary: 36 warnings, 47 suggestions found

⚠️ Warnings (36)
File Line Rule Message
packages/hackerone/_dev/build/docs/README.md 6 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'versus' instead of 'vs'.
packages/hackerone/_dev/build/docs/README.md 14 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'using' instead of 'via'.
packages/hackerone/docs/README.md 7 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'versus' instead of 'vs'.
packages/hackerone/docs/README.md 15 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'using' instead of 'via'.
packages/hackerone/docs/README.md 105 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 105 Elastic.DontUse Don't use 'please'.
packages/hackerone/docs/README.md 107 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 108 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 218 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'and so on' instead of 'etc'.
packages/hackerone/docs/README.md 237 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'and so on' instead of 'etc'.
packages/hackerone/docs/README.md 278 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 295 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 295 Elastic.DontUse Don't use 'and/or'.
packages/hackerone/docs/README.md 297 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 300 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 302 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 304 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 325 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 337 Elastic.DontUse Don't use 'Thus'.
packages/hackerone/docs/README.md 360 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 360 Elastic.DontUse Don't use 'please'.
packages/hackerone/docs/README.md 362 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 363 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 473 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'and so on' instead of 'etc'.
packages/hackerone/docs/README.md 492 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'and so on' instead of 'etc'.
packages/hackerone/docs/README.md 533 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'for example' instead of 'e.g'.
packages/hackerone/docs/README.md 551 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 551 Elastic.DontUse Don't use 'and/or'.
packages/hackerone/docs/README.md 553 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 556 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 558 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 559 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 560 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 581 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 581 Elastic.QuotesPunctuation Place punctuation inside closing quotation marks.
packages/hackerone/docs/README.md 605 Elastic.Latinisms Latin terms and abbreviations are a common source of confusion. Use 'using' instead of 'via'.
💡 Suggestions (47)
File Line Rule Message
packages/hackerone/_dev/build/docs/README.md 14 Elastic.Wordiness Consider using 'because' instead of 'since'.
packages/hackerone/_dev/build/docs/README.md 58 Elastic.Wordiness Consider using 'because' instead of 'since'.
packages/hackerone/_dev/build/docs/README.md 58 Elastic.Wordiness Consider using 'because' instead of 'since'.
packages/hackerone/docs/README.md 15 Elastic.Wordiness Consider using 'because' instead of 'since'.
packages/hackerone/docs/README.md 59 Elastic.Wordiness Consider using 'because' instead of 'since'.
packages/hackerone/docs/README.md 59 Elastic.Wordiness Consider using 'because' instead of 'since'.
packages/hackerone/docs/README.md 95 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 103 Elastic.Wordiness Consider using 'tell' instead of 'inform'.
packages/hackerone/docs/README.md 103 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 103 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 105 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 105 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 106 Elastic.WordChoice Consider using 'efficiently' instead of 'simply', unless the term is in the UI.
packages/hackerone/docs/README.md 106 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 108 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 119 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 119 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 149 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 163 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 190 Elastic.Clone Use cloned only when referring to cloning a GitHub repository or creating a copy that is linked to the original. Often confused with 'copy' and 'duplicate'.
packages/hackerone/docs/README.md 201 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 201 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 291 Elastic.Wordiness Consider using 'all' instead of 'All of '.
packages/hackerone/docs/README.md 295 Elastic.Wordiness Consider using 'sometimes' instead of 'In some cases'.
packages/hackerone/docs/README.md 295 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 350 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 358 Elastic.Wordiness Consider using 'tell' instead of 'inform'.
packages/hackerone/docs/README.md 358 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 358 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 360 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 360 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 361 Elastic.WordChoice Consider using 'efficiently' instead of 'simply', unless the term is in the UI.
packages/hackerone/docs/README.md 361 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 363 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 374 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 374 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 404 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 418 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 445 Elastic.Clone Use cloned only when referring to cloning a GitHub repository or creating a copy that is linked to the original. Often confused with 'copy' and 'duplicate'.
packages/hackerone/docs/README.md 456 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 456 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.
packages/hackerone/docs/README.md 547 Elastic.Wordiness Consider using 'all' instead of 'All of '.
packages/hackerone/docs/README.md 551 Elastic.Wordiness Consider using 'sometimes' instead of 'In some cases'.
packages/hackerone/docs/README.md 551 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 559 Elastic.WordChoice Consider using 'efficiently' instead of 'simply', unless the term is in the UI.
packages/hackerone/docs/README.md 572 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/hackerone/docs/README.md 603 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.

The Vale linter checks documentation changes against the Elastic Docs style guide.

To use Vale locally or report issues, refer to Elastic style guide for Vale.

Comment thread packages/hackerone/manifest.yml Outdated
if (sc.containsKey('asset_type') && sc.containsKey('asset_identifier') && sc.asset_identifier != null) {
def at = sc.asset_type;
def aid = sc.asset_identifier;
if (at instanceof String && at.equalsIgnoreCase('DOMAIN')) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium ingest_pipeline/default.yml:735

When asset_type is 'HOSTNAME', the asset identifier is mapped to host.name and dns.question.name by the map_structured_scope_asset script, but append_related_hosts_users_cve only adds the identifier to related.hosts for 'DOMAIN' assets. This causes HOSTNAME assets to be missing from related.hosts despite being present in other host-related fields. Consider adding 'HOSTNAME' to the condition at line 735 to match the upstream mapping behavior.

-            if (at instanceof String && at.equalsIgnoreCase('DOMAIN')) {
+            if (at instanceof String && (at.equalsIgnoreCase('DOMAIN') || at.equalsIgnoreCase('HOSTNAME'))) {
🤖 Copy this AI Prompt to have your agent fix this:
In file packages/hackerone/data_stream/report/elasticsearch/ingest_pipeline/default.yml around line 735:

When `asset_type` is `'HOSTNAME'`, the asset identifier is mapped to `host.name` and `dns.question.name` by the `map_structured_scope_asset` script, but `append_related_hosts_users_cve` only adds the identifier to `related.hosts` for `'DOMAIN'` assets. This causes `HOSTNAME` assets to be missing from `related.hosts` despite being present in other host-related fields. Consider adding `'HOSTNAME'` to the condition at line 735 to match the upstream mapping behavior.

@elastic-vault-github-plugin-prod
Copy link
Copy Markdown

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

@andrewkroh andrewkroh added the documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. label Apr 28, 2026
@clement-fouque clement-fouque changed the title Hackerone new integration [hackerone] Initial release of HackerOne with Report data streams Apr 30, 2026
@clement-fouque clement-fouque added New Integration Issue or pull request for creating a new integration package. Integration:hackerone HackerOne [Integration not found in source] labels Apr 30, 2026
@clement-fouque clement-fouque marked this pull request as ready for review May 1, 2026 00:08
@clement-fouque clement-fouque requested a review from a team as a code owner May 1, 2026 00:08
@clement-fouque
Copy link
Copy Markdown
Contributor Author

@elastic/security-service-integrations the integration is ready for review. Can you please take care of it? Thank you.

Cc @kruskall @jkakavas

@andrewkroh andrewkroh removed New Integration Issue or pull request for creating a new integration package. Integration:hackerone HackerOne [Integration not found in source] labels May 1, 2026
Comment thread packages/hackerone/data_stream/report/elasticsearch/ingest_pipeline/default.yml Outdated
@P1llus
Copy link
Copy Markdown
Member

P1llus commented May 4, 2026

Could you add integration-experience as the current owner for now? As we will have handle more of these in the future. Requested a peer review from services for CEL as well.

Will do an initial review later today + helping with dashboards

Copy link
Copy Markdown
Contributor

@efd6 efd6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CEL review only

Comment on lines +56 to +57
:
state.?cursor.last_activity_at.orValue("").as(curRaw,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This indentation indicates that the code was not celfmtd.

However, this is used only once. There should not be an as binding here. Maybe an state.?cursor.last_activity_at.optMap(last, (last.parse_time([time_layout.RFC3339Nano, time_layout.RFC3339]) + duration("1ms")).format(time_layout.RFC3339Nano)).orValue(string(now - duration(state.initial_interval))).

Comment on lines +36 to +38
{{else}}
inbox_ids: []
{{/if}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear why this is done given that at L45, there's an optional value deref. This else block can be omitted.

Comment on lines +28 to +30
{{else}}
program_handles: []
{{/if}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same situation here as for inbox_ids.

{
"events": {
"error": {
"code": "400",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

If there's going to be a status code, ISTM that it should come from the API. If it doesn't, it should have a comment explaining why it's a valid insertion.

"Accept": ["application/json"],
},
}).do_request().as(resp,
(resp.StatusCode == int(429) || resp.StatusCode == int(401) || resp.StatusCode == int(403) || resp.StatusCode > int(499)) ?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These conversions are not necessary.

"want_more": false,
}
:
resp.StatusCode == int(200) ?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
resp.StatusCode == int(200) ?
resp.StatusCode == 200 ?

Though suggest the happy path be put first.

Comment on lines +138 to +139
:
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation.

""
).as(page_max,
state.?cycle_max.orValue("").as(prev_max,
(page_max != "" && (prev_max == "" || page_max > prev_max)) ?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the shape of page_max and prev_max?

"code": string(resp.StatusCode),
"id": string(resp.Status),
"message": "GET /v1/reports: " + (
size(resp.Body) != int(0) ?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
size(resp.Body) != int(0) ?
size(resp.Body) != 0 ?

@P1llus P1llus self-assigned this May 4, 2026
@elasticmachine
Copy link
Copy Markdown

💚 Build Succeeded

History

cc @P1llus

@andrewkroh andrewkroh added the New Integration Issue or pull request for creating a new integration package. label May 11, 2026
@clement-fouque
Copy link
Copy Markdown
Contributor Author

Superseded by #18951.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. New Integration Issue or pull request for creating a new integration package.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants