CBOMProfiles /Methodology ← Working group site
CORE

The profile: Interface Disclosure Baseline

This profile is product-independent. Its rules are structural: they say which categories of interface must exist, and what each one must disclose. Written that way, they apply to any product. No rule names a specific product or a specific interface instance.

Two directions of use

A single attribute table is applied in two directions.

Profile one attribute table Producer build / scanner → CBOM specification Consumer CI gate validates CBOM checklist
The profile serves as a specification for the party that generates the CBOM and as a conformance checklist for the party that consumes it.

Three kinds of rule

PRODUCT · nginx 1.27.0 interfaceType · service HTTPS service interface TLS 1.3 · via OpenSSL 3.4.0 client (browser) ↔ server (nginx) ✓ all per-interface rules interfaceType · management Management interface SSH 2.0 · via OpenSSH 9.6 client (admin) ↔ server (host) ← rule P2 requires this exists
Product rule P2 requires at least one management interface. Omitting the management interface, as the non-conforming CBOM does, fails rule P2 even when the service interface is fully described.

Product-level rules (constraints on the set of interfaces)

#RequirementLevelConstraint
P1Declare at least one cryptographic interfaceMUSTminInterfaces: 1
P2Declare at least one management interface, or state why there is noneMUSTminInterfacesOfType: {management, 1}, orDeclaredAbsent
P3Identify the subject the document describesMUSTsubjectIdentified: {startsWith: pkg:}
P4State how complete the declared interface set isMUSTproductAttribute: coverage

P1 and P2 catch omission, which per-attribute rules cannot: a document describing its service interface accurately while saying nothing about how the product is administered passes every interface rule and fails P2. P2 is satisfied either by declaring such an interface or by stating that the subject has none — a library or a hardware token with no configuration surface hides nothing by lacking one, and silence is what the rule is really against. That is the disclosure model applied to structure rather than to an attribute.

P3 and P4 are what make the document usable as a record rather than only as a description. Without P3 a CBOM need not say which version of what it describes, so it cannot be matched to a deployment or compared with the same product's record from last quarter. Without P4 a missing interface is uninterpretable: silence could mean the interface does not exist, or that the producer chose not to list it, and those are entirely different. The Conformance section names both of those as the non-assertions most likely to cause difficulty in procurement, and these are the rules that address them.

Per-interface rules (applied to every interface)

Names follow the conventions in Method. The bare name denotes present state, so keyExchange is what the interface uses; a profile needing declared capability adds the Supported suffix, as the PQC Migration profile does.

#AttributeLevelNotes
I1protocolMUSTTLS, SSH, IPsec, and similar
I2protocolVersionMUST
I3keyExchangeMUSTregistry algorithm identifier
I4encryptionMUSTbulk or AEAD algorithm
I5authenticationMUSTcertificate signature (TLS) or host key (SSH)
I6endpointRolesMUSTat least two endpoints
I7interfaceTypeMUSTfrom the controlled vocabulary
I8lifecycleStageMUSTsee Lifecycle Data
I9implementationPurlMUSTPackage URL of the implementing library. Withholdable: a withheld marker satisfies the rule, silent omission does not. This is the one rule here where the disclosure model decides the verdict.

Derived evaluations such as post-quantum posture are deliberately not profile attributes. They are computed by an external policy from the disclosed facts, because the criteria on which they depend change over time. See Policy Evaluation.

Group rules (one answer per key, within an interface)

The two kinds above each produce a single answer. A product rule answers about the set of interfaces. A per-interface rule answers about one attribute of one interface. Some questions do not have a single answer.

Ask whether an interface can be made quantum-safe. A producer whose key agreement is already done, and whose identity proof is waiting on a certificate authority, has two answers rather than one. Forcing a single answer would report the worse of the two, from which a planner concludes that nothing can proceed when in fact half of it can.

A group rule constrains a repeated group of entries, keyed by a controlled vocabulary. An interface carries one entry per key. The rule's member rules are evaluated inside an entry, so a conditional guard refers to that entry rather than to the interface as a whole.

The PQC Migration profile uses one, keyed by cryptographic purpose. Rule pqc-migration#G1 requires an entry per purpose, and its member G1.2 requires a blocker wherever that purpose's status is not available.

A group rule also declares its coverage, and this is the part worth attention. Coverage may be every value in the vocabulary, or only those values the profile's scope declares.

The difference decides whether a profile that addresses part of a problem is a stage or a floor. With full coverage, a purpose the profile defers still owes a status, so a consumer learns where it stands. With coverage limited to what is in scope, the deferred purposes disappear from the document entirely, and no later profile has a baseline to improve on. C13 checks this, because both readings load and run.

Disclosure states

An attribute with no value may be missing for several different reasons, and the profile keeps those reasons apart. Following the 2026 SBOM minimum elements, a producer states whether the information is unknown to it or is being withheld.

OutcomeMeaningEffect on a MUST rule
valueA value was supplied and checked against the constraint.Passes if valid.
withheldThe producer holds the information and declines to publish it.Passes only where the rule is marked withholdable.
unknownThe producer does not have the information.Fails, but is reported as unknown rather than absent.
undeclaredNeither a value nor a marker was supplied.Fails.

An unknown value does not satisfy a MUST rule, because the requirement has not been met. It is still reported separately from an undeclared one. The first records a limit of the producing process. The second records that the question was never addressed.

In this profile only I9 is withholdable. The reasoning is that a producer may decline to publish a library version and still meet the disclosure objective. A procurement profile might permit no withholding at all.

Which rules are withholdable decides something larger as well: whether a public document can clear the profile, or only a document released under an agreement. That is the subject of Confidentiality. One consumer cannot live with the permission at all. Matching a library against a vulnerability feed is the whole of incident response, and a withheld I9 leaves a responder with nothing to match, which is why Vulnerabilities treats it as the open question blocking that use case. See Challenges and Demo.

Composition: how profiles relate to each other

People mean two different things when they talk about combining profiles. Keeping the two apart matters, because they carry different guarantees.

Independent evaluation compared with extension INDEPENDENT EVALUATION one CBOM procurement migration vulnerability three separate verdicts no profile knows about the others EXTENSION base profile interface disclosure v0.7 derived profile adds and tightens only conforming to the derived profile means conforming to the base
Independent evaluation answers several questions about one document. Extension builds one profile out of another, and carries a guarantee that independent evaluation does not.

Independent evaluation

A CBOM may be evaluated against any number of profiles, each producing its own verdict. The profiles need not know of each other and are not combined. This is what the claim that one document serves several purposes amounts to: a vendor publishes once, and a procurement team, a migration planner and a vulnerability responder each apply the profile matching their decision.

Two conditions make this work. First, attribute names are global across the methodology, so a name means the same thing in every profile that uses it. That is why the naming conventions and the attribute table in Terms apply to all profiles rather than to each one in isolation. Second, a verdict is always reported per profile, so conformance to one says nothing about another.

Extension

A profile may declare that it extends another. It then inherits every rule of the base and states only what it adds or changes. A sector baseline built on a general one, and the PQC migration profile built on the interface disclosure baseline, are both of this kind.

Extension is monotonic. A derived profile may add rules and tighten inherited ones. It may not relax them. What this buys is the property that makes extension worth having: a document that conforms to the derived profile also conforms to the base. Without it, a claim of conformance to a sector profile "based on" the baseline would tell a consumer nothing at all about the baseline, and the word "based" would be doing misleading work.

Operation on an inherited rulePermittedWhy
Raise the level, SHOULD to MUSTyesTightening. Anything satisfying the derived rule satisfies the base rule.
Narrow a constraint, such as restricting an enumeration to a subset or raising a minimum countyesTightening. Compared kind by kind, and an override carrying a constraint the comparison does not recognise is refused rather than assumed safe.
Add a constraint the base did not carry, such as requiring an identifier form where the base required only presenceyesTightening. Recorded as a composition note, so a reader of a report can see what the derived profile added.
Drop a constraint the base carried, or replace an identifier-form requirement with a bare presence checknoRelaxation, and the one most easily written by accident, because the rule still looks present in the file.
Make a withholdable attribute non-withholdableyesTightening.
Add a new attribute or structural ruleyesExtension proper.
Lower the level, MUST to SHOULDnoRelaxing. Breaks the implication that derived conformance means base conformance.
Widen a constraint or remove a rulenoRelaxing, on the same grounds.
Make a non-withholdable attribute withholdablenoRelaxing.
Redefine what an inherited attribute meansnoNames are global. A profile needing different semantics needs a different attribute.

A profile that genuinely needs to relax a base requirement is not an extension of that base. It is an independent profile, and it should be written and claimed as one. Treating that as a rule rather than as an inconvenience is what keeps conformance claims meaningful.

Two things extension is used for

Extension expresses two different intentions, and conflating them produces profiles that are hard to argue about.

Depth. The derived profile asks for more detail about the same subject matter. The migration profile's relationship to the baseline is of this kind: the same interfaces, described more fully.

Coverage. The derived profile brings more subject matter into scope, at the same level of detail. A profile covering key establishment, later extended by one that adds entity authentication, is of this kind. Here the rules often do not change at all. They are written once and applied to whichever purposes the scope declares, so the two profiles differ by a line of scope rather than by a second set of rules.

Both are monotonic and both are permitted. The distinction matters when a family is planned, because the two are sequenced differently. Depth is added when producers can supply it. Coverage is added when the consumer needs it. Saying which of the two a derived profile is doing saves an argument later about why it exists.

Pinning, ranges and identifiers

Rule identifiers

A rule identifier is local to the profile that declares it. The citable form is the profile's tag followed by the identifier — interface-disclosure#I9 — and nothing shorter names a rule. Three profiles in one family may each declare an I1, and in the worked example three of them do.

The letter says how often the rule is evaluated. It is fixed by the section the rule sits in rather than chosen by the author. P means once per product, I once per declared interface, and G once per entry in a group, with members numbered under their group as G1.2. Numbering restarts at 1 in every profile, at every level of a family.

Two consequences are worth stating plainly.

Identifiers are not reused. Once a version is released, an identifier retired in a later version stays retired, and the numbering carries a gap. The reason is that a conformance report or a stored claim may cite that identifier against a document evaluated under the earlier version. Reusing it would make the old report silently wrong, rather than merely out of date.

Identifiers do not appear in CBOM documents at all. They appear in conformance reports and in claims, which is why they have to be stable and why they have to say which profile they came from. See decision 0011.

Expressing a conformance claim

A claim is the artifact that crosses an organisational boundary: a producer hands it to a consumer who was not present when the evaluation ran, and who may read it months later. It is a machine-readable document with its own schema, and the shape below is the illustrative form — claim-example.json is a real one, over both example profiles at once.

Four properties do the work. A claim is bound to one document by digest, so placing it beside a different CBOM contradicts it. It lists every profile separately, with its own verdict and its whole pinned chain, because a document can conform to one profile and fail another. It carries the disclosure states alongside the verdict, because “conforms” with the implementing library withheld is a different answer from “conforms” with it supplied. And it carries what it does not assert inside itself, rather than by reference. See decision 0015.

Conforms to:
  pkic.example.pqc-migration v0.6            (tag: pqc-migration)
    extending pkic.example.interface-disclosure v0.7   (tag: interface-disclosure)
  pkic.example.interface-disclosure v0.7     (independently evaluated)
Carrier: CycloneDX 1.7
Content revision: 3

The tags are part of the claim rather than decoration: a report attached to it cites rules as pqc-migration#I4, and a reader needs the claim to say which profile that tag belongs to.

A claim that cannot be re-checked is a press release. A consumer holding the claim and the document runs validate_cbom.py <cbom> <claim> --verify-claim, which confirms the digest and re-runs every profile the claim names, reporting where the two disagree. A mismatch exits 5 rather than 1, because it is a finding about the claim and not a verdict on the document — someone holding a bad claim and a good document should evaluate the document, and an exit code reading “does not conform” would send them the wrong way.

What verification cannot establish is that the disclosed values are true. A producer who states TLS 1.3 for an interface actually running TLS 1.2 produces a claim that verifies perfectly. That limitation is in the claim's own notAsserted list, and it always will be. Attestation is a different problem, and implying otherwise would be the most damaging thing this format could do.

Machine-readable form

A derived rules file declares its base and lists only its additions and its tightenings.

{
  "profileId": "pkic.example.pqc-migration",
  "profileTag": "pqc-migration",
  "version": "0.6",
  "extends": { "profileId": "pkic.example.interface-disclosure", "version": "0.7" },
  "overrides": [
    { "id": "interface-disclosure#I9", "level": "MUST", "withholdable": false }
  ],
  "interfaceRules": [ ... numbered from I1 in this profile's own space ... ]
}

The override names its target in full. A bare I9 would be this profile's own ninth interface rule, which is a different rule, so the validator rejects an unqualified override rather than guessing.

A validator loading such a file resolves the base, applies the overrides, and rejects any override that relaxes an inherited rule. That check is worth implementing early, because a relaxing override is easy to write by accident and its effect on a conformance claim is not obvious from reading the file.

What “relaxes” means for a constraint. Comparing obligation levels is easy. Comparing constraints is where the guarantee is actually won or lost, so each kind of constraint is compared on its own terms. A minimum may rise and not fall. A list of permitted values may shrink and not grow. A required prefix may lengthen and not shorten. An override may add an obligation the base did not carry, but may not drop one it did. Changing which attribute a rule is about is not an override at all. It is a different rule, and a derived profile adds it under its own id.

The rule that matters most is what happens to a constraint the comparison does not recognise. The override is refused, rather than assumed to be monotonic. A checker that waves through what it cannot assess produces the same green report as one that has actually checked, and that is the worse of the two failures. See decision 0013.

Conformance pipeline

The validator applies four stages in sequence. The content stages are evaluated only if the format stage accepts the CBOM.

CBOM CycloneDX 1.7 Format gate version band Product rules P1–P4 Interface rules I1–I9 × each Verdict a version below the minimum is refused at this stage
The pipeline is shown interactively in the Demo section, and the version bands are described in the Versioning section.
PKIC CBOM Profiles Working Group · illustrative documentation.