elastic / elastic/integrations
[Sublime Security]: audit pipeline fails with dissect error on empty created_by.email_address (Sublime Support actor)
- Dominant language
- Handlebars
- Stars
- 333
- Forks
- 647
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 225
Description
### Integration Name
Sublime Security [packages/sublime_security]
### Dataset Name
sublime_security.audit
### Integration Version
1.11.2
### Agent Version
9.4.4
### Agent Output Type
elasticsearch
### Elasticsearch Version
9.4.4
### OS Version and Architecture
Linux x86_64
### Software/API Version
_No response_
### Error Message
```
Processor dissect with tag fail-dissect_created_by_email_address in pipeline logs-sublime_security.audit-1.11.2 failed with message: Unable to find match for dissect pattern: %{user.name}@%{user.domain} against source:
```
### Event Original
Sanitized, minimal reproducer. The only field that matters for the failure is the empty `created_by.email_address`. This is exactly the shape the Sublime **Support** actor produces (fixed support id, `active: false`, epoch-zero timestamps, blank string fields):
```json
{
"id": "00000000-0000-0000-0000-000000000000",
"type": "message.view_contents",
"created_at": "2026-07-22T21:00:13.840Z",
"created_by": {
"id": "f92c2c8a-21be-40c6-b805-762e95840d1a",
"active": false,
"first_name": "Sublime",
"last_name": "Support",
"email_address": "",
"phone_number": null,
"created_at": "0001-01-01T00:00:00Z",
"updated_at": "0001-01-01T00:00:00Z",
"role": "",
"is_enrolled": false,
"access_restricted": false,
"google_oauth_user_id": "",
"microsoft_oauth_user_id": ""
},
"data": {}
}
```
### What did you do?
Standalone Elastic Agent with the Sublime Security integration, `sublime_security.audit` data stream, `aws-s3` input reading audit-log objects from an S3 bucket via SQS notifications, output to Elasticsearch. No custom pipeline changes; using the package-provided ingest pipeline `logs-sublime_security.audit-`.
### What did you see?
A small but steady stream of documents flipped to `event.kind: pipeline_error` with the dissect error above.
Every failing document is an action attributed to the built-in **Sublime Support** principal (not a tenant user), whose `created_by.email_address` is an empty string `""`. Confirmed by inspecting `event.original` on the failing docs: identical actor object across all of them (`"first_name":"Sublime","last_name":"Support","email_address":""`).
The failing documents span these audit event types (`sublime_security.audit.type`) in a single 24h sample:
| `sublime_security.audit.type` | count |
|---|---|
| `message.view_contents` | 15 |
| `message_group.export.list` | 8 |
| `asa_report.viewed` | 4 |
| `auth.login.support` | 2 |
| `message.access_justification` | 1 |
### What did you expect to see?
The audit event should ingest normally. When `created_by.email_address` is empty (or otherwise not an `user@domain` string), the pipeline should skip the username/domain extraction and leave `user.name` / `user.domain` unset, rather than raising a pipeline error.
### Anything else?
**Root cause (exact location):** In `packages/sublime_security/data_stream/audit/elasticsearch/ingest_pipeline/default.yml`:
- The `rename` (tag `rename_created_by_email_address`) copies `json.created_by.email_address` verbatim; `ignore_missing` does not catch an empty string.
- The `dissect` (tag `dissect_created_by_email_address`) guards only for null:
```yaml
- dissect:
field: sublime_security.audit.created_by.email_address
tag: dissect_created_by_email_address
pattern: '%{user.name}@%{user.domain}'
if: ctx.sublime_security?.audit?.created_by?.email_address != null
on_failure: ...
```
An empty string satisfies `!= null`, so the processor runs and fails on an empty source.
**Suggested fix:** tighten the `if` to require a non-empty value containing `@`, e.g.:
```yaml
if: ctx.sublime_security?.audit?.created_by?.email_address != null && ctx.sublime_security.audit.created_by.email_address.contains('@')
```
Consider the same empty-string tolerance for the sibling steps that consume the email (`set user.email` and `append related.user`).
**Minor:** the `on_failure` for this processor renders the tag as `fail-{{{_ingest.on_failure_processor_tag}}}`, which is why the error message reads `fail-dissect_created_by_email_address`.
Contributor guide
Assessment
This issue has not been assessed yet.