ASIM: documented 'line to add' for Im_<Schema>Custom doesn't match the shipped stub signatures (5/11 schemas; 3 hard-fail, 1 fails silently)
- Dominant language
- Python
- Stars
- 6.1k
- Forks
- 3.8k
- Avg merge
- 4d 7h
- Merged PRs (30d)
- 125
Description
### Summary
The documented "line to add" for patching an `Im_Custom` stub does not match the `functionParameters` of the stubs **shipped in this repository** at [`ASIM/deploy/EmptyCustomUnifyingParsers/`](https://github.com/Azure/Azure-Sentinel/tree/master/ASIM/deploy/EmptyCustomUnifyingParsers).
For **5 of the 11 documented schemas** the argument list is wrong. Three fail hard, one fails **silently**, one loses a filter. Two further shipped stubs have no documented line at all.
I originally filed this against the docs repo as [MicrosoftDocs/defender-docs#520](https://github.com/MicrosoftDocs/defender-docs/issues/520) (2026-06-11). It has had no response in two months, and the artifacts on the wrong end of the comparison live *here* — the stubs were added by #13494, which itself cites that docs page — so I'm re-raising it where the ASIM maintainers are. Either side could be the one to change; that's the decision I'm asking for.
### Verification
- **Stubs**: `ASIM/deploy/EmptyCustomUnifyingParsers/Im_Custom.json` at `ed7ca42` (2026-08-04), read mechanically from each template's `functionParameters`.
- **Docs**: [Manage ASIM parsers → Add a custom parser to a built-in unifying parser](https://learn.microsoft.com/en-us/azure/sentinel/normalization-manage-parsers#add-a-custom-parser-to-a-built-in-unifying-parser), live page as of 2026-08-11 (`ms.date: 2026-07-01`, `updated_at: 2026-08-08`, gitcommit `422ccb92`).
### The five divergences
**1. Authentication — hard failure.** Five documented parameters do not exist in the stub, and two that do exist are absent from the docs.
```
docs: starttime, endtime, targetusername_has_any, actorusername_has_any, srcipaddr_has_any_prefix,
srchostname_has_any, targetipaddr_has_any_prefix, dvcipaddr_has_any_prefix, dvchostname_has_any,
eventtype_in, eventresultdetails_in, eventresult
stub: starttime, endtime, username_has_any, targetappname_has_any, srcipaddr_has_any_prefix,
srchostname_has_any, eventtype_in, eventresultdetails_in, eventresult, disabled, pack
```
`targetusername_has_any`, `actorusername_has_any`, `targetipaddr_has_any_prefix`, `dvcipaddr_has_any_prefix` and `dvchostname_has_any` appear in no shipped `Im_AuthenticationCustom` stub and in no `vimAuthentication*` parser in this repo. Reordering cannot fix this row — it needs the stub's real interface.
**2. ProcessEvent — hard failure.** Docs insert `targetusername_has`; the stub declares only `actorusername_has`.
**3. RegistryEvent — hard failure.** Docs say `registryvaluedata_has_any`; the stub declares `registrydata_has_any`.
For these three, the patched function references an undeclared parameter, so every invocation fails with `Failed to resolve scalar expression named ''`. The portal's *Save as function* rejects the body; an ARM deployment does **not** validate and happily deploys a function that errors on every use — including when reached through the built-in `_Im_`.
**4. AuditEvent — SILENT failure.** Same parameter set, different order.
```
docs: …, srcipaddr_has_any_prefix, eventtype_in, eventresult, actorusername_has_any, operation_has_any, …
stub: …, srcipaddr_has_any_prefix, actorusername_has_any, operation_has_any, eventtype_in, eventresult, …
```
Positional binding puts `eventtype_in` into the leaf's `actorusername_has_any` slot and `eventresult` (a `string`) into `operation_has_any` (a `dynamic`). **The default invocation still works**, so the deployment looks healthy — but any caller passing filters (e.g. a performance-optimized analytic rule calling `_Im_AuditEvent(actorusername_has_any=…)`) gets silently wrong or empty results. Nothing surfaces an error.
**5. WebSession — lost filter.** Docs omit the stub's `eventresultdetails_has_any` (declared after `eventresult`), so that filter can never be forwarded and rows the caller asked to exclude come back.
### Two additional gaps
**6. `disabled` is never forwarded — all 11 rows.** Every stub declares `disabled:bool=false`, and no documented line passes it. The parameter is therefore dead on the custom leaf: `Exclude…` watchlist entries and an explicit `disabled=true` have no effect on it. (Note the built-in unifiers *do* forward it — e.g. `imAuditEvent.yaml`.)
**7. Two shipped stubs have no documented row.** The table covers 11 schemas; this repo ships 13 stubs. `Im_AgentEventCustom` and `Im_AssetEntityCustom` have no "line to add", so there is no documented way to patch them.
### Why the testers don't catch any of this
`ASimSchemaTester` / `ASimDataTester` invoke the parser **without filter arguments**. So the mis-ordered AuditEvent patch produces byte-identical tester output to a correct one, and the unresolvable-parameter patches kill the tester query itself rather than reporting a finding. Neither failure mode is reachable through the normal validation path — which is why #4 in particular can sit in a workspace indefinitely.
### Suggested fix
1. **Regenerate the table from the shipped `functionParameters`** — those are the only signatures that resolve at runtime.
2. **Better: document named-argument invocation.** It is immune to declaration order on both sides, and it is what the built-in unifying parsers already do:
```kusto
MyNewAuditEventParser(starttime=starttime, endtime=endtime, srcipaddr_has_any_prefix=srcipaddr_has_any_prefix, actorusername_has_any=actorusername_has_any, operation_has_any=operation_has_any, eventtype_in=eventtype_in, eventresult=eventresult, object_has_any=object_has_any, newvalue_has_any=newvalue_has_any, disabled=disabled)
```
This also fixes the dead `disabled` parameter for free, and makes the table robust against any future signature change on either side.
3. **Authentication needs its row rewritten**, not reordered.
4. Add rows for `AgentEvent` and `AssetEntity`.
Happy to open a PR against either the stubs or the docs table once you've decided which side should move.
Contributor guide
Assessment
This issue has not been assessed yet.