Skip to content

hiperai: add SecureAI integration for security and AI-governance events - #21158

Open
juanmandelbaum wants to merge 7 commits into
elastic:mainfrom
juanmandelbaum:add-hiperai-final
Open

juanmandelbaum wants to merge 7 commits into
elastic:mainfrom
juanmandelbaum:add-hiperai-final

Conversation

@juanmandelbaum

@juanmandelbaum juanmandelbaum commented Sep 9, 2026 •

Copy link
Copy Markdown

Summary

This PR adds a new integration package for HiperAI SecureAI, an enterprise AI security and governance platform.

What does this integration do?

SecureAI monitors and secures enterprise AI/LLM usage. This integration receives security events and normalizes them to ECS for analysis in Elastic Security.

Event types collected:

  • Authentication & login events
  • SMLTP (Secure Model Link Transport Protocol) policy violations
  • AI model usage (chat completions, API requests)
  • DLP triggers (PII/PHI detection in AI prompts)
  • Security incidents and policy enforcement
  • Configuration changes and audit logs

Integration details

  • Package name: \hiperai`n- Input type: \http_endpoint\ (SecureAI pushes events to Elastic Agent)
  • Owner: HiperAI (@Hiper-AI) — registered Elastic Technology Partner
  • Categories: Security
  • ECS mapping: Full normalization including severity levels, GeoIP, user agent parsing
  • Custom fields: \hiperai.*, namespace for platform-specific data

Resources

Checklist

  • Package passes \elastic-package check\ (Locally linted)
  • Pipeline tests included and passing
  • Documentation with setup instructions
  • Screenshots included
  • SVG logo included
  • Changelog entry added
  • ECS field mappings defined
  • Sample event included

Initial release of the HiperAI SecureAI integration package.
SecureAI is an enterprise AI security and governance platform that
provides real-time monitoring of LLM usage, SMLTP policy enforcement,
prompt injection detection, and DLP for AI workflows.

This integration receives security events via HTTP endpoint and
normalizes them to ECS fields including event categorization,
severity mapping, GeoIP enrichment, and user agent parsing.

Event types include: authentication, SMLTP violations, chat
completions, DLP triggers, API usage, and audit logs.
@juanmandelbaum
juanmandelbaum requested a review from a team as a code owner September 9, 2026 18:13
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

Reviewers

Buildkite won't run for external contributors automatically; you need to add a comment:

  • /test : will kick off a build in Buildkite.

NOTE: https://github.com/elastic/integrations/blob/main/.buildkite/pull-requests.json contains all those details.

@juanmandelbaum

Copy link
Copy Markdown
Author

/test

@qcorporation

Copy link
Copy Markdown
Contributor

@juanmandelbaum - thank you for your contributions. Appreciate it.
To refine the initial implementation would you be willing to do a pass with the integration skills : https://github.com/elastic/integration-skills

/create-integration
/maintain-integration
/review-integration
/research-integration

are the basic core skills to use.

I think it would help with refining the implementation and conforming it to some of our conventions. Happy to help with this as well.

The review-integration and create-integration will definitely help with our documentation conventions and the review will help proactively addressing issues before we run our vera-bot PR reviewer

Full quality pass using the integration-skills review/maintain workflow,
in response to reviewer feedback on PR elastic#21158.

- Bump format_version to 3.4.2 and kibana version floor to the new-package
  standard ^8.19.0 || ^9.1.0.
- Fix the preserve_original_event webhook toggle: it was writing a
  nonexistent http_endpoint config key; now it correctly pushes into tags,
  matching how the pipeline gates on it. Add url var and
  publisher_pipeline.disable_host coupling with the forwarded tag.
- Require and surface secret_header/secret_value in Fleet UI instead of
  hiding webhook auth behind advanced options.
- Fix JSE00001 compliance (message -> event.original rename/remove pair)
  and remove the deprecated trailing event.original cleanup processor.
- Replace the event.category append chain with a Painless script + params
  lookup table covering all 13 documented event types with matching
  event.type values; this also fixes a dead-code bug where the category
  conditions checked json.event_type after it had already been renamed to
  event.action. Fix the same class of bug in the event.outcome block.
- Set ecs.version, tag every processor, guard geoip lookups on IP
  presence, fix Mustache double-brace vs triple-brace field interpolation,
  and reorder on_failure to tag failed documents for retention.
- Restructure base-fields.yml to use external: ecs (correct descriptions
  instead of hand-written placeholders); move input.type to fields/beats.yml.
- Move docs/README.md source to _dev/build/docs/README.md so the shipped
  file is actually rendered instead of containing raw template
  placeholders.
- Anonymize sample_event.json and all pipeline test fixtures (RFC 5737 IPs,
  example.com/example.org emails).
- Split the single combined pipeline test fixture into one file per event
  type (14 total), add test-common-config.yml to exercise the
  preserve_original_event branch, and add coverage for the previously
  untested security_incident event type and the category-fallback script
  branch.
- Bump the ECS dependency in _dev/build/build.yml to git@v9.3.0 and fix
  changelog.yml''s placeholder PR link to the real PR elastic#21158.

elastic-package format/lint/check/build all pass clean; test pipeline
28/28 assertions pass across 14 fixtures.
@juanmandelbaum juanmandelbaum changed the title [New Integration] HiperAI SecureAI hiperai: add SecureAI integration for security and AI-governance events Sep 15, 2026
@juanmandelbaum

Copy link
Copy Markdown
Author

/test

@juanmandelbaum

Copy link
Copy Markdown
Author

Thanks @qcorporation! Ran a full pass with maintain-integration -> review-integration (two rounds: full review, fix, re-review to catch anything the fix pass introduced or missed) plus the ingest-pipelines builder guidance.

Summary of what changed (see d2f4219 for the full diff):

  • Fixed a real logic bug in the pipeline: event.category/event.type and event.outcome were being matched against json.event_type after an earlier processor had already renamed that field to event.action, so several categorization branches were silently dead. Replaced the ad-hoc append chain with a Painless script + params lookup table covering all 13 documented event types, each paired with a valid ECS event.type.
  • Fixed JSE00001 compliance (message -> event.original rename/remove pair) and removed a deprecated trailing event.original cleanup processor.
  • The Preserve Original Event toggle was writing a config key http_endpoint doesn't support; fixed to push into tags the way the pipeline actually gates on it, and added the url var plus forwarded/publisher_pipeline.disable_host coupling.
  • secret_header/secret_value were show_user: false by default (webhook effectively unauthenticated out of the box); now required and visible in the Fleet UI.
  • docs/README.md was committed pre-rendered with the {{event}}/{{fields}} template placeholders still literal; moved the source to _dev/build/docs/README.md so it's actually rendered on build.
  • Anonymized sample/test data (private IPs and non-example.com emails) in both the sample event and all pipeline test fixtures, split the single combined fixture into 14 per-scenario files, and added coverage for two previously-untested branches (security_incident, the category-fallback path).
  • Bumped format_version to 3.4.2, the Kibana floor to ^8.19.0 || ^9.1.0, and the ECS dependency to v9.3.0 to match new-package conventions; restructured base-fields.yml to use external: ecs instead of hand-written field descriptions.

elastic-package format/lint/check/build all pass clean, elastic-package test pipeline is 28/28. Kicked off /test for Buildkite on the new commit. Happy to address anything else that comes up in review.

@qcorporation

Copy link
Copy Markdown
Contributor

/test

@qcorporation

Copy link
Copy Markdown
Contributor

@vera-review-bot review

Fixes the failing dev/codeowners.Check step in Buildkite: manifest.yml
declares owner.github: Hiper-AI but no matching CODEOWNERS entry existed
for packages/hiperai, so it fell through to the repo-wide /packages/
fallback (@elastic/integrations-triaging) with no explicit entry for this
path at all.

Verified locally against the actual check (dev/codeowners.Check) rather
than guessing at the format.
@juanmandelbaum

Copy link
Copy Markdown
Author

/test

1 similar comment
@qcorporation

Copy link
Copy Markdown
Contributor

/test

sample_event.json was wrapped in a test-fixture style {events: [...]} array,
so the static test failed with 'field events is used as array of objects'.
Replace it with a single document taken from the login_success pipeline
test output, which also brings it in line with the current pipeline
(ecs.version, event.type, related.*). Regenerated docs/README.md.

Verified with elastic-package test (asset, static, pipeline) against
stack 8.19.0, matching CI.
@juanmandelbaum

Copy link
Copy Markdown
Author

/test

1 similar comment
@efd6

efd6 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

/test

@efd6

efd6 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

@vera-review-bot review

Comment thread .github/CODEOWNERS Outdated
Comment thread packages/hiperai/_dev/build/docs/README.md
Comment thread packages/hiperai/_dev/build/docs/README.md Outdated
Comment thread packages/hiperai/data_stream/events/elasticsearch/ingest_pipeline/default.yml Outdated
Comment thread packages/hiperai/manifest.yml Outdated
Comment thread packages/hiperai/img/screenshots/secureai-elastic-config.png
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

Comment thread packages/hiperai/_dev/build/docs/README.md Outdated
Comment thread packages/hiperai/data_stream/events/elasticsearch/ingest_pipeline/default.yml Outdated
Comment thread packages/hiperai/manifest.yml
@vera-review-bot

Copy link
Copy Markdown

Review summary

Issues found across the latest commits db1cdfd — 1 critical, 1 high, 3 medium, 4 low
  • 🟠 The template never passes preserve_original_event to the http_endpoint input, so event.original is never populated and the manifest toggle only adds a tag (link)
  • 🟡 The by_category fallback omits the smltp, system and analytics categories declared in fields.yml, so events with an unmapped action in those categories get no event.category/event.type (link)
  • 🟡 Option A setup steps do not match the manifest: the Elastic URL omits the listener path (default /hiperai/events) and the secret header is described as optional although both secret vars are required (link)
  • 🟡 All fixtures are complete happy-path records (link)
  • 🔵 parse_timestamp uses ignore_failure: true, so an unparseable json.timestamp is silently dropped with no error recorded (link)
  • 🔵 append_forwarded_tag re-adds forwarded whenever any tag exists, overriding an operator who removed it from the Tags var (link)
  • 🔵 The Discover screenshot shows a raw SecureAI test document in an ad-hoc data view rather than parsed events in logs-hiperai.events-* (link)

Package-level:

  • 🔴 The committed configuration screenshot (packages/hiperai/img/screenshots/secureai-elastic-config.png) shows a real Elastic Cloud deployment hostname and an unmasked Base64 API key

    Re-take the screenshot against a demo environment, or edit both fields to placeholder values that keep the same shape (an example.com hostname, a dotted/masked key). Rotate the exposed API key in the Elastic Cloud deployment regardless, since the image has been pushed to a public PR.

  • 🔵 New package ships no system test (data_stream/events/_dev/test/system/ and _dev/deploy/ are absent)

    Add packages/hiperai/_dev/deploy/docker/docker-compose.yml using the docker.elastic.co/observability/stream image in webhook mode posting a sample JSON body to http://{{Hostname}}:{{Port}}/hiperai/events, and data_stream/events/_dev/test/system/test-default-config.yml:

    service: hiperai-secureai
    input: http_endpoint
    vars:
      listen_address: 0.0.0.0
      listen_port: 8089
      secret_header: Authorization
      secret_value: ApiKey test
    data_stream:
      vars:
        preserve_original_event: true
    assert:
      hit_count: 1
    wait_for_data_timeout: 1m

Since this is a community PR, a new commit triggers another review — at most once every 30 minutes. I skip the PR while it's approved or has merge conflicts.

🤖 AI-Generated Review | Vera Review Bot - v0.4.2 | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

Ownership:
- manifest owner.github is now elastic/security-service-integrations, with a
  matching CODEOWNERS entry, following the convention used by the other
  partner security packages (bitsight, doppel, spycloud, tychon).

Screenshot:
- Replace the Elastic SIEM configuration screenshot with one that has the
  API key masked and the deployment URL redacted. The previously committed
  key has been rotated.
- Correct the declared screenshot sizes, which claimed 1920x1080 for three
  images that are none of those dimensions.

Input:
- Pass preserve_original_event to the http_endpoint input. The toggle
  previously only added the tag, so event.original was never populated;
  the system test now shows it present.

Pipeline:
- Map event.severity onto the Elastic severity scale (21/47/73/99) with a
  painless script, matching crowdstrike, sentinel_one, m365_defender and
  others, instead of the 1-5 values that were not comparable with anything.
- Complete the by_category fallback so every category declared in
  fields.yml resolves (smltp, system and analytics were missing).
- Record date parsing failures in error.message rather than discarding them
  with ignore_failure.
- Drop the processor that re-appended the forwarded tag, which overrode an
  operator who removed it from the Tags variable and duplicated what the
  stream template already does.

Docs:
- Rewrite the README to the structure required by the documentation
  guidelines, and enable docs_structure_enforced in validation.yml so
  elastic-package check verifies it.
- Drop the Elastic Stack version compatibility claim, which can skew
  against the range declared in the manifest.
- Correct the set up steps: the URL path was missing from the endpoint and
  the secret header was described as optional although it is required.

Tests:
- Add a system test and its docker deploy, exercising the webhook path end
  to end through an agent.
- Regenerate sample_event.json from that system test run, replacing the
  hand-written one.
- Add a malformed-record pipeline fixture covering unknown severity,
  invalid ip, actor-only records and an unmapped event type.

Verified against stack 8.19.0: elastic-package check and the full test
suite pass (2 asset, 30 pipeline, 1 static, 1 system).
@juanmandelbaum

Copy link
Copy Markdown
Author

Thanks @efd6 and @vera-review-bot — all review comments addressed in 4d09a4f.

The API key has been rotated. The screenshot is replaced with one where the key is masked and the deployment URL is redacted. I also corrected the declared screenshot sizes, which claimed 1920x1080 for three images that were none of those dimensions.

@efd6

  • Owner / CODEOWNERS: set both to elastic/security-service-integrations, following the convention in the other partner security packages (bitsight, doppel, spycloud, tychon — all type: partner with an Elastic team as owner.github). Happy to point this at a different team if that is not the right one.
  • README: rewritten to the structure in the documentation guidelines (Overview / What data does this integration collect? / What do I need to use this integration? / How do I deploy this integration? / Troubleshooting / Performance and scaling / Reference). I also added validation.yml with docs_structure_enforced enabled so elastic-package check verifies the structure rather than relying on review.
  • Stack version in the README: removed.
  • Severity mapping: switched to the Elastic severity scale via a painless script — info/low → 21, medium → 47, high → 73, critical → 99 — matching crowdstrike, sentinel_one, m365_defender and others. equalsIgnoreCase so mixed-case vendor values map correctly.

@vera-review-bot

  • High, preserve_original_event: correct, and it was a real gap — event.original was never populated. Fixed by passing the option to the input. I used the unconditional preserve_original_event: true form that every other http_endpoint template in the repo uses (auth0, zscaler_zia, bitdefender, bbot, beyondtrust_isi), keeping the manifest toggle as the control for the tag. The new system test confirms event.original is now present.
  • Medium, by_category fallback: added smltp, system and analytics; all nine categories declared in fields.yml now resolve.
  • Medium, README set up steps: fixed — the endpoint now includes the URL path, and the secret header is documented as required.
  • Medium, happy-path fixtures: added test-hiperai-events-malformed-record-sample.json, covering an unknown severity label, an invalid IP, an actor-only record with no top-level user, an unmapped event type, and a near-empty record.
    One caveat worth flagging: I could not commit a document with an unparseable timestamp. checkErrorMessage in elastic-package fails any pipeline test whose output carries a non-nil error.message, so the fixture that triggers the new on_failure below can never go green — and no *-expected.json in the repo contains a processor failure message. I verified the error path manually (it records Failed to parse with all enclosed parsers and leaves the rest of the document intact and correctly categorized), then shaped the fixture to exercise the missing-timestamp path instead. If there is an idiomatic way to cover that case, I would like to know it.
  • Low, parse_timestamp: ignore_failure replaced with a processor-level on_failure appending to error.message.
  • Low, forwarded tag: processor removed; the stream template and the tags var now solely govern it.
  • Low, system test: added, with a docker deploy using the stream image in webhook mode. It passes end to end through an agent, and sample_event.json is now generated from that run rather than hand-written.
  • Low, Discover screenshot: agreed, it shows a raw test document in an ad-hoc data view. Not updated yet — we will re-capture it against logs-hiperai.events-*.

Not changed, flagging for your call

convert_json_ip_to_source_ip still carries ignore_failure: true, so an invalid json.ip is dropped silently (the malformed-record fixture shows this, falling back to the actor's IP). It is the same class as the parse_timestamp finding, but the checkErrorMessage constraint above means an error.message-based fix cannot be covered by a fixture. Glad to change it if you prefer the error recorded.

Verified against stack 8.19.0 to match CI: elastic-package check and the full suite pass — 2 asset, 30 pipeline, 1 static, 1 system.

@juanmandelbaum

Copy link
Copy Markdown
Author

/test

1 similar comment
@qcorporation

Copy link
Copy Markdown
Contributor

/test

@efd6 efd6 left a comment

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.

@juanmandelbaum Thanks for the summary, very helpful in reviewing.

One nit only, then LGTM

Comment on lines +41 to +47
on_failure:
- append:
field: error.message
tag: append_error_message_parse_timestamp
value: >-
Processor '{{{ _ingest.on_failure_processor_type }}}'
{{{#_ingest.on_failure_processor_tag}}}with tag '{{{ _ingest.on_failure_processor_tag }}}' {{{/_ingest.on_failure_processor_tag}}}failed with message '{{{ _ingest.on_failure_message }}}'

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.

Because we have these here, I'd suggest that you have a conditional append to tags with "preserve_original_event" similar to the one in the global on_failure, but with an if: ctx.error?.message != null so that original events are retained when either the date or script processors fail.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done in 79b44ec — appended at the end of the processor list, with allow_duplicates: false so it does not double up with the tag the input already sets.

Verified by generating against a fixture with an unparseable timestamp: the document comes out with

"error": { "message": ["Processor 'date' with tag 'parse_timestamp' failed with message 'Failed to parse with all enclosed parsers'"] },
"tags": ["preserve_original_event"]

and the rest of the document intact and correctly categorized. That fixture is not committed, for the checkErrorMessage reason in my previous comment.

The date and severity processors handle their own failures, so the
pipeline keeps running and the preserve_original_event append in the
global on_failure never sees them. Append the tag whenever error.message
is set, so the raw event is retained for triage in those cases too.

Suggested by @efd6 in review.

Verified by generating a fixture with an unparseable timestamp: the
document comes out with error.message set and tags [preserve_original_event],
with the rest of the document intact. That fixture is not committed,
because elastic-package fails any pipeline test whose document carries a
non-nil error.message.
@juanmandelbaum

Copy link
Copy Markdown
Author

/test

@ShourieG

Copy link
Copy Markdown
Contributor

/test

@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

✅ All changelog entries have the correct PR link.

@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

💚 Build Succeeded

History

@mergify

mergify Bot commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@efd6

efd6 commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

I would propose the following commit message for the squash.

hiperai: add SecureAI integration

HiperAI SecureAI is an enterprise AI security and governance platform
that monitors and secures AI/LLM usage in organisations. This new
integration receives security events pushed by SecureAI to Elastic
Agent via the http_endpoint input and normalises them to ECS.

Events collected include authentication, policy violations (SMLTP),
AI model usage, DLP triggers (PII/PHI in prompts), security incidents,
and audit/configuration changes. Custom fields are namespaced under
hiperai.*.

@juanmandelbaum How were the test samples obtained; it is helpful to include their provenance in the commit message if issues arise. For example: derived from documentation; obtained from a live instance [with sanitization], etc.

@juanmandelbaum

Copy link
Copy Markdown
Author

@efd6 The sample/test events (sample_event.json, data_stream/events/_dev/test/pipeline/*.json, and the system-test fixtures) are synthetic, constructed from SecureAI's documented event schema — not pulled from a live instance. All identifiers, IPs and hostnames are placeholders: IPs use the RFC 5737 documentation ranges (198.51.100.0/24, 203.0.113.0/24, 192.0.2.0/24), emails use @example.com/@example.org, and session/tenant/user IDs are fabricated. sample_event.json specifically was regenerated by running the system test end-to-end (webhook → agent → pipeline) against one of those synthetic fixtures, so it reflects real pipeline output rather than being hand-typed.

For the squash, here's a proposed commit message with a provenance line added, and "Hiper AI" corrected (with the space):

hiperai: add SecureAI integration

Hiper AI SecureAI is an enterprise AI security and governance platform
that monitors and secures AI/LLM usage in organisations. This new
integration receives security events pushed by SecureAI to Elastic
Agent via the http_endpoint input and normalises them to ECS.

Events collected include authentication, policy violations (SMLTP),
AI model usage, DLP triggers (PII/PHI in prompts), security incidents,
and audit/configuration changes. Custom fields are namespaced under
hiperai.*.

Test samples are synthetic, built from SecureAI's documented event
schema — no data from a live instance. IPs use RFC 5737 documentation
ranges and identifiers (users, tenants, sessions) are fabricated.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants