Migrate SecurityScorecard Cybersecurity Ratings solution to CCF (multi-instance + Azure Function parity) - #14757
Migrate SecurityScorecard Cybersecurity Ratings solution to CCF (multi-instance + Azure Function parity)#14757sigmabaryon wants to merge 9 commits into
Conversation
…card CCF connectors
Convert the Ratings, Factor, and Issue CCF connectors to multi-instance
(DataConnectorsGrid + ContextPane) with one independently-managed connection
per portfolio, scoped server-side via uniqueString pollers, and close the
remaining feature gaps versus the legacy Azure Function connectors:
- Ratings: nested /companies/{domain}/history/score for real dated history
(replaces the now() snapshot), with real day-over-day deltas and backfill.
- Optional own-company "My Scorecard" ingestion via a condition-gated poller
per connector (optional Domain field).
- Inject company domain and industry into Factor/Issue leaf events via
addOnAttributes; drop the cross-connector RatingsHistory parser lookup.
- Issue parser: dedup by (id, portfolio_id); humanize issueName.
- Ratings/Factor parsers: key day-over-day partitioning on portfolio_id.
- Disable logResponseContent; remove stale azuredeploy poller templates.
- Repackage solution at 3.0.0.
…rence
The CCF deployment path substitutes the literal text parameters('workspace')
with the workspace name, so the reference must be wrapped in single quotes to
produce a valid ARM string literal. Without them the expression resolved to
concat(ssc-ccf-wkspc-01, ...) -- a bare token -- and deployment failed with
InvalidTemplate ("the string character 'c' at position '11' is not expected").
Matches the form used by the merged ElasticAgent CCF connector. Applies to all
six pollers (portfolio + own-domain across Ratings, Factor, and Issue).
Repackaged 3.0.0.
The Vendor Scores panels exclude the selected Domain by design
(subject_s != '{Domain}'), because {Domain} denotes your own company rather
than a filter -- vendors are everyone except you. The CCF migration repointed
the picker at all companies (the legacy "NA" own-domain marker was never
produced by CCF), so selecting any entry removed it from the results.
Source the picker from own-company rows only -- "NA" from the legacy Function
connector and "My Scorecard" from the new CCF own-domain poller -- and make it
optional so the vendor pages still render when no own-domain is configured.
Repackaged 3.0.0.
…or titles The V3 packaging tool appends " (using Azure Functions)" to Function App connector titles, guarding on the plural string "using Azure Functions". The deprecation titles used the singular "(using Azure Function)", so the guard missed and the suffix was appended a second time, rendering as "... (using Azure Function) (using Azure Functions)". Drop the suffix from the source titles and let the packaging tool add it. Repackaged 3.0.0.
…dedup
- Domain textbox declared no validations block, so the packaging tool fell
through to its default and emitted the parameter as
{defaultValue: "Domain", minLength: 1}. A user who left the field blank --
as its own label instructs -- submitted "" and failed minLength, taking down
the entire connection deployment including the portfolio poller. Adding
validations.required:false makes the generated parameter defaultValue ""
with no minLength, per CCF_README.
- queryWindowInMin 10080 -> 1440 on all six pollers. SecurityScorecard was the
only solution in the repository above 1440 (70 others use 1440); the
underlying data is daily, so a 7-day window meant either weekly polling or
~7x redundant API volume against rateLimitQPS 1.
- Widen the Issue parser dedup key from (id, portfolio_id) to
(id, portfolio_id, domain, issue_date). The narrower key collapsed
active->resolved state transitions -- breaking the workbook's Active/Resolved
sums -- and could collide across companies if event ids are not globally
unique. The workbook's own dedup expressions all include subject_s.
- factor_score: drop the tolong() wrapper, which floored fractional factor
scores.
Repackaged 3.0.0.
|
@microsoft-github-policy-service agree company="Leen" |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Migrates the SecurityScorecard Cybersecurity Ratings solution from legacy Azure Function App connectors to Codeless Connector Framework (CCF) connectors with multi-instance support, and updates parsers/workbook for backward-compatible querying.
Changes:
- Added new CCF connector bundles (tables, DCRs, polling configs, connector definitions) plus “My Scorecard” optional ingestion.
- Added/updated KQL parsers to union legacy
*_CLwith new*History_CLtables and updated workbook queries accordingly. - Updated solution packaging metadata (solution data file, UI definition, workbook metadata) and marked legacy connectors as deprecated.
Reviewed changes
Copilot reviewed 25 out of 28 changed files in this pull request and generated 32 comments.
Show a summary per file
| File | Description |
|---|---|
| Workbooks/WorkbooksMetadata.json | Updates workbook dependencies to include new CCF tables/connectors. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Workbooks/SecurityScorecardWorkbook.json | Updates time ranges/parameters and migrates workbook queries to parser-based tables. |
| Solutions/SecurityScorecard Cybersecurity Ratings/SolutionMetadata.json | Adjusts solution identifiers/categories metadata. |
| Solutions/SecurityScorecard Cybersecurity Ratings/ReleaseNotes.md | Adds release notes for the 3.0.0 migration. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Parsers/SecurityScorecardRatings.yaml | Adds Ratings parser that unions legacy and CCF history with deltas. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Parsers/SecurityScorecardIssue.yaml | Adds Issues parser that unions legacy and CCF history. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Parsers/SecurityScorecardFactor.yaml | Adds Factors parser that unions legacy and CCF history plus metadata lookup. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Package/testParameters.json | Adds ARM test parameters for packaging/validation. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Package/createUiDefinition.json | Updates installation UX copy and lists new CCF connectors/parsers. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data/Solution_SecurityScorecard.json | Registers new CCF connectors and parsers; updates solution version to 3.0.0. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardRatings_ccp/SecurityScorecardRatings_tables.json | Adds new SecurityScorecardRatingsHistory_CL table schema. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardRatings_ccp/SecurityScorecardRatings_PollingConfig.json | Adds CCF pollers for portfolio + optional “My Scorecard” ratings ingestion. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardRatings_ccp/SecurityScorecardRatings_DataConnectorDefinition.json | Adds customizable CCF connector definition for Ratings. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardRatings_ccp/SecurityScorecardRatings_DCR.json | Adds DCR stream/transform for ratings history ingestion. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardRatings/SecurityScorecardRatings_API_FunctionApp.json | Marks legacy Ratings Function App connector as deprecated. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardIssue_ccp/SecurityScorecardIssue_tables.json | Adds new SecurityScorecardIssuesHistory_CL table schema. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardIssue_ccp/SecurityScorecardIssue_PollingConfig.json | Adds CCF pollers for portfolio + optional “My Scorecard” issues ingestion. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardIssue_ccp/SecurityScorecardIssue_DataConnectorDefinition.json | Adds customizable CCF connector definition for Issues. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardIssue_ccp/SecurityScorecardIssue_DCR.json | Adds DCR stream/transform for issues history ingestion (incl. pre-filter). |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardIssue/SecurityScorecardIssue_API_FunctionApp.json | Marks legacy Issues Function App connector as deprecated. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardFactor_ccp/SecurityScorecardFactor_tables.json | Adds new SecurityScorecardFactorHistory_CL table schema. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardFactor_ccp/SecurityScorecardFactor_PollingConfig.json | Adds CCF pollers for portfolio + optional “My Scorecard” factor ingestion. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardFactor_ccp/SecurityScorecardFactor_DataConnectorDefinition.json | Adds customizable CCF connector definition for Factors. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardFactor_ccp/SecurityScorecardFactor_DCR.json | Adds DCR stream/transform for factor history ingestion. |
| Solutions/SecurityScorecard Cybersecurity Ratings/Data Connectors/SecurityScorecardFactor/SecurityScorecardFactor_API_FunctionApp.json | Marks legacy Factors Function App connector as deprecated. |
Register the three CCF history tables with the KQL validator. The solution parsers reference SecurityScorecardRatingsHistory_CL, SecurityScorecardFactorHistory_CL and SecurityScorecardIssuesHistory_CL, which have no schema under KqlvalidationsTests/CustomTables, so Validate_SolutionParsersFunctions_HaveValidKql fails all three with "does not refer to any known table, tabular variable or function". Schemas mirror each CCF bundle's *_tables.json. Also fix the IssueType picker projecting "lable" instead of "label", so the dropdown renders the humanized factor names rather than falling back to the raw factor keys. Package regenerated to carry the workbook change; solution version stays at 3.0.0.
|
Hi @sigmabaryon Kindly retain the existing ZIP file and avoid deleting it during the update and review all Copilot comments and mark them as resolved, as appropriate and update release notes with latest changes.
Thanks! |
Address review feedback from @v-maheshbh: - Restore Package/2.0.0.zip, which was removed when 3.0.0 was generated. Prior version archives are retained across the repo (BitSight keeps seven, Cloudflare seven, ElasticAgent two), so the existing zip stays alongside the new one. - Add the 2.0.0 row to ReleaseNotes.md so the retained archive has a matching entry, and refresh the 3.0.0 date to the current publish date.
|
Hi @v-maheshbh — thanks for the review. All three points are addressed
|

Change(s)
Migrate the SecurityScorecard Cybersecurity Ratings solution from the Python Function App data connectors to the Codeless Connector Framework (CCF), with multi-instance support and feature parity with the legacy Azure Function connectors. Solution stays at version 3.0.0 (pre-publication rework).
Data connectors (Ratings, Factor, Issue) — new CCF
_ccp/bundlesDataConnectorsGrid+ContextPane): customers add one independently-managed connection per SecurityScorecard portfolio, listed/deleted independently. Each connection is scoped server-side to/portfolios/{PortfolioId}/companies, with per-connection ARM resource names viauniqueString(parameters('PortfolioId'))so instances coexist in one workspace./companies/{domain}/history/score,/history/factors/score,/history/events) and map the APIdatetoscore_date/TimeGenerated(nonow()snapshotting).Domainfield drives a second, condition-gated flat poller per connector that ingests your own company's history, taggedportfolio_name = "My Scorecard".domainandindustryare carried into the nested leaf events viaaddOnAttributes(projected from the portfolio-companies listing), so Factor/Issue no longer depend on a cross-connector lookup for enrichment.breachissues filtered pre-ingest;logResponseContentdisabled;queryWindowInMinset to 1440 (daily).Parsers (
SecurityScorecardRatings/Factor/Issue.yaml)*_CLtables with a CCF view over the new*History_CLtables, preserving backward compatibility for existing data.prev()partitioned byportfolio_id; Factor exposes per-factor metadata via a datatable; Issue dedups the rolling poll window by(id, portfolio_id, domain, issue_date)and humanizesissueName_s.Workbook (
SecurityScorecardWorkbook.json)TimeGeneratedin place ofingestion_time(); 30-day panel window.portfolioName_s in ('NA','My Scorecard')) and is optional; the Vendor Scores panels continue to exclude the own company by design.Legacy Function App connectors
[DEPRECATED](title + description), retained for backward compatibility. The deprecated-title(using Azure Functions)suffix is now applied once by the packaging tool.Packaging / cleanup
Package/mainTemplate.json,createUiDefinition.json,3.0.0.zipregenerated by the V3 tool).azuredeploy_*_poller_connector.jsontemplates and the leftoverPackage/2.0.0.zip.concat('parameters('workspace')', ...)), matching merged CCF connectors — required for the deployment to validate.Reason for Change(s)
The Python Function App connectors depend on the deprecated HTTP Data Collector API and require an Azure Function App, storage account, and stored checkpoints to operate. Moving Ratings/Factor/Issue ingestion to native codeless pollers removes that hosting dependency, ingests on the workspace's own cloud via DCE/DCR (fixing the legacy connectors' broken Gov-cloud path), and adds multi-portfolio and own-company ingestion. The parsers preserve backward compatibility so existing
*_CLdata continues to query alongside the new CCF data.Version Updated
ReleaseNotes.mdandData/Solution_SecurityScorecard.jsonare in sync at 3.0.0.Testing Completed
SecurityScorecardRatingsHistory_CL,SecurityScorecardFactorHistory_CL,SecurityScorecardIssuesHistory_CL— withdomain,industry,portfolio_id, andportfolio_namepresent, and record counts matching the API responses. Multi-instance (one connection per portfolio) and the parser → workbook path verified end to end.Checked that the validations are passing and have addressed any issues that are present
.script/local-validation/build-and-validate.ps1against the solution: ARM-TTK (48/48), the TypeScript validators (JSON/YAML/data-connector schema/workbook/branding), Field Types, and Classic App Insights all pass. KQL/Detection/Non-ASCII are skipped locally (no .NET runtime) and run in CI.https://api.securityscorecard.io— the SecurityScorecard API base URL placeholder/instruction text (an API root that returns 404 to a browser). It is pre-existing content and not a broken documentation link.Known limitations / follow-ups
Level {…} Change(a staticseveritylabel) and theDiff Overridechange-only-ingestion toggle from the Function App are not reproduced; the shipped defaults are equivalent, and change-only can be expressed at query time (| where scoreChange_d != 0)./metadatacalls (CCF cannot make auxiliary enrichment calls); re-sync if SecurityScorecard adds or renames factors/issue types.queryWindowInMinis the cadence lever).