feat(cryptography): add cryptographic agility plane to CBOM#947
Conversation
Optional cryptoProperties.agility (configurationSource, configurationRef, changeMechanism) plus certificate renewal and key rotation objects backed by a shared lifecycleAutomation enum. Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
|
As discussed in yesterday's CBOM WG meeting, I updated the proposal to move the "agility" object up to the component level, so other components can use the change-management properties too. I also unified the objects describing certificate renewal and related-crypto-material rotation (keys, tokens, passwords, etc.) into a single shared type. |
Mehrn0ush
left a comment
There was a problem hiding this comment.
Hi,
I really like the direction of this PR, especially the move of agility to the component level and the shared lifecycleControl shape for certificate renewal and crypto-material rotation.
The inline comments I left are mostly questions about how producers and consumers may interpret these fields in practice.
While reading through this, I was wondering whether the distinction between current deployed state, supported capability, and intended target state belongs somewhere in this scope, or whether it is better handled as follow-up work. My current reading is that these fields describe the current component or cryptographic asset and how its current configuration can be changed, while PQC transition plans, target algorithms, or future migration states would be represented elsewhere. Making that boundary explicit might help consumers avoid interpreting values such as runtime-config or software-update as evidence that a specific PQC or hybrid target is already supported.
I was also thinking about the difference between “this can technically be changed” and “this change is actually under the operator’s control.” For PQC readiness, that distinction seems important. Two assets may both require a software-update, but one may be updateable in-house while the other depends on a vendor firmware roadmap. Similarly, runtime-config does not necessarily mean that a PQC or hybrid target is available.
Maybe this is outside the intended scope of this PR, but would it make sense to add, or at least plan as follow-up, lightweight references from agility to control/authority, target migration state, and evidence/mitigation objects? That could keep this PR compact while making the agility plane more directly useful for PQC readiness and audit workflows.
A compact 2.0 example would also be very helpful, especially one showing TLS policy/configurationRef, negotiated selection, ACME certificate renewal, and KMS-backed key/material rotation.
Also, out of curiosity, are the bundled 2.0 schemas expected to be regenerated in this PR, or are they handled separately by automation? I see the new agility, renewal, rotation, and lifecycleControl definitions in the modular model schemas, but I do not see them yet in schema/2.0/cyclonedx-2.0-bundled.schema.json or the minified bundle. If bundled schemas are intended to stay in sync with model schema changes, validators using the bundled schema may not accept BOMs using the new fields?.
| "configurationSource": { | ||
| "type": "string", | ||
| "title": "Configuration Source", | ||
| "description": "Describes how this component's configuration was determined, ordered from least to most agile.", |
There was a problem hiding this comment.
One question I had while reading this: the description says these values are “ordered from least to most agile.” Could this be softened unless consumers are expected to treat enum order as normative?
Some values seem to describe configuration origin or authority, while “negotiated” describes runtime selection. For example, a TLS deployment may have an administrator- or policy-managed set of allowed algorithms, while the final selection is negotiated at runtime. A short note on how producers should choose a value in that case would help avoid inconsistent modeling.
There was a problem hiding this comment.
Good points. They are ordered "roughly" from least to most agile. I think adding this word makes it less strict.
Some values seem to describe configuration origin or authority, while “negotiated” describes runtime selection. For example, a TLS deployment may have an administrator- or policy-managed set of allowed algorithms, while the final selection is negotiated at runtime. A short note on how producers should choose a value in that case would help avoid inconsistent modeling.
Agreed, "negotiated" is kind of orthogonal, so might be well a separate property (boolean).
There was a problem hiding this comment.
Updated the PR accordingly.
| "automation": { | ||
| "type": "string", | ||
| "title": "Automation", | ||
| "description": "The degree of automation with which the operation is performed, ordered from least to most agile.", |
There was a problem hiding this comment.
I like the shared lifecycleControl shape. Would it be useful to clarify that automation captures the degree of automation, while mechanism carries the concrete renewal or rotation method?
For example, is the intended modeling pattern something like:
- automatic + mechanism: "ACME"
- automatic + mechanism: "AWS KMS (provider-managed)"
- manual + mechanism: "M-of-N key ceremony"
- automatic or on-demand + mechanism: "ephemeral session key"
I think a short note like this would keep the enum compact while still giving implementers guidance for the additional cases discussed in #892, such as provider-managed rotation, protocol-driven renewal, quorum ceremonies, and ephemeral material.
There was a problem hiding this comment.
Added some notes to the description accordingly.
There was a problem hiding this comment.
Thanks, great.
It seems a small wording nit left in the meta:enum text for other/unknown still refers to “mechanism”. Since this enum describes automation, maybe “Another automation mode applies” / “The automation mode is not known” would be slightly clearer.
| "changeMechanism": { | ||
| "type": "string", | ||
| "title": "Change Mechanism", | ||
| "description": "Describes how a change to this component's configuration is applied, ordered from least to most agile.", |
There was a problem hiding this comment.
One more question: is changeMechanism intended to capture the type of change required, the way the change becomes active, or the least disruptive supported path?
Some values describe what must be changed, such as hardware-replacement, firmware-update, or software-update, while others describe operational impact, such as restart-required or runtime-config.
Maybe a short note could help producers model common cases consistently, for example a software update that also requires a restart, or a TLS configuration reload that does not require a full process restart. If multiple steps apply, would the intended pattern be to record the least disruptive supported path for the intended change and use configurationRef or evidence for additional context?
There was a problem hiding this comment.
Thinking about it there may be multiple steps involved in changing e.g., an algorithm (e.g., software update & updating a hardware accelerator), so we might want to convert this to "changeMechanisms", an array that includes several options.
There was a problem hiding this comment.
That makes sense to me. An array would capture the multi-step cases much better, especially when a change involves both an implementation/update step and an activation step.
One small thing that may be worth clarifying if it becomes changeMechanisms: would the array represent all required steps, all supported options, or the minimum viable path for the intended change? For example, software-update + restart-required would mean something different from software-update OR runtime-config.
There was a problem hiding this comment.
One small thing that may be worth clarifying if it becomes changeMechanisms: would the array represent all required steps, all supported options, or the minimum viable path for the intended change? For example, software-update + restart-required would mean something different from software-update OR runtime-config.
I think it would be a "change mechanism consisting of potentially multiple required steps". So the name could remain changeMechanism and we add a clarifying explanation.
There was a problem hiding this comment.
Yes, that makes sense. A note that the mechanism may involve multiple required steps would make the intended interpretation clear without implying alternatives.
There was a problem hiding this comment.
Updated the PR accordingly.
There was a problem hiding this comment.
Thanks, this all looks good to me and matches what we discussed.
| "title": "Configuration Reference", | ||
| "description": "The bom-ref of the configuration that determines this component's configuration. Typically points to a component of type 'data' whose data type is 'configuration'." | ||
| }, | ||
| "changeMechanism": { |
There was a problem hiding this comment.
This should ideally be an array
Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
Mehrn0ush
left a comment
There was a problem hiding this comment.
Looks good to me. Thanks for addressing the comments.
Summary
This adds the cryptographic "agility plane" outlined in #892. It records how a cryptographic asset's configuration was set, how that configuration can be changed, and how keys and certificates are rotated and renewed, so that crypto-agility and PQC migration readiness can be expressed in a CBOM.
This covers the three observable dimensions raised in the issue: configuration source, change mechanism, and rotation/renewal. Everything is optional, so existing CBOMs stay valid.
What's added
A new
cryptoProperties.agilityobject that applies to any asset type:configurationSource: how the configuration was determined, roughly ordered from least to most agile:hardcoded,product-default,administrator-configured,policy-managed,negotiated(plusother,unknown).configurationRef: a bom-ref to the configuration that drives this setting, typically adatacomponent whose data type isconfiguration.changeMechanism: how a change gets applied, ordered from least to most agile:not-possible,hardware-replacement,firmware-update,software-update,restart-required,runtime-config(plusother,unknown).A shared
lifecycleAutomationenum for the degree of automation, ordered from least to most agile:not-supported,manual,on-demand,automatic(plusother,unknown).Two per-domain lifecycle objects:
certificateProperties.renewal={ automation, mechanism }, whereautomationis alifecycleAutomationvalue andmechanismis a free-form string (e.g.ACME,EST,SCEP,CMP,CMC).relatedCryptoMaterialProperties.rotation={ automation, mechanism }, wheremechanismis a free-form string (e.g.KMIP,PKCS#11,AWS KMS,Google Cloud KMS,Azure Key Vault,HashiCorp Vault Transit).Design notes
otherandunknownfollow the usual CycloneDX convention.mechanismfields are free-form strings with examples rather than enums, since rotation mechanisms in particular vary a lot (protocols, interfaces, managed services). The name follows the existingsecuredBy.mechanism.configurationSourceandchangeMechanismlive on oneagilityobject instead of being repeated per asset type, because they apply equally to algorithms, protocols, certificates, and keys.Other agility aspects
Originally posted by @stevespringett in #892
Backwards compatibility
Fully additive; no breaking changes.
Refs #892