Fix stale-issue bug, add integrations (SNS+Slack), and DSPM data discovery#8
Merged
Merged
Conversation
Phase 1.1 - Stale-issue fix + trends: - Fix runner.ts existing-issue branch to re-derive riskScore/severity/pathSummary on re-match instead of skipping (was frozen at first creation) - Add PostureTrendStore for daily posture snapshots (openIssues, publicBuckets, etc.) - Add GET /trends/:metric API endpoint - CDK: add PostureTrendsTable Phase 1.2 - Integrations core (SNS + Slack): - New @khalifa/integrations package with pluggable IssueActionSink interface - SNS sink (publishes issue JSON to ISSUES_TOPIC_ARN) - Slack sink (incoming-webhook card with severity filtering) - IssueIntegrationsOrchestrator loads sinks from ISSUE_SINKS env var - Wire emitToIntegrations into runner after issue create/update - Add Issue.externalRefs field persisted to DynamoDB - API: GET /integrations/status, POST /issues/:id/suppress, POST /issues/:id/reopen - CDK: add SNS topic, grant risk-engine sns:Publish - ConfigMap: ISSUE_SINKS, SLACK_WEBHOOK_URL, SLACK_MIN_SEVERITY env vars Phase 2.2 - DSPM data discovery: - New dspm-scanner Lambda with S3 sampler + regex + Macie classifiers - Regex classifier detects: AWS keys, GCP SA JSON, private keys, JWT, credit cards (Luhn), emails, phone, SSN, high-entropy secrets - Macie classifier (opt-in) pulls findings via ListFindings/GetFindings - promoteClassification() maps PII findings to data_classification tiers - New DataClassificationFinding vertex + CLASSIFIES edge in graph schema - New RULE-011 (public datastore with PII) and RULE-012 (secret in S3) - CDK: DspmScannerFn (15m timeout, 2GB mem), EventBridge daily 03:00 UTC - ConfigMap: DSPM_SCAN_MODE (off|tagged-only|all), MACIE_ENABLED env vars Tests: 121 passing across 12 suites (risk-engine, integrations, api-service, dspm-scanner, collector)
- Remove prepare:tsc from risk-engine package.json (caused npm ci to run tsc before @khalifa/integrations was built) - Update build:lambdas to build integrations first - Update jest.setup.js to build integrations before risk-engine - Update CI workflow: add integrations/dspm-scanner to cache paths, format/lint/typecheck/build steps, and build integrations before risk-engine in typecheck/build/test jobs
The old prepare:tsc produced dist/ during npm ci, which api-service's tsc --noEmit relied on. Now we explicitly build integrations + risk-engine (with output) before type-checking api-service.
Collaborator
|
@therandomsecurityguy I wanted to ask you about the direction for this. Would be good to discuss what a final state of this tool would look like. |
Shasheen8
approved these changes
Jul 9, 2026
Collaborator
|
@Anusha-RG can we get this data into the dashboard too? But we need to first plug it into prod |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the gap analysis by addressing three of the highest-priority findings from the Wiz-parity review: the dead
autoTicketConfig, the stale-issue lifecycle bug, and the absence of automated data discovery (DSPM).Phase 1.1 — Stale-issue fix + posture trends
runner.tsexisting-issue branch only added toactiveIssueIdswithout refreshing fields — issues were frozen at first creation. NowrefreshExistingIssuere-derivesriskScore,severity,pathSummary, andmetadata.scoringFactorson every re-match, guarded by#status <> :resolvedso resolved issues aren't clobbered.PostureTrendStore(packages/risk-engine/src/posture-trend-store.ts) writes daily snapshots to DynamoDBPostureTrends(metrics:openIssuesBySeverity,publicBuckets,crossAccountTrusts,usersWithoutMfa).GET /trends/:metric?days=90returns the historical series.Phase 1.2 — Integrations core (SNS + Slack)
@khalifa/integrationspackage with pluggableIssueActionSinkinterface — the previously deadautoTicketConfigis now wired to live sinks.ISSUES_TOPIC_ARN(drives email/Lambda/SQS fan-out) with severity/rule/issueId message attributes.SLACK_MIN_SEVERITY(defaulthigh).IssueIntegrationsOrchestratorloads sinks from comma-separatedISSUE_SINKSenv var; dedupes names; ignores unknown sinks. Best-effort emit — sink errors never fail the rule run.Issue.externalRefsfield added to types (risk-engine + api-service), persisted viaupdateExternalRefs(dedup bysystem+id).GET /integrations/status(Viewer+),POST /issues/:id/suppress(Analyst+),POST /issues/:id/reopen(Analyst+).khalifa-issues, risk-engine role grantedsns:Publish+PostureTrendsTablewrite.ISSUES_TOPIC_ARN,ISSUE_SINKS,SLACK_WEBHOOK_URL,SLACK_MIN_SEVERITY,UI_BASE_URL,POSTURE_TRENDS_TABLE.Phase 2.2 — DSPM data discovery
dspm-scannerLambda — agentless S3 sampler with pluggable classifiers.regex-classifier.ts) detects: AWS access keys (AKIA…), AWS secret keys, GCP service-account JSON, private keys (-----BEGIN … PRIVATE KEY-----), JWTs, credit cards (Luhn-validated), emails, phone, SSN, high-entropy secrets (Shannon entropy ≥ 4.5).MACIE_ENABLED=true) enriches with managed PII findings viaListFindings/GetFindings.promoteClassification()maps findings tosecret/restricted/internaltiers with confidence scores.DataClassificationFindingvertex +CLASSIFIESedge toS3Bucket/RdsInstance; new propdata_class_source: 'tag'|'scanner'|'macie'.RULE-011(public datastore with PII),RULE-012(secret committed in S3 object).DspmScannerFn(15m timeout, 2GB mem), EventBridge daily at 03:00 UTC, S3 read IAM grants;DSPM_SCAN_MODE=off|tagged-only|all(defaulttagged-onlyfor cost control).piiTypes,secretCount,confidence).Test plan
npm run build --workspaces— all 9 workspaces compile cleancdkworkspacetsc)npx jest— 121 tests passing across 12 suites (risk-engine, integrations, api-service, dspm-scanner, collector)runner.test.tsverifies re-match updates existing issue fields (not frozen)runner.test.tsverifiesemitToIntegrationsskips suppressed issues and disabledautoTicketConfigorchestrator.test.tsverifies sink loading, dedup, and unknown-sink handlingclassifier.test.tsverifies regex patterns (AWS keys, private keys, JWT, Luhn credit cards, SSN, GCP SA, high-entropy) andpromoteClassificationtiersrules.test.tsupdated to expect 12 rules (11 enabled — RULE-003 still disabled)Files changed
37 files, +2,180 / -302 lines.
Not in this PR (Phase 2.1 — designed, not built)
Jira sink, Security Hub ASFF export, and SSM Automation auto-remediation actions. The
IssueActionSinkinterface andRemediationActiontype inpackages/integrations/src/types.tsare ready to accept them as a follow-up.