Skip to content

Add an OpenSSH package - #175

Merged
mavam merged 7 commits into
mainfrom
package/openssh
Aug 21, 2026
Merged

Add an OpenSSH package#175
mavam merged 7 commits into
mainfrom
package/openssh

Conversation

@mavam

@mavam mavam commented Aug 17, 2026

Copy link
Copy Markdown
Member

🔍 Problem

The library has no package for OpenSSH, so sshd messages arrive as opaque
Syslog text. Remote logins are one of the most widely deployed and least
structured security-relevant log sources.

🛠️ Solution

Add an openssh package that turns raw sshd message bodies into OCSF
Authentication (class 3002), following the layered normalization API our
package development tutorial
describes:

  • openssh::ocsf::normalize takes a message body all the way.
  • openssh::parse and openssh::ocsf::map stay reachable for pipelines that
    inspect, enrich, or route the structured event before mapping.
  • All three take their input positionally and write to into.

A message body carries neither a timestamp nor a host, so the normalizer takes
time and hostname from the Syslog envelope. A message template the parser
does not model becomes an OCSF Base Event that carries its payload.

💬 Review

This PR previously also aligned Amazon VPC Flow, Check Point, DHCPD, named, and
PAN-OS with the same contracts. That refactoring now follows in a separate PR,
so this one adds one package and changes nothing else.

📚 Docs PR: tenzir/content#260

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acbf82cb10

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread openssh/operators/parse.tql Outdated
Comment thread openssh/operators/parse.tql Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f35fcd0598

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread openssh/operators/ocsf/events/authentication.tql Outdated
Comment thread openssh/operators/ocsf/events/authentication.tql Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

4 similar comments
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

1 similar comment
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@mavam mavam changed the title Add an OpenSSH package with an OCSF Authentication mapper Standardize package parser and mapper contracts Aug 18, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@mavam mavam changed the title Standardize package parser and mapper contracts Add an OpenSSH package Aug 20, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

OpenSSH `sshd` writes free-form messages to Syslog, which makes remote
logins one of the most widely deployed and least structured
security-relevant log sources. Turn them into OCSF Authentication.

`openssh::ocsf::normalize` takes a message body all the way, and
`openssh::parse` and `openssh::ocsf::map` stay reachable for pipelines
that inspect, enrich, or route the structured event before mapping. All
three take their input positionally and write to `into`, following the
layered normalization API the package development tutorial describes.

A message body carries neither a timestamp nor a host, so the normalizer
takes `time` and `hostname` from the Syslog envelope. A message template
the parser does not model becomes an OCSF Base Event that carries its
payload, so no line is dropped.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

The internal mapper took the whole staging record as `$scope`, so every
line carried a prefix that said nothing: `$scope.ocsf.user.name = move
$scope.event.user.name`. "Scope" also borrows a static-semantics word for
what is just a record with two fields.

Hand the leaf the two halves it actually uses, named for their shapes:

    openssh::ocsf::events::authentication $into.openssh, $into.ocsf

    $ocsf.user.name = move $openssh.user.name

Every line now names the vocabulary on each side, and the rule has no
special case: a product's shape is called after the product, a schema
after the schema, so `splunk::cim::ocsf::dns_activity` will take
`$into.ocsf, $into.cim`. The leaf also becomes callable on its own, which
a test can use.

Flattening the record literal into per-attribute assignments drops the
`...$ocsf` respread that only existed to preserve `status_detail`.

Baselines are unchanged.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@mavam

mavam commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

Docs companion: tenzir/content#272 switches the internal mapper examples to the same $into.<product>, $into.ocsf signature this PR uses, and renames the amazon reference mapper's staging slot to match.

Every operator that fills a field now takes the field it reads and the
field it writes, both positional:

    openssh::parse message, event
    openssh::ocsf::map event, ocsf

That retires `into=` and the staging record from both. `map` no longer
wraps the two halves in a composite to keep them disjoint, because the
caller already handed it two disjoint fields, so its body drops the
`$into.` prefix from every line and the mapper reads:

    $ocsf.time = move $openssh.time?

`openssh::ocsf::normalize` keeps `into=this`, because it produces a whole
event rather than filling a field. It is now the only operator that stages
anything, and it also owns the `unmapped` join that `map` used to perform,
which puts the residue decision next to the provenance decision.

Baselines are unchanged.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Classify every parsed verb through the lookup table and apply session-state overrides as record spreads. This removes the nested session-end branches without changing parsed values.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

mavam added 2 commits August 21, 2026 14:52
Eight cases the earlier input missed: IPv6 peers, the
`keyboard-interactive/pam` method, an attempt without a trailing protocol
token, an invalid user with a `[preauth]` phase, a maximum-attempts line
without the `error:` prefix, and an authenticating user on a connection
close.

Three more pin the limits rather than the coverage. `Postponed`, `Partial`,
and `Received disconnect` yield no event, which is what the package
promises for a template it does not model.
…pper

`openssh::ocsf::normalize` took a message body plus `time` and `hostname`
arguments, because a body carries neither. Qualifiers on the one-shot call
are the wrong shape: it should take an input and be done. So it now takes
the Syslog event that carries the message, defaulting to `this`:

    where app_name == "sshd"
    openssh::ocsf::normalize

The envelope field names come from `read_syslog` and `parse_syslog` rather
than from a guess. Taking the raw line instead would not work, because
`parse_syslog` yields `content` for RFC3164 with a timestamp string that
has no year, so a correct OCSF `time` is not recoverable inside the
package.

`openssh::ocsf::map` now ends with `$ocsf.unmapped = move $openssh`, so the
mapper consumes its source from start to finish and the residue lands where
OCSF puts it. It drops the staged envelope fields first, which fixes a
`unmapped: {hostname: ...}` that the package had invented on the unmodeled
path and that no source ever sent. That is the one baseline change.

Matches tenzir/content#272.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@mavam
mavam merged commit abafa52 into main Aug 21, 2026
3 checks passed
@mavam
mavam deleted the package/openssh branch August 21, 2026 14:52
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.

1 participant