Proto commits in mondoohq/cnquery

These commits are when the Protocol Buffers files have changed: (only the last 100 relevant commits are shown)

Commit:7642e1d
Author:Tim Smith

⭐ os: report whether the OS vendor provides each package, and where third-party software came from Implements ADR 049. `package.osProvided` is true when the operating system vendor provides a package and false for third-party software; it is null only when nothing on the system answers. `package.source` says how the package arrived (os, vendor-repository, app-store, homebrew, installer, direct, snap, flatpak, chocolatey, unknown), from which repository or store, and the repository's address without credentials. The rule is the operating system's own signing keys, read from the files of an explicit, per-distribution list of key packages: - rpm: the package's signature key (RSAHEADER/DSAHEADER/SIGPGP/SIGGPG, v3 packets included for SUSE) against the keys the distribution's key package installs; the repository from dnf4/dnf5 history, zypper's log or yumdb. - dpkg: the installed version matched exactly against the apt indexes, whose release file must be signed by the archive keyring. A name in no index is a local install only when every enabled component has an index. - macOS: Apple's OS signing identity or the sealed /System volume (Safari's cryptex included), then App Store, Homebrew cask link, installer receipt, else direct. - Windows: AppX system components, packages provisioned in the image and Microsoft frameworks are the OS's; inbox apps are Store-signed, so the signature kind alone cannot decide. Edge and WebView2 count when Edge Update records Windows as their source. Sources resolve lazily, once per package manager, so a plain inventory does no new work. Over SSH the indexes are filtered and the histories queried on the host, and small files are fetched in one batch. The SBOM carries both (os_provided, PackageSource) and the generator merges them from a separate query, so an older provider fails only that query. ADR 049 is amended with what the implementation found. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Commit:970002a
Author:Dominik Richter
Committer:GitHub

✨ ADR45 Phase 3 (#11014)

The documentation is generated from this commit.

Commit:cca4c34
Author:Dominik Richter
Committer:Dominik Richter

✨ ADR45 Phase 3

The documentation is generated from this commit.

Commit:4d30420
Author:Dominik Richter
Committer:GitHub

🌟 ADR-046 Structured Provider Errors (#10973) * 🌟 ADR-046 Structured Provider Errors * ✨ add error structure * ✨ implement phase 1 of error kinds * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:099c0f5
Author:Tim Smith
Committer:Tim Smith

πŸ› honor a requested asset name after connecting A name passed with --asset-name, or written as a `name:` in an inventory file, was thrown away by the time the scan reported. Connecting replaces the root asset with the provider's connection asset, and a provider names that asset in its detect step after whatever it connected to. Several providers do so unconditionally rather than only filling in a name that is still empty, so the caller's name lost. v12 papered over this at the end of DiscoverAssets, re-applying the name when discovery produced exactly one asset; that block did not survive the move to the AssetExplorer, and nothing replaced it. The name alone cannot say who asked for it. Around seventeen providers set Asset.Name in their own ParseCLI before any user input is involved -- the os provider names a `docker <id>` asset after the raw container id, auth0 names its asset "Auth0" -- and improve it in detect once connected. Restoring any name that was present before connecting would hand those placeholders the win: mql discover docker 04be48ed3018 restore-any-name: "04be48ed3018" ParseCLI's raw container id this change: "vj-name-test" what detect resolved So the caller says which it is. inventory.Asset grows name_override, set by cnspec's --asset-name and by a `name:` in an inventory file. Discovery captures a marked name before connecting and puts it back afterwards, on root assets only; assets found underneath a root keep the name their discovery gave them. No marker, no restore, so an older cnspec against a newer mql keeps today's behavior rather than mis-naming assets. The request also has to reach the fan-out providers, where it was still a no-op. The aws detect step sets a platform but never a platform ID, and a node without one is dropped before scanning, so renaming it changes nothing a user sees. The request now travels to the single asset below such a node, which is v12's `len(Assets) == 1` rule asked one level at a time. A node that fans out to many children is left alone, so nothing in a 409-asset scan gets renamed. Loaders that do not go through InventoryFromYAML need the marker too. Ansible does: a host key is the operator's name for that host, and it stops being the connection target the moment ansible_host is set, so `instance1` with `ansible_host: 104.154.55.51` names the asset instance1. Unmarked, the os provider's cloud detect overwrites it with the instance's cloud name. Domainlist does not: that file holds targets, one per line, and the name is a verbatim copy of the line that built the connection, so marking `example.com:443` would suppress the normalized `example.com` the network provider computes after connecting. A comment records the decision and the existing test asserts the asset stays unmarked. The marking loop lives on Inventory.MarkRequestedNames so a loader opts in with one call. The root path also guards createRuntimeForAsset returning (nil, nil) on a duplicate connection, which Connect() already did and the root nil-dereferenced. Adds terraform detector tests covering that plan, state and HCL connections are each named after the platform that was selected for them. Verified against a running container, an aws account, and terraform plan/state/ HCL, with cnspec built against this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:ae48e73
Author:Dominik Richter
Committer:GitHub

🌟 IaC provider (#10939) * 🌟 IaC provider Simplify your IaC handling with this one simple provider! * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * πŸ› add missing testdata * ✨ mark as experimental --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:f87aec4
Author:Dominik Richter
Committer:Dominik Richter

🌟 IaC provider Simplify your IaC handling with this one simple provider!

Commit:a55c991
Author:Dominik Richter
Committer:GitHub

🌟 Cross-Asset traversal (#10687) * 🌟 Cross-Asset traversal ADR-031, Phase 8, implemented!! * ✨ sub-runtime timeouts * ✨ docker cross-asset call * ✨ runtime for asset wrapper * ✨ asset root membership * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:7b701f9
Author:Dominik Richter
Committer:GitHub

⭐ Deprecation notices + replacement info (#10679) ``` $ mql run local -c "os.hostname" deprecated: os.hostname has migrated to hostname ``` ``` $ mql run local -c "os { hostname machineid }" deprecated: os.hostname has migrated to hostname deprecated: os.machineid has migrated to machineid ``` ``` $ mql run local -c "os" deprecated: os has migrated to _ ```

Commit:a681033
Author:Dominik Richter
Committer:GitHub

✨ root narrowing (ADR-031, rooted resource) (#10677) * ✨ root narrowing (ADR-031, rooted resource) * πŸ‡ root lookup index Over 10 member reads: 34Β΅s β†’ 4.9Β΅s at 800 resources, 490Β΅s β†’ 51Β΅s at 8000 * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:1cfb4e7
Author:Dominik Richter
Committer:Dominik Richter

✨ root narrowing (ADR-031, rooted resource)

Commit:575a6e0
Author:Dominik Richter
Committer:GitHub

🌟 ADR-031 Typed Asset Roots (#10675) * 🌟 ADR-031 Typed Asset Roots * ✨ set asset root from connection i.e. instead of os.any we use os.linux when i run locally on my machine * πŸ“ƒ explain v13, v14, and v15+ modes (with assetRoot) * ✨ bare root member resolution * ✨ @global + unrooted warnings * ✨ MONDOO_FEATURES=RootedNamespace * πŸ› rooted vs unrooted for normal resources (_.sshd / sshd) * πŸ› simplify labels for rooted resources * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:15fe5ea
Author:Tim Smith
Committer:Tim Smith

πŸ› mark a requested asset name instead of inferring one from the field Review found the previous commit's premise wrong. It restored any name that was present on the inventory asset before connecting, on the theory that a name there was put there by the caller. Seventeen providers set Asset.Name in their own ParseCLI before any user input is involved, and improve it in detect once connected, so that restore handed the placeholder the win: mql discover docker 04be48ed3018 before this commit: "04be48ed3018" ParseCLI's raw container id, restored after: "vj-name-test" what detect resolved A requested name and a provider default are the same string in the same field, so the caller has to say which it is. inventory.Asset grows name_override, set by cnspec's --asset-name and by a `name:` in an inventory file. No marker, no restore, so an older cnspec against a newer mql keeps today's behavior rather than mis-naming assets. Also from review: --asset-name was still a no-op on the fan-out providers. The aws detect step sets a platform but never a platform ID, and a node without one is dropped before scanning, so renaming it changes nothing a user sees. The request now travels to the single asset below it that can be scanned, which is v12's `len(Assets) == 1` rule asked one level at a time. A node that fans out to many children is left alone, so nothing in a 409-asset scan gets renamed. And the root path now guards createRuntimeForAsset returning (nil, nil) on a duplicate connection, which Connect() already did and the root nil-dereferenced. Verified against a running container, an aws account, and terraform plan/state/ HCL, with cnspec built against this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:c064379
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: enforce US English and fix the typos the dictionary missed `typos` has been passing on every PR, but three things were going unchecked. **No locale was set.** Without `locale = "en-us"` the checker accepts British spellings, so they never failed CI. Turning it on surfaced 236 findings across 128 files, 40 of them in `.lr` doc comments, which is the prose that gets parsed into the public resource docs. 177 are fixed here: `behaviour`, `labelling`, `recognised`, `unrecognised`, `marshalled`, `realised`, `modelled`, `favour`, `honoured` and friends, in comments, markdown, test names and test messages. The other 59 are spelled the British way by contract, not by accident, so they are exempted rather than renamed: - upstream API and SDK identifiers: `AnalyseAsset` (mvd), `ContentSynchronisation` (Artifactory), `FixVersionDependant` (Xray), `SynchroniseConsumerGroupOffsets` (MSK), `AllowQueueing` (Vertex AI), `GetBehaviourOk` (STACKIT), `FixKustomizationPreMarshalling` (kustomize) - the shipped MQL fields derived from them, where a rename would be a breaking schema change - the proper nouns MITRE, Spectre and EndeavourOS, which the en-us dictionary wants to turn into `miter`, `specter` and `endeavor` These go in `extend-identifiers` where the exact token is what needs exempting, so the same word stays flagged in prose. Only the MSK local variable `synchronise` and comments around these fields were touched. **Five typos the correction dictionary has no entry for**, found by diffing comment prose against a word list and keeping near-misses of words the repo already uses: - `cound not determine orgName ...` in an okta error string returned to users - `serverVASetings` in the azure cloud defender lister - `try to collecta instance metadata` in the awsebs id detector - `report jever result it has` in the llx block executor - `counterparty asset` in inventory.proto, where every other use in the tree says `counterpart` **Two dead baselines.** `compleated` and `deliminated` matched nothing anywhere in the tree, including generated files and testdata. `cound` and `setings` drop out too now that their single occurrences are fixed. Verified: `typos` is clean with the new config, `go build ./...` passes in the root module and all 20 touched provider modules, and the tests in every package with a changed test file pass. Schema regeneration produces no diff, since `.lr` doc comments are not embedded in `.lr.go`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:5cadf1c
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: convert the British spellings from the third rebase main has moved 106 commits since the last pass, and the new comments and test names brought back the usual set: behaviour, recognise, favour, licence, labelling, marshalling, judgement, and friends. Converted with `typos --write-changes`, which is now clean. Every change is a comment, a test case name, an assertion message, or markdown prose. No identifier, schema field, or wire contract is touched. Also carries the modprobe comment fix over to kernel_test.go: #10536 deleted kernel_internal_test.go and moved its tests there, taking the typo along. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:66dfbeb
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: revert a non-typo word swap and finish the en-us pass Two review follow-ups. `counterparty` -> `counterpart` in inventory.proto was not a spell-check fix. `typos` never flagged it (it flags only `licenced` in that file), and the two words differ in meaning: a counterparty is the other party to a relationship, which is exactly what an ADR 030 relationship edge names. Reverted. Reverting it also drops providers-sdk/v1/inventory/inventory.pb.go from the change set entirely, so the PR no longer touches a generated file. `parallelised` -> `parallelized` in docs/provider-scan-performance.md. The en-us locale misses this one, so it is a hand fix rather than a checker hit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:4956250
Author:Christoph Hartmann
Committer:GitHub

πŸ› sbom: read the licensing an imported document states (#10597) * πŸ› sbom: read the licensing an imported document states The Protobom decoder is an importer: it parses an SBOM somebody else produced into this model. It read the name, version and identifiers of every package and dropped everything the document said about licensing, which is information that exists nowhere else in the file. A document stating a package's declared license, a concluded one, its copyright and its supplier came out carrying none of them. protobom keeps the same distinction the model does, so the mapping is direct rather than a flattening: `licenses` is what a package says about itself and `license_concluded` is what the document's producer determined, and they become DECLARED and CONCLUDED entries rather than one merged list. `copyright` and the first named supplier come across with them. The legacy scalar keeps being written, as every other producer here does, and takes the first declared entry -- the convention the field's own documentation asks producers to follow -- falling back to the concluded value when a document declares none. A scalar left empty while a license was in fact stated is the failure that fallback exists to prevent. Adds ConcludedLicense alongside DeclaredLicense, which the package did not have. It shares the value handling, because which of the three mutually exclusive fields a string belongs in is a property of the string and not of how it was obtained; what differs is the acquisition, the location it was read from, and a confidence clamped into (0,1]. A score outside that range is a producer bug rather than certainty, and a consumer ranking conclusions against each other would read it as a real measurement. One behaviour is pinned that this change does not implement: NOASSERTION is SPDX for "this document does not say", it is identifier-shaped, and nothing about its spelling would stop it becoming a license named NOASSERTION. protobom drops it before it reaches the model. If a future version stopped doing that, every package in every imported document would gain a license that does not exist, so the test asserts on it rather than trusting it. Every assertion fails when the licensing read is removed, confirmed by reverting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * πŸ› sbom: keep location meaning a path, and stop the importer's output crashing Three fixes from review, one to this branch and two it made worth fixing. **license_comments is not a location.** The first commit mapped protobom's license_comments onto License.location, which the model documents as the file a license was read from. license_comments is free-form prose about how the license fields were arrived at: the fixture's own value is "concluded from LICENSE", a sentence rather than a path, and the CycloneDX renderer writes exactly such a sentence into that field elsewhere. Two producers filling one field with two kinds of value is worse than leaving it empty, which is what an importer with no path to report should do. **An imported document could not be rendered.** Asset.Platform was left nil unless the document named an operating system, and most do not. Every renderer reads it unguarded, so parsing a document and handing it to a renderer -- the obvious thing to do with an importer -- panicked on a nil dereference. Platform is initialized up front. **The metadata guard was unreachable.** doc.Metadata.Name was read one line before the check for whether doc.Metadata exists, so a document without metadata panicked on the line above its own guard. The name is read after the check now, and the check covers a nil document too. Not fixed here, and reported rather than patched: the SPDX renderer builds a Creator from Generator.Vendor, and common.Creator refuses to marshal an empty one, so any BOM whose generator carries no vendor fails to render -- an imported one included. That is a renderer bug, and fixing it means deciding what a document with no stated vendor claims to have been created by, which is not this change's call. The render test asserts CycloneDX for that reason and says why. Each fix fails its test when reverted individually. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * πŸ› sbom: let a conclusion nobody scored say so, instead of reporting certainty `ConcludedLicense` mapped a zero confidence to 1.0. The importer passes zero deliberately -- an SPDX or CycloneDX document carries no match score -- so every conclusion relayed from somebody else's document came out claiming the top of the scale, indistinguishable from one this scanner matched exactly. That is the one thing the field exists to prevent. The model documents confidence as what lets a consumer "tell a certainty from an inference rather than reading both as the same fact", and promoting an absent score collapses exactly that distinction, in the direction that overstates. The argument for 1.0 was that relaying an unscored conclusion is a statement rather than a measurement, and a statement is what 1.0 means. It holds for a *declared* license, whose 1.0 says "the package asserted this". It does not hold for a concluded one: a conclusion is a measurement by definition, so its score is a claim about how the measurement went, and there was no measurement here. A consumer ranking conclusions cannot see the difference. So zero now travels as zero: - above 1 still clamps to 1.0, a producer bug rather than extra certainty - at or below zero is no score at all, and stays zero - in (0,1] is a measurement and travels as written `double confidence` has no presence in proto3, so zero was already what an absent score decoded to. This makes the code agree with what was already on the wire, and the field's comment now documents the third reading rather than promising a range that excludes it. Both renderers already gate on `> 0 && < 1`, so a zero emits no CycloneDX property and no SPDX comment clause: the difference is between staying silent and asserting. The importer's own comment is updated to match, and `location`'s comment now says it is a path rather than prose -- the constraint the previous commit enforced, written down where the next producer will look. Pinned in two places: the constructor, and the importer reading a document that scores nothing. The second is the assertion that fails if the constructor ever goes back to promoting an absent score, which nothing else here would notice. Both confirmed to fail against the old behaviour before fixing it. Co-Authored-By: Claude <noreply@anthropic.com> * πŸ› sbom: don't emit a nameless operating system for a document that names none Rebased onto #10598, which is now on main, and testing the two together surfaced a wart this branch introduced. Initializing Asset.Platform stopped the renderers dereferencing nil, but the CycloneDX renderer emits the OS component unconditionally, so an imported document came out carrying an operating system with no name: { "bom-ref": "os:", "type": "operating-system", "name": "" } A scanned host always names a platform. A document parsed from somebody else's SBOM often does not, because most SBOMs describe an application rather than a machine, and a consumer would have to recognise that entry as junk and filter it. The component is emitted only when the asset names a platform. The new test is the seam between this branch and #10598, which were written separately: an imported conclusion carries confidence 0 because the format states no score, and both renderers report a score only when it is in (0,1), so a relayed conclusion is emitted with no score rather than as one that scored perfectly. It also pins that the conclusion still reaches the document marked `"acknowledgement": "concluded"`, and that no nameless OS component appears. Verified against the merged base rather than a local merge of the two branches. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * πŸ› sbom: stop the CycloneDX renderer dereferencing a nil platform Review catch on the line the previous commit added. Gating the OS component on `bom.Asset.Platform.Name != ""` still dereferences Platform, which is a pointer, so a BOM without one panics before it can be skipped. Not a regression: the `.Cpes` read it replaced dereferenced it the same way. What makes it worth closing rather than shrugging at is that the rest of the package already treats a nil platform as reachable. cnquery_bom.go guards `bom.Asset != nil && bom.Asset.Platform != nil` on the same field, and both other renderers handle it -- checked, not assumed: cyclonedx-json PANIC: invalid memory address or nil pointer dereference spdx-json rendered 601 bytes table rendered 4 bytes so CycloneDX was the only one that did not. Nothing in tree reaches it now that this branch initialises Platform in the importer, which is the reason it gets a test rather than only a guard: the next producer to build a Sbom by hand would otherwise find it the way this was found. The test renders a platform-less BOM through all three formats. Nil Asset is deliberately left alone. cnquery_bom.go guards that too, but this function reads bom.Asset in several other places, so a guard here would move the panic rather than close it -- a separate question from the one this fixes. Fails when the nil check is removed, confirmed by reverting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * πŸ› sbom: don't import SPDX's "no license" as a license called NONE Review asked whether the legacy scalar could pick up a raw NOASSERTION from license_concluded, since the list filters it and the scalar took the node field directly. Checking what protobom actually delivers says no -- it zeroes NOASSERTION before the importer sees it: RAW node="concluded-noassertion-only" concluded="" but the same probe found the real one. NONE is passed straight through: RAW node="concluded-none-only" concluded="NONE" PKG name="concluded-none-only" scalar="NONE" licenses=1 NONE is the other half of SPDX's absence vocabulary: the package is under no license, where NOASSERTION means the document does not know. Neither is a license, both are identifier-shaped, and nothing about their spelling stops one becoming a license named "NONE" -- reported to a consumer as a fact about the package and indistinguishable from one the document actually stated. So the review was right that a sentinel was leaking, and wrong about which one and where: it reached the list as well as the scalar, which is worse than reported. Both sentinels are filtered at the point an imported value becomes a license, which covers the declared list, the concluded entry and the scalar in one place. NOASSERTION is handled even though protobom drops it today, because which sentinels a parser filters is its decision and not a contract, and the failure is silent in either direction. The fixture gains a package stating NONE, since none of the existing ones did -- which is why this survived the round of tests that pinned NOASSERTION. Fails when the filter is removed, confirmed by reverting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

Commit:63b9726
Author:Christoph Hartmann
Committer:GitHub

✨ sbom: give Package a license model that can tell declared from concluded (#10491) * ✨ sbom: give Package a license model that can tell declared from concluded `Package.license` is one string, so a document cannot say the thing that matters most about a package's licensing: what its manifest *declares* is not always what its shipped files say. A package declaring MIT while shipping an AGPL-3.0-only license file is exactly the case a compliance document must not flatten, and the scalar has no room for both values. Producers that read the shipped text had nowhere to put it, so the renderers echoed the declared license into the concluded field and said NOASSERTION for copyright. Adds `Package.licenses` β€” a repeated `License`, each carrying spdx_id / expression / name (which one is set says what kind of value it is, because CycloneDX models the three mutually exclusively and rejects a document that confuses them), an acquisition of declared or concluded, a confidence in (0,1], and the file a concluded license was read from. Adds `copyright` and `supplier` alongside, both required by attribution output and both with a natural home in each renderer. The `license` scalar stays authoritative when `licenses` is empty, so a producer that has not adopted the list renders exactly as before β€” no flag day. CycloneDX: declared entries render as `component.licenses`, concluded ones as `component.evidence.licenses`, which is what CycloneDX evidence is for β€” they were read out of a file rather than asserted by the package. Copyright renders both as `component.copyright` and as evidence. SPDX: `PackageLicenseConcluded` is now the concluded value where one was determined rather than an echo of declared; `PackageCopyrightText` and `PackageSupplier` carry real values; LicenseRef-* identifiers from either field reach `hasExtractedLicensingInfos`, which the spec requires before they may be referenced. Tests cover the split end to end in both formats, the legacy-scalar fallback, and the NOASSERTION cases β€” the absence of exactly these tests is why the renderers shipped emitting no licenses at all. Note on regeneration: this was generated with protoc v3.21.12 rather than the v6.33.6 the committed file recorded. That was checked rather than assumed β€” regenerating the unmodified proto with the local toolchain reproduced the committed output byte for byte apart from that version comment, so the plugins (pinned via `go tool`) are what determine the output here. Co-Authored-By: Claude <noreply@anthropic.com> * 🧹 sbom: deprecate the license scalar in favour of the licenses list The list supersedes the scalar, so the scalar should say so in the one place every consumer already looks: the generated code. `[deprecated = true]` puts a `// Deprecated:` marker on both the field and its getter, so an IDE and a staticcheck-enabled build point migrating callers at `licenses` without anyone having to read the proto. This is a descriptor-only change. The field options gain deprecated=true (4 bytes of rawDesc) and nothing else moves β€” the wire format, the field number and the value are untouched, verified by a round trip through proto.Marshal/Unmarshal. Regenerated with protoc 33.6 (recorded as v6.33.6), the same toolchain the file already carried, so the diff is the deprecation and nothing else. Nothing is being removed. Every renderer still falls back to the scalar when `licenses` is empty, which is what makes this safe to land ahead of any producer adopting the list β€” the deprecation says which field new code should read, not that this one stopped working. The comment also records something the model does NOT enforce, because assuming it is how a consumer ends up with an empty license: nothing populates the scalar from `licenses`. The fallback runs one way only. A producer that adopts the list has to keep setting the scalar itself, or consumers still reading it will see nothing where a license was in fact determined. The previous wording ("the scalar stays populated with the first declared entry") stated that as a property of the model when it is a convention asked of producers, so it now says which it is. Co-Authored-By: Claude <noreply@anthropic.com> * πŸ› sbom: stop a free-form license name rendering as an invalid SPDX expression `License.name` exists to carry a value that is neither an SPDX identifier nor an expression β€” "BSD-like, see LICENSE", "see LICENSE". An SPDX license field holds a license *expression*, and that constrains what may go in it: a listed identifier, a `LicenseRef-*` the document defines, `NONE`, or `NOASSERTION`. A free-form name is none of those, and the renderer was passing it straight through. Alone that produced an unparseable field. Joined it produced something worse: "licenseDeclared": "MIT AND see LICENSE" which reads as an expression right up to the operand that is not one, so a consumer either rejects the document or silently reads a license that does not exist. The join is only reachable through the new list, so this is a defect in the field being added rather than a pre-existing one. A name now becomes the `LicenseRef-*` identifier SPDX specifies for a license that is not on its list, and the original text becomes that reference's name in `hasExtractedLicensingInfos` β€” so the reader learns what the reference means instead of receiving one the document never defines. Where nothing in a name survives sanitization there is no identifier to reference, so the entry is dropped rather than emitting a bare prefix. Two smaller fixes alongside: - Grouping parentheses are decided on the operands actually rendered, not on the input count, so an entry that carried no value no longer wraps the one that did: a lone `MIT OR Apache-2.0` was rendering as `(MIT OR Apache-2.0)`. - `extractedLicenseSet` carries the name an identifier stands for, which is what lets a synthesized reference keep its original text. `add` no longer clobbers a recorded name when it re-scans the rendered expression the reference landed in. The `license` scalar is deliberately left passing through unchanged. Producers set it to whatever their package manager reported, and a large share of OS packages report something that is not an SPDX expression, so re-encoding it here would rewrite what every existing document says about them. That is a migration to make on purpose, not as a side effect of adding a list. `TestSPDXLegacyScalarPassesThroughUnchanged` pins it so a future change is a decision. Tests fail without the fix β€” verified by reverting the encoding and watching `TestSPDXFreeFormNameBecomesLicenseRef` and `TestSPDXNameIsNotJoinedRawIntoAnExpression` go red. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>

Commit:473f4aa
Author:Christoph Hartmann
Committer:Christoph Hartmann

feat(sbom): give Package a license model that can tell declared from concluded `Package.license` is one string, so a document cannot say the thing that matters most about a package's licensing: what its manifest *declares* is not always what its shipped files say. A package declaring MIT while shipping an AGPL-3.0-only license file is exactly the case a compliance document must not flatten, and the scalar has no room for both values. Producers that read the shipped text had nowhere to put it, so the renderers echoed the declared license into the concluded field and said NOASSERTION for copyright. Adds `Package.licenses` β€” a repeated `License`, each carrying spdx_id / expression / name (which one is set says what kind of value it is, because CycloneDX models the three mutually exclusively and rejects a document that confuses them), an acquisition of declared or concluded, a confidence in (0,1], and the file a concluded license was read from. Adds `copyright` and `supplier` alongside, both required by attribution output and both with a natural home in each renderer. The `license` scalar stays authoritative when `licenses` is empty, so a producer that has not adopted the list renders exactly as before β€” no flag day. CycloneDX: declared entries render as `component.licenses`, concluded ones as `component.evidence.licenses`, which is what CycloneDX evidence is for β€” they were read out of a file rather than asserted by the package. Copyright renders both as `component.copyright` and as evidence. SPDX: `PackageLicenseConcluded` is now the concluded value where one was determined rather than an echo of declared; `PackageCopyrightText` and `PackageSupplier` carry real values; LicenseRef-* identifiers from either field reach `hasExtractedLicensingInfos`, which the spec requires before they may be referenced. Tests cover the split end to end in both formats, the legacy-scalar fallback, and the NOASSERTION cases β€” the absence of exactly these tests is why the renderers shipped emitting no licenses at all. Note on regeneration: this was generated with protoc v3.21.12 rather than the v6.33.6 the committed file recorded. That was checked rather than assumed β€” regenerating the unmodified proto with the local toolchain reproduced the committed output byte for byte apart from that version comment, so the plugins (pinned via `go tool`) are what determine the output here. Co-Authored-By: Claude <noreply@anthropic.com>

Commit:6043a86
Author:Dominik Richter
Committer:GitHub

⭐ ADR40: Cross-version MQL support (#10465) * ⭐ ADR40: Cross-version MQL support Cross-version MQL β€” schema resolution, migration lenses, and down-adaptation * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:ac4d133
Author:Tim Smith

πŸ› mark a requested asset name instead of inferring one from the field Review found the previous commit's premise wrong. It restored any name that was present on the inventory asset before connecting, on the theory that a name there was put there by the caller. Seventeen providers set Asset.Name in their own ParseCLI before any user input is involved, and improve it in detect once connected, so that restore handed the placeholder the win: mql discover docker 04be48ed3018 before this commit: "04be48ed3018" ParseCLI's raw container id, restored after: "vj-name-test" what detect resolved A requested name and a provider default are the same string in the same field, so the caller has to say which it is. inventory.Asset grows name_override, set by cnspec's --asset-name and by a `name:` in an inventory file. No marker, no restore, so an older cnspec against a newer mql keeps today's behavior rather than mis-naming assets. Also from review: --asset-name was still a no-op on the fan-out providers. The aws detect step sets a platform but never a platform ID, and a node without one is dropped before scanning, so renaming it changes nothing a user sees. The request now travels to the single asset below it that can be scanned, which is v12's `len(Assets) == 1` rule asked one level at a time. A node that fans out to many children is left alone, so nothing in a 409-asset scan gets renamed. And the root path now guards createRuntimeForAsset returning (nil, nil) on a duplicate connection, which Connect() already did and the root nil-dereferenced. Verified against a running container, an aws account, and terraform plan/state/ HCL, with cnspec built against this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:b9b060e
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: enforce US English and fix the typos the dictionary missed `typos` has been passing on every PR, but three things were going unchecked. **No locale was set.** Without `locale = "en-us"` the checker accepts British spellings, so they never failed CI. Turning it on surfaced 236 findings across 128 files, 40 of them in `.lr` doc comments, which is the prose that gets parsed into the public resource docs. 177 are fixed here: `behaviour`, `labelling`, `recognised`, `unrecognised`, `marshalled`, `realised`, `modelled`, `favour`, `honoured` and friends, in comments, markdown, test names and test messages. The other 59 are spelled the British way by contract, not by accident, so they are exempted rather than renamed: - upstream API and SDK identifiers: `AnalyseAsset` (mvd), `ContentSynchronisation` (Artifactory), `FixVersionDependant` (Xray), `SynchroniseConsumerGroupOffsets` (MSK), `AllowQueueing` (Vertex AI), `GetBehaviourOk` (STACKIT), `FixKustomizationPreMarshalling` (kustomize) - the shipped MQL fields derived from them, where a rename would be a breaking schema change - the proper nouns MITRE, Spectre and EndeavourOS, which the en-us dictionary wants to turn into `miter`, `specter` and `endeavor` These go in `extend-identifiers` where the exact token is what needs exempting, so the same word stays flagged in prose. Only the MSK local variable `synchronise` and comments around these fields were touched. **Five typos the correction dictionary has no entry for**, found by diffing comment prose against a word list and keeping near-misses of words the repo already uses: - `cound not determine orgName ...` in an okta error string returned to users - `serverVASetings` in the azure cloud defender lister - `try to collecta instance metadata` in the awsebs id detector - `report jever result it has` in the llx block executor - `counterparty asset` in inventory.proto, where every other use in the tree says `counterpart` **Two dead baselines.** `compleated` and `deliminated` matched nothing anywhere in the tree, including generated files and testdata. `cound` and `setings` drop out too now that their single occurrences are fixed. Verified: `typos` is clean with the new config, `go build ./...` passes in the root module and all 20 touched provider modules, and the tests in every package with a changed test file pass. Schema regeneration produces no diff, since `.lr` doc comments are not embedded in `.lr.go`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:807a4fe
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: revert a non-typo word swap and finish the en-us pass Two review follow-ups. `counterparty` -> `counterpart` in inventory.proto was not a spell-check fix. `typos` never flagged it (it flags only `licenced` in that file), and the two words differ in meaning: a counterparty is the other party to a relationship, which is exactly what an ADR 030 relationship edge names. Reverted. Reverting it also drops providers-sdk/v1/inventory/inventory.pb.go from the change set entirely, so the PR no longer touches a generated file. `parallelised` -> `parallelized` in docs/provider-scan-performance.md. The en-us locale misses this one, so it is a hand fix rather than a checker hit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:0161b9d
Author:Tim Smith
Committer:GitHub

πŸ›‘ inventory: remove the deprecated connection `backend` field (#9992) * πŸ›‘ inventory: remove the deprecated connection `backend` field The `backend` field and its `ProviderType` enum were replaced by the string `type` field back in v10, and every code path since has treated `backend` purely as a migration fallback. The FIXME asking for their removal has been sitting in `inventory.proto` for four majors; v14 is the window. Removed: - `enum ProviderType` and `Config.backend` from `inventory.proto`. Field number 28 is now `reserved` so a future field cannot silently inherit the old wire tag. - `v8_inventory.go` in full. It held the `ProviderID_*` constants, the `ProviderType_idvalue` lookup, `ProviderType.UnmarshalJSON` and `ConnBackendToType` β€” all of which existed only to serve `backend`, and none of which is referenced anywhere else. Its own header said the file could go in v10. - The migration fallbacks in `InventoryFromYAML` and `Runtime.providerForAsset`. - `conf.Backend = ProviderType_HOST` in the network provider, a write that nothing read. An inventory that specifies neither `type` nor `backend` previously warned and resolved to an empty connection type, which then failed further down in provider lookup with an unrelated message. It now reports "no connection `type` provided in inventory" against that connection and moves to the next one, so the multierr names the real problem. The commented-out examples in `testdata/aws_inventory.yaml` were updated to `type:` so they stop teaching a field that no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * 🧹 inventory: point the last debugtest configs at `type` The three debugtest helpers still set the removed `backend` field. They are excluded from normal builds, so nothing caught it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:f7fa2f6
Author:Tim Smith
Committer:GitHub

πŸ›‘ remove deprecated min_mondoo_version from the resource schema (#10028) * πŸ›‘ remove deprecated min_mondoo_version from the resource schema `ResourceInfo.min_mondoo_version` (field 25) and `Field.min_mondoo_version` (field 23) were marked `[deprecated = true]` and documented "remove in v14, not used anymore as of v13". Nothing in this repo or in cnspec reads or writes them outside the generated marshalling code -- `min_provider_version` carries the signal now. Both field numbers are marked `reserved` so they can never be reused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * 🟒 reserve the min_mondoo_version field name and fix protolint - reserve the field *name* in addition to the number, so neither the tag nor the identifier can be reused (review suggestion) - shorten the two reserved-field comments; protolint enforces an 80 column limit and both were 81 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:5127192
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: enforce US English and fix the typos the dictionary missed `typos` has been passing on every PR, but three things were going unchecked. **No locale was set.** Without `locale = "en-us"` the checker accepts British spellings, so they never failed CI. Turning it on surfaced 236 findings across 128 files, 40 of them in `.lr` doc comments, which is the prose that gets parsed into the public resource docs. 177 are fixed here: `behaviour`, `labelling`, `recognised`, `unrecognised`, `marshalled`, `realised`, `modelled`, `favour`, `honoured` and friends, in comments, markdown, test names and test messages. The other 59 are spelled the British way by contract, not by accident, so they are exempted rather than renamed: - upstream API and SDK identifiers: `AnalyseAsset` (mvd), `ContentSynchronisation` (Artifactory), `FixVersionDependant` (Xray), `SynchroniseConsumerGroupOffsets` (MSK), `AllowQueueing` (Vertex AI), `GetBehaviourOk` (STACKIT), `FixKustomizationPreMarshalling` (kustomize) - the shipped MQL fields derived from them, where a rename would be a breaking schema change - the proper nouns MITRE, Spectre and EndeavourOS, which the en-us dictionary wants to turn into `miter`, `specter` and `endeavor` These go in `extend-identifiers` where the exact token is what needs exempting, so the same word stays flagged in prose. Only the MSK local variable `synchronise` and comments around these fields were touched. **Five typos the correction dictionary has no entry for**, found by diffing comment prose against a word list and keeping near-misses of words the repo already uses: - `cound not determine orgName ...` in an okta error string returned to users - `serverVASetings` in the azure cloud defender lister - `try to collecta instance metadata` in the awsebs id detector - `report jever result it has` in the llx block executor - `counterparty asset` in inventory.proto, where every other use in the tree says `counterpart` **Two dead baselines.** `compleated` and `deliminated` matched nothing anywhere in the tree, including generated files and testdata. `cound` and `setings` drop out too now that their single occurrences are fixed. Verified: `typos` is clean with the new config, `go build ./...` passes in the root module and all 20 touched provider modules, and the tests in every package with a changed test file pass. Schema regeneration produces no diff, since `.lr` doc comments are not embedded in `.lr.go`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:999f5fa
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: revert a non-typo word swap and finish the en-us pass Two review follow-ups. `counterparty` -> `counterpart` in inventory.proto was not a spell-check fix. `typos` never flagged it (it flags only `licenced` in that file), and the two words differ in meaning: a counterparty is the other party to a relationship, which is exactly what an ADR 030 relationship edge names. Reverted. Reverting it also drops providers-sdk/v1/inventory/inventory.pb.go from the change set entirely, so the PR no longer touches a generated file. `parallelised` -> `parallelized` in docs/provider-scan-performance.md. The en-us locale misses this one, so it is a hand fix rather than a checker hit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:fd1ed71
Author:Dominik Richter
Committer:GitHub

⭐ strict mode (#10323) * ⭐ strict mode Adds strict mode to MQL, see ADR-043 * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:e372f1b
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: revert a non-typo word swap and finish the en-us pass Two review follow-ups. `counterparty` -> `counterpart` in inventory.proto was not a spell-check fix. `typos` never flagged it (it flags only `licenced` in that file), and the two words differ in meaning: a counterparty is the other party to a relationship, which is exactly what an ADR 030 relationship edge names. Reverted. Reverting it also drops providers-sdk/v1/inventory/inventory.pb.go from the change set entirely, so the PR no longer touches a generated file. `parallelised` -> `parallelized` in docs/provider-scan-performance.md. The en-us locale misses this one, so it is a hand fix rather than a checker hit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:f8a1448
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: enforce US English and fix the typos the dictionary missed `typos` has been passing on every PR, but three things were going unchecked. **No locale was set.** Without `locale = "en-us"` the checker accepts British spellings, so they never failed CI. Turning it on surfaced 236 findings across 128 files, 40 of them in `.lr` doc comments, which is the prose that gets parsed into the public resource docs. 177 are fixed here: `behaviour`, `labelling`, `recognised`, `unrecognised`, `marshalled`, `realised`, `modelled`, `favour`, `honoured` and friends, in comments, markdown, test names and test messages. The other 59 are spelled the British way by contract, not by accident, so they are exempted rather than renamed: - upstream API and SDK identifiers: `AnalyseAsset` (mvd), `ContentSynchronisation` (Artifactory), `FixVersionDependant` (Xray), `SynchroniseConsumerGroupOffsets` (MSK), `AllowQueueing` (Vertex AI), `GetBehaviourOk` (STACKIT), `FixKustomizationPreMarshalling` (kustomize) - the shipped MQL fields derived from them, where a rename would be a breaking schema change - the proper nouns MITRE, Spectre and EndeavourOS, which the en-us dictionary wants to turn into `miter`, `specter` and `endeavor` These go in `extend-identifiers` where the exact token is what needs exempting, so the same word stays flagged in prose. Only the MSK local variable `synchronise` and comments around these fields were touched. **Five typos the correction dictionary has no entry for**, found by diffing comment prose against a word list and keeping near-misses of words the repo already uses: - `cound not determine orgName ...` in an okta error string returned to users - `serverVASetings` in the azure cloud defender lister - `try to collecta instance metadata` in the awsebs id detector - `report jever result it has` in the llx block executor - `counterparty asset` in inventory.proto, where every other use in the tree says `counterpart` **Two dead baselines.** `compleated` and `deliminated` matched nothing anywhere in the tree, including generated files and testdata. `cound` and `setings` drop out too now that their single occurrences are fixed. Verified: `typos` is clean with the new config, `go build ./...` passes in the root module and all 20 touched provider modules, and the tests in every package with a changed test file pass. Schema regeneration produces no diff, since `.lr` doc comments are not embedded in `.lr.go`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:74c2cac
Author:Tim Smith
Committer:Tim Smith

🧹 spell check: enforce US English and fix the typos the dictionary missed `typos` has been passing on every PR, but three things were going unchecked. **No locale was set.** Without `locale = "en-us"` the checker accepts British spellings, so they never failed CI. Turning it on surfaced 236 findings across 128 files, 40 of them in `.lr` doc comments, which is the prose that gets parsed into the public resource docs. 177 are fixed here: `behaviour`, `labelling`, `recognised`, `unrecognised`, `marshalled`, `realised`, `modelled`, `favour`, `honoured` and friends, in comments, markdown, test names and test messages. The other 59 are spelled the British way by contract, not by accident, so they are exempted rather than renamed: - upstream API and SDK identifiers: `AnalyseAsset` (mvd), `ContentSynchronisation` (Artifactory), `FixVersionDependant` (Xray), `SynchroniseConsumerGroupOffsets` (MSK), `AllowQueueing` (Vertex AI), `GetBehaviourOk` (STACKIT), `FixKustomizationPreMarshalling` (kustomize) - the shipped MQL fields derived from them, where a rename would be a breaking schema change - the proper nouns MITRE, Spectre and EndeavourOS, which the en-us dictionary wants to turn into `miter`, `specter` and `endeavor` These go in `extend-identifiers` where the exact token is what needs exempting, so the same word stays flagged in prose. Only the MSK local variable `synchronise` and comments around these fields were touched. **Five typos the correction dictionary has no entry for**, found by diffing comment prose against a word list and keeping near-misses of words the repo already uses: - `cound not determine orgName ...` in an okta error string returned to users - `serverVASetings` in the azure cloud defender lister - `try to collecta instance metadata` in the awsebs id detector - `report jever result it has` in the llx block executor - `counterparty asset` in inventory.proto, where every other use in the tree says `counterpart` **Two dead baselines.** `compleated` and `deliminated` matched nothing anywhere in the tree, including generated files and testdata. `cound` and `setings` drop out too now that their single occurrences are fixed. Verified: `typos` is clean with the new config, `go build ./...` passes in the root module and all 20 touched provider modules, and the tests in every package with a changed test file pass. Schema regeneration produces no diff, since `.lr` doc comments are not embedded in `.lr.go`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:ac6a376
Author:Tim Smith
Committer:Tim Smith

πŸ›‘ inventory: remove the deprecated connection `backend` field The `backend` field and its `ProviderType` enum were replaced by the string `type` field back in v10, and every code path since has treated `backend` purely as a migration fallback. The FIXME asking for their removal has been sitting in `inventory.proto` for four majors; v14 is the window. Removed: - `enum ProviderType` and `Config.backend` from `inventory.proto`. Field number 28 is now `reserved` so a future field cannot silently inherit the old wire tag. - `v8_inventory.go` in full. It held the `ProviderID_*` constants, the `ProviderType_idvalue` lookup, `ProviderType.UnmarshalJSON` and `ConnBackendToType` β€” all of which existed only to serve `backend`, and none of which is referenced anywhere else. Its own header said the file could go in v10. - The migration fallbacks in `InventoryFromYAML` and `Runtime.providerForAsset`. - `conf.Backend = ProviderType_HOST` in the network provider, a write that nothing read. An inventory that specifies neither `type` nor `backend` previously warned and resolved to an empty connection type, which then failed further down in provider lookup with an unrelated message. It now reports "no connection `type` provided in inventory" against that connection and moves to the next one, so the multierr names the real problem. The commented-out examples in `testdata/aws_inventory.yaml` were updated to `type:` so they stop teaching a field that no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:115a1a8
Author:Tim Smith
Committer:Tim Smith

🟒 reserve the min_mondoo_version field name and fix protolint - reserve the field *name* in addition to the number, so neither the tag nor the identifier can be reused (review suggestion) - shorten the two reserved-field comments; protolint enforces an 80 column limit and both were 81 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:81e9994
Author:Tim Smith
Committer:Tim Smith

πŸ›‘ remove deprecated min_mondoo_version from the resource schema `ResourceInfo.min_mondoo_version` (field 25) and `Field.min_mondoo_version` (field 23) were marked `[deprecated = true]` and documented "remove in v14, not used anymore as of v13". Nothing in this repo or in cnspec reads or writes them outside the generated marshalling code -- `min_provider_version` carries the signal now. Both field numbers are marked `reserved` so they can never be reused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:55e66c9
Author:Dominik Richter
Committer:GitHub

🧹 v14 -> non-versioned go-mod (#10234) * 🧹 v14 -> non-versioned go-mod We are removing the versioned dependency in golang. This doesn't affect end-users of MQL, so y'all are fine. This is only relevant for developers and whoever integrates with the go-dependencies of this project (or cnspec). Given the consistancy at which we are now releasing major versions, we decided that this version indicator doesn't really provide much value anymore. The important APIs are versioned anyway and everything else has clean deprecation windows that aren't affected by the go-dependencies. Thus, we can avoid one annoying (potentially erroneous) update step every 6 months and all the ripple-effects it has. * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:cb829a9
Author:Tim Smith
Committer:Tim Smith

πŸ›‘ inventory: remove the deprecated connection `backend` field The `backend` field and its `ProviderType` enum were replaced by the string `type` field back in v10, and every code path since has treated `backend` purely as a migration fallback. The FIXME asking for their removal has been sitting in `inventory.proto` for four majors; v14 is the window. Removed: - `enum ProviderType` and `Config.backend` from `inventory.proto`. Field number 28 is now `reserved` so a future field cannot silently inherit the old wire tag. - `v8_inventory.go` in full. It held the `ProviderID_*` constants, the `ProviderType_idvalue` lookup, `ProviderType.UnmarshalJSON` and `ConnBackendToType` β€” all of which existed only to serve `backend`, and none of which is referenced anywhere else. Its own header said the file could go in v10. - The migration fallbacks in `InventoryFromYAML` and `Runtime.providerForAsset`. - `conf.Backend = ProviderType_HOST` in the network provider, a write that nothing read. An inventory that specifies neither `type` nor `backend` previously warned and resolved to an empty connection type, which then failed further down in provider lookup with an unrelated message. It now reports "no connection `type` provided in inventory" against that connection and moves to the next one, so the multierr names the real problem. The commented-out examples in `testdata/aws_inventory.yaml` were updated to `type:` so they stop teaching a field that no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:d5f27b1
Author:Tim Smith
Committer:Tim Smith

🟒 reserve the min_mondoo_version field name and fix protolint - reserve the field *name* in addition to the number, so neither the tag nor the identifier can be reused (review suggestion) - shorten the two reserved-field comments; protolint enforces an 80 column limit and both were 81 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:8c41696
Author:Tim Smith
Committer:Tim Smith

πŸ›‘ remove deprecated min_mondoo_version from the resource schema `ResourceInfo.min_mondoo_version` (field 25) and `Field.min_mondoo_version` (field 23) were marked `[deprecated = true]` and documented "remove in v14, not used anymore as of v13". Nothing in this repo or in cnspec reads or writes them outside the generated marshalling code -- `min_provider_version` carries the signal now. Both field numbers are marked `reserved` so they can never be reused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:27ec312
Author:Tim Smith

🟒 reserve the min_mondoo_version field name and fix protolint - reserve the field *name* in addition to the number, so neither the tag nor the identifier can be reused (review suggestion) - shorten the two reserved-field comments; protolint enforces an 80 column limit and both were 81 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:2bf4a58
Author:Tim Smith

πŸ›‘ remove deprecated min_mondoo_version from the resource schema `ResourceInfo.min_mondoo_version` (field 25) and `Field.min_mondoo_version` (field 23) were marked `[deprecated = true]` and documented "remove in v14, not used anymore as of v13". Nothing in this repo or in cnspec reads or writes them outside the generated marshalling code -- `min_provider_version` carries the signal now. Both field numbers are marked `reserved` so they can never be reused. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:dcb4606
Author:Tim Smith

πŸ›‘ inventory: remove the deprecated connection `backend` field The `backend` field and its `ProviderType` enum were replaced by the string `type` field back in v10, and every code path since has treated `backend` purely as a migration fallback. The FIXME asking for their removal has been sitting in `inventory.proto` for four majors; v14 is the window. Removed: - `enum ProviderType` and `Config.backend` from `inventory.proto`. Field number 28 is now `reserved` so a future field cannot silently inherit the old wire tag. - `v8_inventory.go` in full. It held the `ProviderID_*` constants, the `ProviderType_idvalue` lookup, `ProviderType.UnmarshalJSON` and `ConnBackendToType` β€” all of which existed only to serve `backend`, and none of which is referenced anywhere else. Its own header said the file could go in v10. - The migration fallbacks in `InventoryFromYAML` and `Runtime.providerForAsset`. - `conf.Backend = ProviderType_HOST` in the network provider, a write that nothing read. An inventory that specifies neither `type` nor `backend` previously warned and resolved to an empty connection type, which then failed further down in provider lookup with an unrelated message. It now reports "no connection `type` provided in inventory" against that connection and moves to the next one, so the multierr names the real problem. The commented-out examples in `testdata/aws_inventory.yaml` were updated to `type:` so they stop teaching a field that no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Commit:9640843
Author:Dominik Richter
Committer:GitHub

🌟 v14: asset tree relationships (ADR-030) (#9534) * 🌟 asset tree relationships (ADR-030) This is a v14 feature that provides Asset Relationships, anchored in the resource-tree. It deprecates the traditional (flat) relationships in favor of these relationships which point to schema anchors that can be used to tie it all together. The follow-up ADR-031 will allow us to run queries across this connection. * 🟒 reviewer feedback Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:31ed9b6
Author:Christoph Hartmann
Committer:GitHub

feat(fex): add label and mime_type to File evidence (#9423) * feat(fex): add label and mime_type to File evidence The File evidence message could carry document contents but had no way to name or type them. Add two optional fields: - `label` β€” a human-readable label/identifier for the file evidence, useful when a finding carries several file evidences or when a UI needs a title for the document rather than a raw path. - `mime_type` β€” the MIME/content type (e.g. "application/json") so consumers can interpret or render `contents` correctly. Regenerated fex.pb.go and fex_vtproto.pb.go. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(fex): keep File label/mime_type comments under 80 cols (protolint) The label comment line exceeded protolint's 80-column limit. Reflow the two new comments and regenerate (the doc comments are mirrored into fex.pb.go). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:344881d
Author:Christoph Hartmann
Committer:GitHub

sbom: dependency graph + dev/prod scope + stable bom_ref (#9036) * feat(languages): expose packageβ†’package dependency edges (npm, ref-based) Adds `DependsOn []string` to languages.Package β€” the refs (purls) of the packages a package directly depends on, i.e. the dependency-graph edges the Bom's Root/Direct/Transitive shape flattened away. Refs (not names) disambiguate a package present at multiple versions. npm packagelockjson (lockfileVersion 2+) populates it: for each package entry's `dependencies`, resolve the required name to its installed `packages` entry via npm hoisting (fromPath/node_modules/dep, walking up to root), and use that entry's purl as the ref β€” built identically to how the target node's own Purl is built, so an edge ref always matches its target node (self-consistent graph). Left nil where the manifest encodes no edges (Go go.mod) or the legacy lockfileVersion≀1 branch. Same pattern will extend to cargo/pnpm/yarn/bun. Prototype for xgrep SCA reachability (R2); to be reconciled with the mql team + the sbom-proto/CycloneDX dependencies section before upstreaming (see design doc). Tests: TestPackageJsonLockDependencyEdges (appβ†’fooβ†’bar, edge ref == target Purl); full languages suite green. * fix(languages): packagelockjson Direct() resolves deps by install path Direct() looked the root's declared dependencies up in the `packages` map by bare name, but that map is keyed by install path (node_modules/<name>) for lockfileVersion 2+, so every lookup missed and Direct() returned an empty set. Resolve via node_modules/<name> and build Name/Purl/Cpes/DependsOn from the path key, identical to Transitive(), so a package's Direct and Transitive representations (and refs) match. This restores the direct/transitive split that downstream SCA scope relies on. Test: TestPackageJsonLockDirect (rootβ†’foo resolved, matches Transitive's foo). * feat(languages): expose dev/prod dependency scope (npm) Add `Scope` to languages.Package (PackageScopeProd / PackageScopeDev / "" when the manifest doesn't distinguish), so a consumer can rank a CVE in a dev/test-only tool differently from a production-runtime one. npm packagelockjson populates it from the lock's per-package `dev` flag (lockfileVersion 2+); devOptional counts as prod since it can appear in the production tree. Left "" for the legacy v1 branch and ecosystems without the flag. Parser gains Dev/DevOptional fields. Tests: TestPackageJsonLockScope + @babel/code-frame (dev) equality/golden assertions updated. Full languages suite green (52 pkgs). * sbom: model dependency graph + dev/prod scope + stable bom_ref on the proto Add the CycloneDX/SPDX dependency-graph and scope shape to the sbom proto so the package->package dependency graph and dev/prod scope the lockfile parsers already resolve survive into the standard SBOM output (previously flattened away): - Package.bom_ref (28): a stable, document-internal component id. Deterministic -- purl-when-present, else synthesized -- replacing the per-render uuid.New() bom-ref so CycloneDX output is reproducible and dependency edges have a stable endpoint. - Package.scope (29): prod/dev dependency scope. - Sbom.dependencies (7) + Dependency{ref, depends_on}: the package->package graph, each endpoint referenced by bom_ref (the CycloneDX dependencies / SPDX DEPENDS_ON shape). Renderers: the generator stamps a deterministic bom_ref on every component; CycloneDX emits the dependencies section + maps dev scope to ScopeExcluded; SPDX emits DEPENDS_ON relationships. sbom.BomRefFor centralizes the ref rule. Populating Sbom.dependencies/scope end-to-end still needs the per-ecosystem package resources to carry dependsOn/scope (schema + codegen) -- a follow-up; the proto model and renderers are in place here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * languages: dependency edges + scope for pnpm, yarn, cargo Fan out the DependsOn (ref=purl) + Scope pattern (established for npm packagelockjson) to the other tree-encoding lockfile parsers, so their package->package graph survives into the SBOM: - pnpm (pnpmlock): DependsOn from each entry's resolved `dependencies`; Scope from the per-entry `dev` flag (v5/v6; v9 carries no per-entry flag -> prod). - yarn (yarnlock): DependsOn resolved via a name@spec -> resolved-version index built from the lockfile keys (which may list several specs per entry). yarn v1 does not distinguish dev from prod, so no scope. - cargo (cargolock): DependsOn from each crate's `dependencies` list, resolving a version-less reference when the crate is locked at a single version. Cargo.lock has a unified resolve graph (no dev/normal split), so no scope. Each edge ref is built the same way the parser builds each package's own Purl, so an edge ref matches its target node's Purl (a self-consistent graph). bun.lock is deferred: it uses npm-style hoisting with a tuple format that needs richer fixtures to resolve edges. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * sbom: satisfy protolint + copywrite on the new proto/fields - rename repeated field depends_on -> dependency_refs (protolint REPEATED_FIELD_NAMES_PLURALIZED); update renderers + test. - reflow new proto comments under the 80-col limit. - add the copyright year to the new dependency_graph_test.go header. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(sbom): integrity hashes on the package model and renderers Add the third SBOM-fidelity field alongside the dependency graph and scope: package integrity digests. - languages.Package.Hashes ([]PackageHash{Alg, Value}) β€” hex digests tagged with the CycloneDX algorithm spelling. Populated by the npm packagelockjson parser from the lockfile Subresource-Integrity `integrity` (sha512-<base64> -> hex), across the v2+ packages, root-declared, and legacy dependency paths. - sbom proto: a Hash message + repeated Package.hashes (field 30), regenerated. - CycloneDX renderer emits component.hashes; SPDX emits package checksums (dash-free algorithm spelling). - Tests: hashesFor SRI parsing (algs/malformed/empty), updated npm extractor expectations, and CycloneDX/SPDX hash rendering. Other ecosystems leave Hashes nil (unaffected). protolint + the sbom/languages suites are green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(languages): correct npm purls for scoped and nested packages NewPackageUrl was fed the lockfileVersion 2+ install-path key (e.g. "node_modules/@babel/core"), which it split on "/" β€” taking "node_modules" as the namespace and "@babel" as the name. Every scoped package under a path key collapsed to `pkg:npm/node-modules/%40<scope>@<version>`, so purl-keyed consumers deduped whole scopes down to one component (all of @babel/* β†’ one). Nested copies were also named by their full path ("@babel/core/node_modules/ms"). - packageLockPackageName now takes the segment after the LAST "node_modules/", so scoped names survive ("@babel/core") and nested copies resolve to the bare name ("ms"). - Direct/Transitive and resolveDepPurl build Purl/Cpes/edge-refs from that name, not the path key β€” yielding `pkg:npm/%40babel/core@<version>` and self-consistent graph edges. Verified against a real express+jest tree: recovers ~40 previously-dropped scoped packages (incl. all @babel core packages) with zero purl-prefix artifacts. Updated the extractor test that had encoded the buggy purl/cpe. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sbom): review hardening β€” DoS guard, SPDX injection, scope/dedup fixes Addresses the performance/security/production-readiness review of this PR: - SECURITY: bound the npm resolveDepPurl node_modules walk-up (maxNodeModulesDepth) so a crafted deeply-nested lockfile key can't drive superlinear CPU (per-scan DoS). Also precompute a pathβ†’purl index once per lockfile, removing the O(edges) redundant NewPackageUrl rebuilds. - SECURITY: NewSPDXPackageID now assigns the sanitizer result back (`id = expr.ReplaceAllString(...)`) β€” previously a no-op, letting a package name with a newline inject tags into SPDX tag-value output. - ACCURACY: pnpm v9 lockfiles carry no per-entry dev flag; scopeOf now returns "" (unknown) for v9 instead of asserting prod, so a dev-only package isn't mislabeled production (consistent with yarn/cargo). - CORRECTNESS: the CycloneDX renderer dedups components by bom-ref (two packages sharing a purl no longer emit a duplicate, invalid bom-ref) and drops dependency edges referencing absent components (matches the SPDX renderer). - Deterministic root/OS component bom-refs (were per-render UUIDs). Tests added for each. Full sbom + languages suites green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(languages): parse classic yarn.lock v1 + integrity hashes for pnpm/yarn (a) Classic yarn.lock (v1) failed to parse: the on-the-fly YAML converter only rewrote quoted `key "value"` lines, but yarn writes `integrity sha512-…` unquoted, leaving invalid YAML β€” so a real `yarn add` lockfile never parsed. The converter now handles both quoted and unquoted values and passes through comments/blank lines/mapping headers; scanner buffer grown for long integrity lines. Verified against a real express yarn.lock (68 pkgs, exact syft parity). (b) Integrity hashes now extend to pnpm and yarn (both record SRI `integrity`), not just npm. Extracted the shared SRIβ†’hash logic into javascript.NewHashes and call it from all three parsers; npm's local hashesFor is removed. pnpm reads resolution.integrity, yarn reads the new entry Integrity field. Verified e2e vs syft across react-dom/webpack/eslint/@nestjs (npm), pnpm-webpack, and yarn-express: exact coverage parity, clean purls, self-consistent graphs, and hashes now present for pnpm (0β†’70) and yarn (68). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: fix golangci-lint (De Morgan) and license headers - yarnlock converter: `!(A && B)` β†’ `!A || !B` (staticcheck QF1001). - Add the copywrite-compliant license header to the new test files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(sbom): address code-review β€” SPDX dedup, license field, scope docs - SPDX renderer now dedups packages by bom-ref (matches CycloneDX). Two entries sharing a purl no longer emit duplicate SPDX packages / silently overwrite the refToID map with a possibly-different id. - Fix a pre-existing copy-paste bug: PackageLicenseDeclared was set to pkg.Version instead of pkg.License. - Document the npm scopeOf devOptional handling (dev+optional and optional-only both report prod, since they can appear in the deployed tree) and add a TestScopeOf covering the four flag combinations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

Commit:efcac53
Author:Christoph Hartmann
Committer:GitHub

✨ fex: add CloudResource component detail (#9394) * ✨ fex: add CloudResource component detail A Component captures the id/identifiers of what a finding is about, but for a cloud object (an AWS/Azure/GCP resource) the bare id loses the structured detail worth recording. Add a CloudResource variant to the component details oneof β€” provider, native id (ARN / full resource name), type, region, account, partition, and tags β€” so a finding can carry the resource's structure, not just its id. All fields optional. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 🧹 fex: keep CloudResource proto comments under the 80-char lint limit --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:ecd564d
Author:Christoph Hartmann
Committer:GitHub

✨ fex: add city and coordinates to NetworkRange geolocation (#9391) NetworkRange already carries the ASN, AS/org name, and country of an IP block. Add the finer geolocation an IP-geo lookup commonly returns β€” city name and latitude/longitude (decimal degrees) β€” so a network evidence can record where an address is located, not just which country and ASN it belongs to. All optional. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:39a670a
Author:Christoph Hartmann
Committer:GitHub

✨ fex: add ThreatIntelIndicator, Malware, AiModel, AiAgent evidence (#9355) Extend the FindingExchange Evidence.details oneof with four structured evidence types: - ThreatIntelIndicator β€” an IP, domain, URL, or file hash observed and matched against threat intelligence (type, value, category, source, source_url, last_observed_at). First-class evidence for threat findings. - Malware β€” a detected malicious-software artifact (name, type, path, state). - AiModel β€” the AI/ML model involved in a finding (name, type, version, publisher, deployment). - AiAgent β€” the AI agent implicated in or that flagged a finding (id, name, model, session_id). Additive: field numbers 32-35 in the oneof, no existing field changed, so wire-compatible. Regenerated fex.pb.go and fex_vtproto.pb.go. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:207b485
Author:Christoph Hartmann
Committer:GitHub

feat(fex): propose network detail types for Evidence (#9351) * feat(fex): propose network detail types for Evidence Add typed network artifacts to fex.Evidence so findings from network scanners carry structured detail instead of untyped properties, following the HttpRequest precedent. Adds Connection.evidence (matched banner/service string, field 6) and four details oneof variants: DnsRecord (28), Certificate (29), DomainRegistration (30), and NetworkRange (31). Generated code regenerated; protolint passes. Status: Proposed. Field names mirror the server-internal etl schema, so these only surface once the server learns them; see ADR 029. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(fex): use uint32 for NetworkRange.asn to fit 4-byte ASNs ASNs are unsigned 32-bit (RFC 6793), up to 4,294,967,295 β€” a signed int32 caps at 2^31-1 and would sign-flip high ASNs already in use. Switch to uint32. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(fex): DnsRecord.ttl uint32; document type as free-form string TTL is a 31-bit unsigned quantity (RFC 2181 Β§8), so uint32 avoids representing nonsensical negative TTLs, consistent with NetworkRange.asn. Keep DnsRecord.type a free-form string (not an enum) β€” the IANA record-type registry is large and evolving and scanners surface arbitrary types; documented inline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:bd4d30f
Author:Christoph Hartmann
Committer:GitHub

✨ fex: add code-location line/column to FileComponent (#9228) Add start_line/end_line/start_column/end_column to FileComponent so SAST/SARIF findings can carry the code location where an issue occurs. The SARIF converter (and future SAST converters) currently drop region line info because there was nowhere to put it. Additive/backward-compatible (0 = unset). Regenerated pb/vtproto. Part of ADR-062's field-fidelity proto-extension backlog (Tier 1, code location). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:97588f3
Author:Christoph Hartmann
Committer:GitHub

✨ fex: add HttpRequest evidence type for DAST findings (#9226) Add an HttpRequest message and wire it into the Evidence oneof (field 27). It captures the web request that triggered a finding β€” method, url, param, attack payload, matched evidence, and optional raw request/response β€” giving DAST scanners (OWASP ZAP, Burp Suite) a first-class home for request context instead of the generic properties map. Additive/backward-compatible. Regenerated pb/vtproto; added a round-trip test. Part of ADR-062's field-fidelity proto-extension backlog (Tier 2). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:e43eebc
Author:Christoph Hartmann
Committer:GitHub

✨ Add sbomupload upstream client (Sbom.BulkUploadSbom) (#9223) Add the Mondoo Platform SBOM-upload client to mql, next to sbomscan/fex/mvd. Uploading an SBOM via Sbom.BulkUploadSbom stores it and lets the platform enrich it into vulnerabilities automatically β€” the client computes no VEX. This is the "upload SBOM, VEX happens upstream" path (distinct from sbomscan's ephemeral ScanUploadedSbom, which returns VEX for the caller to upload). - providers-sdk/v1/upstream/sbomupload: sbomupload.proto (package mql.sbomupload.v1, service Sbom) + generated pb/vtproto + hand-written ranger client + round-trip test. - Makefile: add to shared/generate. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:263900a
Author:Christoph Hartmann
Committer:GitHub

✨ Add sbomscan upstream client (ExtendedVulnMgmt.ScanUploadedSbom) (#9150) Promote the Mondoo Platform vulnerability-scan client from xgrep into mql, its canonical home next to providers-sdk/v1/upstream/{fex,mvd}. Clients (cnspec, xgrep) send an SBOM to ExtendedVulnMgmt.ScanUploadedSbom and get back VEX (ephemeral scan; caller uploads the VEX itself). - providers-sdk/v1/upstream/sbomscan: vulnscan.proto (package mql.sbomscan.v1) + generated pb/vtproto + the hand-written ranger client + a round-trip test. - Makefile: add the package to shared/generate. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:6ae773c
Author:Christoph Hartmann

sbom: satisfy protolint + copywrite on the new proto/fields - rename repeated field depends_on -> dependency_refs (protolint REPEATED_FIELD_NAMES_PLURALIZED); update renderers + test. - reflow new proto comments under the 80-col limit. - add the copyright year to the new dependency_graph_test.go header. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Commit:59b00a6
Author:Christoph Hartmann

sbom: model dependency graph + dev/prod scope + stable bom_ref on the proto Add the CycloneDX/SPDX dependency-graph and scope shape to the sbom proto so the package->package dependency graph and dev/prod scope the lockfile parsers already resolve survive into the standard SBOM output (previously flattened away): - Package.bom_ref (28): a stable, document-internal component id. Deterministic -- purl-when-present, else synthesized -- replacing the per-render uuid.New() bom-ref so CycloneDX output is reproducible and dependency edges have a stable endpoint. - Package.scope (29): prod/dev dependency scope. - Sbom.dependencies (7) + Dependency{ref, depends_on}: the package->package graph, each endpoint referenced by bom_ref (the CycloneDX dependencies / SPDX DEPENDS_ON shape). Renderers: the generator stamps a deterministic bom_ref on every component; CycloneDX emits the dependencies section + maps dev scope to ScopeExcluded; SPDX emits DEPENDS_ON relationships. sbom.BomRefFor centralizes the ref rule. Populating Sbom.dependencies/scope end-to-end still needs the per-ecosystem package resources to carry dependsOn/scope (schema + codegen) -- a follow-up; the proto model and renderers are in place here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Commit:67c3abb
Author:Christoph Hartmann
Committer:GitHub

✨ Add CATEGORY_SECRET to FEX FindingDetail category (#9019) Secrets-detection findings (e.g. from xgrep's `secrets` rule category) were indistinguishable from code/SAST findings because there was no dedicated category β€” they had to be reported as CATEGORY_SECURITY. Add CATEGORY_SECRET (= 7) so downstream consumers can classify and surface secrets on their own. Additive enum value; regenerated fex.pb.go. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:5ca99bc
Author:Christoph Hartmann
Committer:GitHub

🌟 fex: publish Finding Exchange proto contract in the provider SDK (#8478) * 🌟 fex: publish Finding Exchange proto contract in the provider SDK Add a new providers-sdk/v1/upstream/fex package publishing the public Finding Exchange (FEX) and Vulnerability Exchange (VEX) data structures. This is the contract query packs use to construct finding/vulnerability documents and the format used to batch findings for upload. Messages: - FindingDocument (oneof wrapper: vex or fex) - VulnerabilityExchange, FindingExchange - FindingsUploadRequest (batch wrapper) - supporting types: Affects, Component, FileComponent, Rating, Severity, Source, Reference, VulnerabilityDetails, Remediation, FindingDetail, Evidence (+ File/User/Process/Container/Kubernetes/RegistryKey/ Connection/AttackTactic/AttackTechnique) - enums: Status, ScoringMethod, Confidence, SeverityRating, and the nested Remediation.Category, FindingDetail.Category, Connection.ConnectionProtocol The package is self-contained (imports only well-known google protobuf types). Field 14 of VulnerabilityExchange is reserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * πŸ“„ fex: fix two doc-comment typos in fex.proto - "finding wa last seen" -> "finding was last seen" - add missing space after // on the Evidence comment Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * πŸ“„ fex: wrap Evidence comment to stay under 80 cols Adding the missing space after // pushed the line to 81 chars. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Commit:b2ad665
Author:Christoph Hartmann
Committer:GitHub

🧹 ci: replace check-spelling with typos (#8461) * 🧹 ci: replace check-spelling with typos for spell checking The check-spelling@v0.0.26 action self-aborts on a security advisory it published against its own latest release, so the spell-check job fails on every PR that touches a checked file. Switch to crate-ci/typos, which checks the whole repo and is config-driven. Add _typos.toml: exclude generated code and testdata, and baseline the existing vocabulary β€” real technical terms and abbreviations, a company name, intentional test fixtures, and a set of pre-existing misspellings that are baked into MQL schema field names / exported Go identifiers (renaming those is a breaking change, left for a separate cleanup). Also fix the genuine typos typos found in comments, strings, and local identifiers across the tree, and drop the now-unused check-spelling config under .github/actions/spelling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * 🧹 ci: address spell-check review feedback - ipmi: keep the misspelled "ipmbEventReciever" JSON tag for wire/persisted compatibility (renaming it silently drops the field from old payloads); the Go field stays correctly named. Baseline "reciever" in _typos.toml. - ms365: fix "scaped"/"scaping" -> "escaped"/"escaping" in comments, which typos missed. - sbom: regenerate mql_sbom.pb.go from the .proto via go generate rather than hand-editing the generated file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

Commit:fe4c014
Author:Christoph Hartmann
Committer:Christoph Hartmann

🧹 ci: replace check-spelling with typos for spell checking The check-spelling@v0.0.26 action self-aborts on a security advisory it published against its own latest release, so the spell-check job fails on every PR that touches a checked file. Switch to crate-ci/typos, which checks the whole repo and is config-driven. Add _typos.toml: exclude generated code and testdata, and baseline the existing vocabulary β€” real technical terms and abbreviations, a company name, intentional test fixtures, and a set of pre-existing misspellings that are baked into MQL schema field names / exported Go identifiers (renaming those is a breaking change, left for a separate cleanup). Also fix the genuine typos typos found in comments, strings, and local identifiers across the tree, and drop the now-unused check-spelling config under .github/actions/spelling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Commit:c8880f1
Author:Dominik Richter
Committer:GitHub

πŸ“ƒ document alias handling on resources metadata (#8201)

Commit:d90a2b7
Author:Preslav

✨ Add SendReport RPC for structured diagnostic reports ErrorReporting now also exposes SendReport β€” a schema-less envelope that ships a google.protobuf.Struct payload tagged with a report_type discriminator. The envelope (service_account_mrn, agent_mrn, product, tags) mirrors SendErrorReq so both flow through the same auth + Sentry routing on the platform side. First consumer is the serverless-scanner-aws lambda's on-demand health report. The server-side handler can stay a no-op until consumers materialize; the type registration in this PR is enough for clients to start emitting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Commit:918a60e
Author:Christian Zunker
Committer:GitHub

✨ sbom.Package: add license + install_date proto fields (#7817) Adds two slots on sbom.Package so SBOM uploads can carry the new package metadata exposed by the OS / npm / python work: string license = 26; string install_date = 27; `license` is the SPDX expression (or upstream-reported license string). `install_date` is RFC3339 β€” empty when the backend doesn't report install time (dpkg without log parsing, apk, pacman, macOS). Pure proto + regen; no behavioural change to existing code paths. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Commit:33e4b54
Author:Jay Mundrawala
Committer:GitHub

🎫 Add feature flag for token-response WIF token exchange (#7362) Introduces the ExchangeTokenForToken feature flag. When enabled, the WIF external token exchange sends response_type=TOKEN and decodes the returned bearer token into ServiceAccountCredentials.Token. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Commit:8d9ecd8
Author:Jay Mundrawala
Committer:GitHub

Allow authenticating a service account with a bearer token (#6910)

Commit:a93c983
Author:Dominik Richter
Committer:GitHub

⭐ introduce maturity for providers, resources, and fields (#7140)

Commit:5cdca23
Author:Christoph Hartmann
Committer:GitHub

🧹 update copyright year to 2024, 2026 and bump copywrite to v0.25.2 (#7082) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Commit:da25948
Author:Ivan Milchev
Committer:GitHub

✨ implement vault delete for berglas (#7078) * ✨ implement vault delete for berglas Signed-off-by: Ivan Milchev <ivan@mondoo.com> * address comments Signed-off-by: Ivan Milchev <ivan@mondoo.com> --------- Signed-off-by: Ivan Milchev <ivan@mondoo.com>

Commit:52e7bf6
Author:Mikita Iwanowski
Committer:GitHub

✨ Add custom tags to error reports for enhanced context (#6957)

Commit:2cbeede
Author:vj

✨ Add platform info to slow query alert Add PlatformInfo message to the error reporting proto and include it in SendErrorReq and SlowQueryInfo so slow query alerts carry context about the platform being scanned (name, arch, title, kind, runtime). Closes #6877 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Commit:c839db3
Author:Dominik Richter
Committer:GitHub

✨ track provider versions per resources and fields (#6654) * ✨ track provider versions per resources and fields Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * πŸ› fix minMondooVersions to previous state Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:fc08d03
Author:Dominik Richter
Committer:Dominik Richter

πŸ›‘ rename sbom cnquery=>mql Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:55dc1bd
Author:Dominik Richter
Committer:Dominik Richter

πŸ›‘πŸŒŸ cnquery => mql (#6599) * πŸ›‘πŸŒŸ rename cnquery => mql This is a major restructure as part of the v13 release. We are renaming cnquery to simplify concepts and just focus on mql instead. As part of v13 we are already moving all querypacks to cnspec, so what remains is the unification of the data-plane. Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * ✨ cnquery => mql logo + duplicate cleanup Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:1190a8e
Author:Dominik Richter
Committer:Dominik Richter

πŸ›‘ remove cnquery scan (#6513) * πŸ›‘ remove cnquery scan Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 try to fix tests Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🧹 remove benchmark tests (see details) - we don't have querypacks anymore, which is what the benchmarks were running - we have benchmarks in cnspec - we will instead want separate provider and runtime benchmarks Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:cfc2a23
Author:Dominik Richter

πŸ›‘ rename sbom cnquery=>mql Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:ac591d5
Author:Dominik Richter
Committer:GitHub

πŸ›‘πŸŒŸ cnquery => mql (#6599) * πŸ›‘πŸŒŸ rename cnquery => mql This is a major restructure as part of the v13 release. We are renaming cnquery to simplify concepts and just focus on mql instead. As part of v13 we are already moving all querypacks to cnspec, so what remains is the unification of the data-plane. Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * ✨ cnquery => mql logo + duplicate cleanup Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:71f87d4
Author:Tim Smith
Committer:GitHub

πŸ“„ Update outdated documentation URLs (#6569) * πŸ“„ Update outdated documentation URLs Fix redirecting URLs in comments and documentation: - golang.org β†’ go.dev (Go moved their docs) - docs.microsoft.com β†’ learn.microsoft.com (Microsoft consolidated docs) - jqlang.github.io/jq β†’ jqlang.org (jq moved their site) - tools.ietf.org β†’ datatracker.ietf.org (IETF consolidated) - www.terraform.io/docs β†’ developer.hashicorp.com/terraform (HashiCorp moved docs) - cnquery.io β†’ mondoo.com/cnquery (domain redirect) - git.k8s.io β†’ github.com/kubernetes (shortlink to full URL) - confluence.jetbrains.com β†’ jetbrains.com/help/teamcity (JetBrains moved docs) - wiki.jenkins.io β†’ jenkins.io/doc (Jenkins moved docs) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * 🧹 regenerate proto file * 🧹 fix protolint errors --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Christoph Hartmann <chris@lollyrock.com>

Commit:369c978
Author:Dominik Richter
Committer:GitHub

πŸ›‘ remove cnquery scan (#6513) * πŸ›‘ remove cnquery scan Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🟒 try to fix tests Signed-off-by: Dominik Richter <dominik.richter@gmail.com> * 🧹 remove benchmark tests (see details) - we don't have querypacks anymore, which is what the benchmarks were running - we have benchmarks in cnspec - we will instead want separate provider and runtime benchmarks Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:66136f4
Author:Christoph Hartmann
Committer:GitHub

🧹shell suggestions (#6378) * 🧹 remove filtered queries for shell as this is not stable * 🧹simplify the shell completer * 🧹 include provider in suggestion * 🧹sort shell suggestion by connected provider * 🧹 add test for shell resource sorting function

Commit:c0d2c18
Author:Christoph Hartmann

🧹 include provider in suggestion

Commit:8dbd478
Author:Preslav Gerchev
Committer:GitHub

🧹 Drop deprecated v8 kind. (#3976) Signed-off-by: Preslav <preslav@mondoo.com>

Commit:bbada67
Author:Dominik Richter
Committer:GitHub

✨ extract property handler for bundles/packs + update examples (#5900)

Commit:7781208
Author:Dominik Richter
Committer:GitHub

⭐ add support for server-side features (#5898) This allows the server to set or unset certain features that it supports. This means e.g. that if the server can store resources data in the new format, we can send it this way. Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:97cab15
Author:Dominik Richter
Committer:Dominik Richter

πŸŽ‰ v12.0.0-pre1 Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:ba6b63a
Author:Dominik Richter
Committer:Dominik Richter

πŸŽ‰ v12.0.0-pre1 Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:8322827
Author:Christian Zunker
Committer:GitHub

✨ Add installed kernels explicitly to SBOM (#5868) * ✨ Detect active and inactive kernels Add the MQL data to the SBOM. Signed-off-by: Christian Zunker <christian@mondoo.com> * πŸ“ƒ tiny message doc Signed-off-by: Dominik Richter <dominik.richter@gmail.com> --------- Signed-off-by: Christian Zunker <christian@mondoo.com> Signed-off-by: Dominik Richter <dominik.richter@gmail.com> Co-authored-by: Dominik Richter <dominik.richter@gmail.com>

Commit:dafa41a
Author:Christian Zunker
Committer:Christian Zunker

✨ Detect active and inactive kernels Add the MQL data to the SBOM. Signed-off-by: Christian Zunker <christian@mondoo.com>

Commit:c7e3b00
Author:Dominik Richter
Committer:Dominik Richter

πŸŽ‰ v12 πŸŽ‰ Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:d678028
Author:Dominik Richter
Committer:Dominik Richter

⭐ v12 Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:2c9d595
Author:Dominik Richter
Committer:Dominik Richter

⭐ v12 Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:4a50cdf
Author:Dominik Richter
Committer:Dominik Richter

⭐ v12 Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:8f45890
Author:Dominik Richter
Committer:GitHub

✨ introduce human time (#5778) This allows users to specify timestamps in a human-readable way. Particularly useful when dealing with YAML files, ie querypacks and policies, where you can now specify timestamps with a lot more grace and variety. We are also breaking out the time parsing code into its own utility so the same parser is now shared between MQL and policy/querypack bundles. Finally I found an issue with the numeric variants of RFC 822 and RFC 1123, since both are parsed in their non-numeric variants without error. Thus, the numeric variants are removed for now in the auto-detection. Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:d509746
Author:Christoph Hartmann
Committer:GitHub

⭐️ Improve cnquery sbom command (#5750) * ⭐️ add protobom for sbom conversion * 🧹 users need to explicitly enable the exclusion of the evidence for sbom generation * ⭐️ exclude CPEs from SBOM export * ⭐️ sbom asset title * 🧹 update go mod * 🧹 update protobuf files * 🧹 update go mod * 🧹 fix tests * 🧹 update cli test

Commit:8df7438
Author:Christian Zunker
Committer:GitHub

✨ Add title to SBOM packages (#5746) Signed-off-by: Christian Zunker <christian@mondoo.com>

Commit:b14a4ac
Author:Salim Afiune Maya
Committer:GitHub

✨ cnquery run `--exit-1-on-failure` (#5656) This change adds a new flag named `--exit-1-on-failure` which will make `cnquery` exit with code `1` if any query result failed. Simple Example: ``` cnquery run -c "1==2" --exit-1-on-failure ``` Closes https://github.com/mondoohq/cnspec/issues/1671 Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

Commit:8cd7f94
Author:Salim Afiune Maya
Committer:Salim Afiune Maya

✨ cnquery run `--exit-1-on-failure` This change adds a new flag named `--exit-1-on-failure` which will make `cnquery` exit with code `1` if any query result failed. Simple Example: ``` cnquery run -c "1==2" --exit-1-on-failure ``` Closes https://github.com/mondoohq/cnspec/issues/1671 Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

Commit:ddfe8ef
Author:Christian Zunker
Committer:GitHub

✨ Add MQL VEX document resource (#5555) * ✨ Add VEX documents to shodan hosts Fixes: https://github.com/mondoohq/cnquery/issues/5404 Signed-off-by: Christian Zunker <christian@mondoo.com> * 🧹 Rename VEX MQL resource and also add to core Signed-off-by: Christian Zunker <christian@mondoo.com> * Remove source from proto Signed-off-by: Christian Zunker <christian@mondoo.com> * 🧹 reverse changes in shodan * 🧹 make vex resource public Signed-off-by: Christian Zunker <christian@mondoo.com> --------- Signed-off-by: Christian Zunker <christian@mondoo.com> Co-authored-by: Christoph Hartmann <chris@lollyrock.com>

Commit:85ad84e
Author:Ivan Milchev
Committer:GitHub

✨ extend sbom proto (#5535) Signed-off-by: Ivan Milchev <ivan@mondoo.com>

Commit:779e4a6
Author:Salim Afiune Maya
Committer:GitHub

⭐️ `lr`: add provider dependencies to schema (#5495) * ⭐️ `lr`: add provider dependencies to schema Resources within a provider can depend on resources from another provider, for example; The `os` provider depends on `network` provider. The `lr` parser already reads these imports but it wasn't passing it to the schema. This change adds the list of dependencies so that we can install them at runtime. Signed-off-by: Salim Afiune Maya <afiune@mondoo.com> * ✨ test dependencies in lr files Signed-off-by: Salim Afiune Maya <afiune@mondoo.com> --------- Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

Commit:03884fa
Author:Dominik Richter
Committer:Dominik Richter

⭐ v12 Signed-off-by: Dominik Richter <dominik.richter@gmail.com>

Commit:e1647fb
Author:Salim Afiune Maya
Committer:Salim Afiune Maya

⭐️ `lr`: add provider dependencies to schema Resources within a provider can depend on resources from another provider, for example; The `os` provider depends on `network` provider. The `lr` parser already reads these imports but it wasn't passing it to the schema. This change adds the list of dependencies so that we can install them at runtime. Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

Commit:0e78e82
Author:Salim Afiune Maya
Committer:Salim Afiune Maya

wip Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>