Skip to content

feat(integration-crowdstrike): endpoint block event poller (Stage 1) - #58

Draft
KunalSin9h wants to merge 2 commits into
mainfrom
feat/integration-crowdstrike-events
Draft

KunalSin9h wants to merge 2 commits into
mainfrom
feat/integration-crowdstrike-events

Conversation

@KunalSin9h

Copy link
Copy Markdown
Member

What

Adds safedep integration crowdstrike run, a cursor-based poller that streams SafeDep endpoint package-guard block events and, in this stage, logs them. Two signals, treated as one stream tagged by action:

  • Malicious package blocks (PmgPackageAction.BLOCKED)
  • Dependency cooldown blocks (PmgPackageAction.COOLDOWN_BLOCKED)

This is Stage 1 (poll + log). Stage 2 (push to CrowdStrike SIEM) and Stage 3 are future work — the sink is a port from day one, so Stage 2 is a new adapter plus one wiring line.

How

  • Source: EndpointManagementService.ListEndpointPackageGuardEvents over the control plane (a.ControlPlane(), OAuth), the same service the safedep endpoint commands use. Filtered server-side to PACKAGE_DECISION + the two block actions, ascending by event time.
  • Cursor: profile-scoped KV watermark on event.Timestamp with EventId boundary dedup (the API doesn't document TimeRange.Start inclusivity, so we're correct either way). TimeRange requires both Start and End and rejects start >= end, so End is capped at now per drain.
  • Sink port (eventSink): printClient adapter logs each event — JSONL on stdout under -o json, human line on stderr otherwise. Swapping in a crowdstrikeClient (Stage 2) changes nothing in the source/service/cursor.
  • Mirrors the jfrog integration patterns (reporter, cursor store, poll loop, cursor set/remove verbs). jfrog is untouched (copied the small generic pieces rather than refactor a shipped feature).

Auth

Control-plane OAuth: safedep auth login (device flow). An API-key-only login does not work for this service.

Tests / checks

  • go build ./..., go vet, golangci-lint (0 issues), and the full internal/cmd/... suite incl. the cobra convention tests — all green.
  • Unit tests cover: request shape (both actions, ascending, page size, start<end), multi-page token walk, cursor advance + EventId dedup, backfill, first-run anchor, PermissionDenied→not-entitled, Unauthenticated→auth error, callback-error wrap, infra-retry, and event→JSON/human mapping for both actions.

Notes for reviewers

  • docs/integration-crowdstrike-spec.md is the design record (staging, decisions, open items).
  • Draft: pending a live end-to-end run against a tenant with the endpoint add-on.

🤖 Generated with Claude Code

Add `safedep integration crowdstrike run`, a cursor-based poller that
streams SafeDep endpoint package-guard block events and logs them.

- Source: EndpointManagementService.ListEndpointPackageGuardEvents over
  the control plane (a.ControlPlane, OAuth), filtered to PACKAGE_DECISION
  with BLOCKED and COOLDOWN_BLOCKED actions, ascending by event time.
- Cursor: profile-scoped KV watermark on event.Timestamp with EventId
  boundary dedup (TimeRange.Start inclusivity is undocumented). TimeRange
  requires both Start and End, so End is capped at now per drain.
- Sink is a port (eventSink) with a printClient adapter that logs each
  event (JSONL under -o json, human line otherwise). A crowdstrikeClient
  SIEM-push adapter is Stage 2: swap the adapter, nothing else changes.
- Mirrors the jfrog integration patterns (reporter, cursor store, poll
  loop, cursor set/remove verbs); jfrog is untouched.

Docs, README links, and a design spec included. Tests cover request
shape, paging, cursor advance + dedup, backfill, and error mapping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

Explain that next_page_token is a within-cycle paging cursor only, while
TimeRange.Start is the client-maintained cross-cycle freshness cursor, and
why a Timestamp watermark is correct for immutable append-only events.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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