Implement vulnerability integration and ticketing configurations#137
Merged
alex-dembele merged 9 commits intoJul 18, 2026
Merged
Conversation
…ed creds) Add VulnIntegration (per-source scanner connector config: encrypted API credentials, base URL, live-pull schedule, inbound webhook token, auto-risk / auto-ticket toggles) and VulnTicketingConfig (tenant ITSM config) domain models, their tenant-scoped Gorm repository, and the cross-module linkage columns on the Vulnerability register (risk_id + ticket ref). Credentials are AES-256-GCM at rest and never serialised (json:"-"); only HasCredentials is exposed. Wired into AutoMigrate + migration 0033. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… returned)
Add the connector-configuration use cases (Save/List/Get/Delete integration,
Save/Get/Delete ticketing) behind a CredentialCipher seam satisfied by the
scanner's AES-256-GCM cipher, plus the Fiber handler and routes under
/vulnerabilities/integrations and /vulnerabilities/ticketing (guarded by
vulnerabilities:{read,update,delete}). Credentials are write-only (json:"-"),
preserved on update when not re-supplied, and a webhook token is minted on demand.
Tests: save success/unsupported-source/preserve-creds, cross-tenant NotFound,
ticketing requires-provider/success.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scanners can now push findings automatically to
POST /api/v1/vulnerabilities/webhook/:source, authenticated by the integration's
opaque webhook token (query ?token=, X-Webhook-Token, or Bearer) — no user JWT.
Mounted on `app` before the /api/v1 JWT gate (same pattern as scanner agents);
the token carries the tenant identity, the :source segment is cross-checked, and
the payload parser accepts a bare array, a {findings|results|data|vulnerabilities|
items} wrapper, or a single object. Unknown/disabled tokens get a uniform 401.
Test: parseWebhookFindings across shapes + malformed input.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add internal/vulnscan/livepull: a per-source Puller registry that makes REAL authenticated HTTP calls and returns findings in each tool's native shape, which then flow through the existing normalisers → prioritisation → upsert. Real pullers (httptest-proven mechanisms): Microsoft Defender for Endpoint (OAuth2 client-credentials → /api/vulnerabilities), CrowdStrike Falcon Spotlight (OAuth2 → combined/vulnerabilities), Tenable Nessus/Tenable.io (X-ApiKeys → workbenches), Qualys VMDR (Basic auth → XML detection list, parsed), Microsoft Defender for Cloud (OAuth2 → ARM subAssessments). Honest seams for OpenVAS (GMP, not REST) and AWS Inspector (SDK path) — they report why + point to webhook/ import, never fabricating data (same contract as the scanner cloud collectors). TriggerLivePullUseCase decrypts creds, polls via an injectable LivePuller seam, ingests, and records ok/error + count on the integration row; exposed at POST /vulnerabilities/integrations/:id/pull. LivePullScheduler polls due integrations (schedule_minutes) behind VULN_LIVEPULL_ENABLED. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…TI feed IngestUseCase gains an optional CTIEnricher seam (WithCTIEnricher): every ingested finding with a CVE is cross-referenced against cti_vulnerabilities (NVD + CISA-KEV sync) BEFORE prioritisation. KEV is OR-ed in (never downgraded) and implies exploited-in-the-wild; CVSS/severity backfill only gaps. So a scanner finding that only knew a modest CVSS is correctly floored to P1 once the CTI feed reveals it is known-exploited. EPSS stays sourced from the finding (the current CTI feed has no EPSS; a future feed lights it up with no caller change). Wired in main.go via a CTIRepoEnricher over the shared CTI repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
IngestUseCase gains an optional RiskProposer seam (WithRiskProposer) triggered, opt-in per integration (IngestInput.AutoCreateRisk, propagated from the webhook, live-pull and manual-import paths), when a finding is P1 or CISA-KEV AND attributed to an asset. The created risk is linked back onto the vulnerability row (risk_id). The infrastructure impl (internal/infrastructure/vulnrisk) mirrors the CTI CVE→risk path: Source=scan_auto, SourceCVEID set, probability/impact on the Score Engine scales, idempotent by (tenant, asset, cve|name) so re-scans never duplicate. Tests: KEV-on-asset creates+links, disabled/no-asset/low-priority all skip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add pkg/ticketing: a domain-free provider package with REAL REST clients for Jira Cloud (POST /rest/api/2/issue, Basic email+token → SEC-42 + /browse URL) and ServiceNow (POST /api/now/table/incident, Basic auth → INC number + nav URL); absent/wrong creds surface the tool's real error, never a fabricated ticket (httptest-proven, incl. the 401 case + SN priority map). Application: ConfigTicketOpener composes the tenant ITSM config + provider and renders a vulnerability into a ticket (summary/description/priority). Wired into ingest via WithTicketOpener (auto-open for P1/KEV, opt-in per integration AutoCreateTicket, propagated through webhook/live-pull/manual) and exposed manually at POST /vulnerabilities/:id/ticket (CreateTicketUseCase — 404 unknown, 409 already-ticketed, 400 ITSM-not-configured). Ticket ref linked onto the row. Tests: auto-open on KEV, skip when disabled, manual success/not-configured/ already-ticketed/not-found. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…webhooks) Replace the read-only ConnectorsPanel with a full config screen (IntegrationsPanel): per-source credential forms (write-only — existing secrets show as configured and are preserved unless re-typed), base URL, inbound webhook URL with copy + regenerate, live-pull toggle + schedule + Pull now, and the auto-create-risk / auto-create-ticket toggles. A Ticketing tab configures Jira/ServiceNow (provider, instance URL, project/table, credentials). New typed service + React Query hooks (zero any). The vulnerability drawer now shows the opened ITSM ticket link (or an Open-a-ticket button) and flags a linked auto-created risk. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… 6.5) Document the integration config screen (encrypted creds + inbound webhooks), real REST live-pull (Defender/CrowdStrike/Nessus/Qualys/Azure + honest OpenVAS/ AWS seams), CTI KEV/CVSS enrichment on ingest, auto-create-risk from P1/KEV, and Jira/ServiceNow auto-ticketing — with the live-proof (creds never returned, webhook 202/401/400, real Qualys 401 recorded, encrypted-at-rest, no fake ticket).
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.
No description provided.