Skip to content

feat: add support for Service.trustZone - #980

Open
VanL wants to merge 4 commits into
CycloneDX:mainfrom
modelmonster:feat/service-trust-zone
Open

feat: add support for Service.trustZone#980
VanL wants to merge 4 commits into
CycloneDX:mainfrom
modelmonster:feat/service-trust-zone

Conversation

@VanL

@VanL VanL commented May 19, 2026

Copy link
Copy Markdown

Adds the optional trust_zone field to Service, available in CycloneDX v1.5 and later. Serializes as trustZone in JSON and <trustZone> in XML for schemas 1.5, 1.6, and 1.7; omitted for earlier versions.

Implements part of issue #578.

Description

Adds the optional trust_zone field to Service, available in
CycloneDX v1.5 and later. Serializes as trustZone in JSON and
<trustZone> in XML for schemas 1.5/1.6/1.7; omitted for earlier
versions.

Resolves a part of: #578

AI Tool Disclosure

  • My contribution does not include any AI-generated content
  • My contribution includes AI-generated content, as disclosed below:
    • AI Tools: Codex, Claude Code
    • LLMs and versions: Opus 4.7, Codex 5.5 (XHigh)
    • Prompts: Reviewed the existing TODO in cyclonedx/model/service.py:242-251,
      drafted an implementation plan, and implemented per the CycloneDX 1.5+
      service.trustZone schema. Implemented multiple agent adversarial review.

Affirmation

@VanL
VanL requested a review from a team as a code owner May 19, 2026 17:13
@codacy-production

codacy-production Bot commented May 19, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@read-the-docs-community

read-the-docs-community Bot commented May 19, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds CycloneDX v1.5+ support for Service.trustZone (Python attribute trust_zone) in the Service model, ensuring it serializes/deserializes correctly and is omitted for earlier schema versions.

Changes:

  • Added optional trust_zone: Optional[str] to cyclonedx.model.service.Service, with schema-version-gated serialization (v1.5+ only) and XML normalized-string handling.
  • Added/updated JSON and XML output validation tests to confirm presence/absence by schema version and schema rejection for pre-1.5 documents.
  • Updated deserialization tests and snapshot fixtures/models to include trustZone for v1.5–v1.7 outputs.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cyclonedx/model/service.py Introduces trust_zone property with v1.5+ serialization views and normalized XML string handling; updates equality/hash tuple.
tests/test_output_xml.py Adds XML output tests for trustZone across schema versions, including normalization and pre-1.5 rejection validation.
tests/test_output_json.py Adds JSON output tests for trustZone across schema versions and pre-1.5 rejection validation.
tests/test_model_service.py Adds model-level tests for default/setter behavior and equality/sorted-set membership impact.
tests/test_deserialize_xml.py Adds XML deserialization test for trustZone (v1.7).
tests/test_deserialize_json.py Adds JSON deserialization test and JSON→XML roundtrip test preserving trust_zone.
tests/_data/models.py Updates complex services fixture to set trust_zone so snapshots include the new field where applicable.
tests/_data/snapshots/get_bom_with_services_complex-1.5.xml.bin Snapshot updated to include <trustZone> for schema v1.5.
tests/_data/snapshots/get_bom_with_services_complex-1.5.json.bin Snapshot updated to include trustZone for schema v1.5.
tests/_data/snapshots/get_bom_with_services_complex-1.6.xml.bin Snapshot updated to include <trustZone> for schema v1.6.
tests/_data/snapshots/get_bom_with_services_complex-1.6.json.bin Snapshot updated to include trustZone for schema v1.6.
tests/_data/snapshots/get_bom_with_services_complex-1.7.xml.bin Snapshot updated to include <trustZone> for schema v1.7.
tests/_data/snapshots/get_bom_with_services_complex-1.7.json.bin Snapshot updated to include trustZone for schema v1.7.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jkowalleck

jkowalleck commented Jun 4, 2026

Copy link
Copy Markdown
Member

please rebase onto latest main branch

@jkowalleck

Copy link
Copy Markdown
Member

please rebase onto latest main branch.
It brings additional tests that might be needed here.

Comment thread tests/test_deserialize_json.py Outdated
bom: Bom = Bom.from_json(json) # <<< is expected to not crash
self.assertIsNotNone(bom)

def test_service_trust_zone_from_json(self) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this test needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the comment below, I usually put in similar tests. Sorry I didn't see the main serialization/deserialization harness. I have deleted/moved as appropriate.

Comment thread tests/test_deserialize_json.py Outdated
})
self.assertEqual('internal-vpc', next(iter(bom.services)).trust_zone)

def test_service_trust_zone_json_to_xml_roundtrip(self) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this test needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test (as well as the from-json test) were designed to make sure that the new trustZone items would round-trip correctly. Anytime I am working with a serialization format I add a similar test. I can remove it if you would like, though.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved per other comment.s

Comment thread tests/test_deserialize_xml.py Outdated
self.assertBomDeepEqual(expected, bom,
fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps)

def test_service_trust_zone_from_xml(self) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this test needed?

Comment thread tests/test_output_json.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(de)serzialization tests are automatically done with all the test models.
please move them there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Sorry for not noticing the proper harness.

Comment thread tests/test_output_xml.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(de)serzialization tests are automatically done with all the test models.
please move them there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Sorry for not noticing the proper harness.

VanL added 2 commits July 1, 2026 09:49
Adds the optional `trust_zone` field to `Service`, available in
CycloneDX v1.5 and later. Serializes as `trustZone` in JSON and
`<trustZone>` in XML for schemas 1.5, 1.6, and 1.7; omitted for earlier
versions.

Implements part of issue CycloneDX#578.

Signed-off-by: VanL <van@ospo.co>
Signed-off-by: VanL <van@ospo.co>
@VanL
VanL force-pushed the feat/service-trust-zone branch from c1325cb to 3db6f16 Compare July 1, 2026 14:50
Signed-off-by: VanL <van@modelmonster.ai>
@VanL
VanL force-pushed the feat/service-trust-zone branch from 3db6f16 to 32c8304 Compare July 1, 2026 21:52

@CAOShurong CAOShurong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted review disclosure: I used Codex to independently inspect and execute the checks below on the current head 25c9a4c. This is a technical review, not a maintainer or code-owner statement.

I verified the compatibility boundary that this change is intended to provide:

  • In a clean environment with the built 11.11.0 wheel installed, Service.trust_zone serializes as trustZone/<trustZone> for v1.5, v1.6, and v1.7; strict JSON/XML validation succeeds; root and nested services preserve the value through JSON and XML deserialization.
  • For v1.4, the field is omitted at both root and nested-service levels. Injecting trustZone into v1.4 JSON/XML is rejected by the bundled strict schemas, so the new field does not leak into older documents.
  • Focused model/output/deserialization tests: 756 passed. Full suite with PYTHONUTF8=1: 6962 passed. Flake8, mypy, wheel/sdist build, and clean-wheel installation also passed.

The implementation and current fixtures therefore preserve the pre-v1.5 boundary while adding the requested v1.5+ field. I found no correctness or compatibility issue on this exact head and approve.

@saquibsaifee

Copy link
Copy Markdown
Contributor

@VanL is the PR ready from your side?

@VanL

VanL commented Aug 31, 2026

Copy link
Copy Markdown
Author

Yes, I think so

@serializable.view(SchemaVersion1Dot6)
@serializable.view(SchemaVersion1Dot7)
@serializable.xml_sequence(9)
def trust_zone(self) -> Optional[str]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trust_zone property is missing the @serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING) decorator that all other Optional[str] fields in this class carry (e.g. group, description, version, name).

The CycloneDX schema defines trustZone as xs:normalizedString, which requires tab/newline characters to be collapsed to spaces. Without this decorator, a value like 'internal\tvpc' will be written as a literal tab into the XML output, producing an invalid document.

@property
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.view(SchemaVersion1Dot7)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)  # ← add this
@serializable.xml_sequence(9)
def trust_zone(self) -> Optional[str]:

After adding the decorator, the XML snapshot fixtures (*.xml.bin) need to be regenerated — the tab in internal\tvpc should be normalized to a space (internal vpc) in the XML output.

</endpoints>
<authenticated>false</authenticated>
<x-trust-boundary>true</x-trust-boundary>
<trustZone>internal vpc</trustZone>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML snapshot contains a raw tab character (internal\tvpc) rather than the normalized form internal vpc.

Since trustZone is typed as xs:normalizedString in the CycloneDX XML schema, tab/newline/carriage-return characters must be normalized to spaces before output. Once the @serializable.xml_string(NORMALIZED_STRING) decorator is added to the trust_zone property in service.py, please regenerate this snapshot — it should read <trustZone>internal vpc</trustZone> instead.

@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.view(SchemaVersion1Dot7)
@serializable.xml_sequence(9)

@saquibsaifee saquibsaifee Aug 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@serializable.xml_sequence(9)
@serializable.xml_sequence(9)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request schema 1.5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants