Risk and PQC Scoring Methodology
How CBOM Secure decides that a key is Critical, that a host scores 78, or that an estate is PQC Hybrid. Every rating in the product comes from the rules on this page; none of it is a hidden heuristic.
Where cryptographic judgement comes from
All strength opinion lives in curated ranking tables held as data, not compiled into any report or widget. There are three:
| Table | Keyed on | Example key |
|---|---|---|
| Algorithms | Compound algorithm reference | AES/256, RSA/2048, ECDSA/NISTP384, ML-DSA-65 |
| TLS cipher suites | Suite name | ECDHE-RSA-AES256-GCM-SHA384 |
| SSH algorithms | Role and algorithm | kex:curve25519-sha256 |
Each row carries a strength category and a post-quantum flag:
"AES/256": { "Cat": 4, "PQS": true, "type": "cipher", "comment": "CNSA 2.0 algo" }
Because the tables are data, an administrator can update them as guidance changes — a new algorithm, a revised recommendation, an organisation's own stricter view — without a product release.
Cat — strength category
An integer from 1 to 4. Lower is worse.
Cat | Meaning | Bucket | Examples |
|---|---|---|---|
| 1 | Broken, or below any acceptable margin | Critical | DES/56, AES/128, RSA/1024, MD5, ECDSA/NISTP192 |
| 2 | Acceptable today, insufficient margin | High | AES/192, Ed25519, ECDH/NISTP256 |
| 3 | Sound, but not the target state | Low | RSA/2048, RSA/4096, DH/3072, ECDSA/NISTP256 |
| 4 | Meets the target state | Safe | AES/256, ECDSA/NISTP384, ML-DSA-65, SLH-DSA, ChaCha20 |
PQS — post-quantum safety
A boolean: true if the algorithm is believed to survive a cryptographically relevant quantum computer. It is independent of Cat. AES/256 is Cat 4 and PQ-safe; RSA/4096 is Cat 3 and not.
The rating scale
One scale, used by every criteria, every material type and every widget.
| Level | Bucket | Meaning |
|---|---|---|
| 1 | Critical | Fails outright |
| 2 | High | Insufficient margin |
| 3 | Low | Sound but not target state |
| 4 | Safe | Meets target state |
| — | No Analysis | The criteria cannot be evaluated from what this material stores |
Display order is fixed everywhere: Critical, High, Low, Safe, No Analysis.
There is no "Medium" on this scale. Medium appears only in the composite host score and in the source-code scanner severity ladder, which are different scales measuring different things. Do not read a Medium from one as comparable to a level from the other.
No Analysis is a real answer, not a failure. It means this material does not store what the criteria needs — a key with no recorded storage location cannot be rated on storage location. It is reported rather than guessed, and rather than being silently folded into a risk bucket.
Criteria by material type
Each criteria applies only to the types it can speak for. Anything else is No Analysis by construction.
| Type | Criteria that apply |
|---|---|
| Key | Key Strength, Quantum Safe, Key Reuse, Storage Location |
| Certificate | Certificate Validity, Certificate Expiry, Weak Signature Algorithm, Weak Certificate Key, Self-Signed, Quantum Safe |
| Protocol | Cipher Suite Strength, Cipher Suite Quantum Safe, SSH Key Exchange, SSH Host Key, SSH Cipher, SSH MAC |
| Source code | Algorithm Strength, Quantum Safe |
Key criteria
| Criteria | Rule |
|---|---|
| Key Strength | The Cat of the key's algorithm reference. |
| Quantum Safe | Safe if the algorithm is PQ-safe, Critical if not, No Analysis if the algorithm is not in the table. |
| Key Reuse | Critical if this key's public-key hash appears on more than one key anywhere in the estate; otherwise Safe. No Analysis when the key carries no public-key hash. |
| Storage Location | Safe if the key is held in an HSM; Critical otherwise. No Analysis when the storage location is not recorded. |
Two consequences worth stating plainly:
Key reuse is assessed against the whole population, not one host. A key becomes Critical the moment an unrelated key elsewhere is found to share its public-key hash, so a key's rating can change without that key changing.
Storage Location is a strict HSM test. A file, a keystore or a cloud KMS entry is Critical. That is deliberate — the criteria answers "is this key in dedicated hardware", not "is it reasonably protected".
Certificate criteria
| Criteria | Rule |
|---|---|
| Certificate Validity | Safe if the certificate's lifetime is 398 days or fewer; Critical otherwise. |
| Certificate Expiry | Safe if 30 or more days remain; Critical otherwise. |
| Weak Certificate Key | The Cat of the subject public key's algorithm. |
| Quantum Safe | The PQ-safety of the subject public key's algorithm. |
| Self-Signed | Critical if issuer and subject are identical; otherwise Safe. |
| Weak Signature Algorithm | Critical if the signature algorithm contains a weak primitive; otherwise Safe. |
Both date-based criteria report No Analysis when a date is missing or unparseable rather than assuming a default.
The 398-day rule is the CA/Browser Forum maximum TLS certificate lifetime. A certificate issued for longer is Critical whatever its algorithm.
Weak primitive list: MD2, MD4, MD5, SHA-1, Blowfish, 3DES, DES, RC4, RC2.
Signature algorithms are matched on normalised tokens rather than by equality, because sensors report full identifiers — sha1WithRSAEncryption, ecdsa-with-SHA256, SHA1_RSA — and never a bare digest name. Matching is bounded so that sha1 does not match a longer name that merely begins with it, and des does not match inside 3des.
Protocol criteria
An endpoint is only as strong as the weakest thing it will negotiate. Every advertised algorithm is rated and the worst result is the endpoint's rating.
| Criteria | Rule |
|---|---|
| Cipher Suite Strength | The worst Cat across every advertised suite that the table rates. |
| Cipher Suite Quantum Safe | Safe only if every rated suite is PQ-safe; Critical otherwise. |
| SSH Key Exchange | Worst Cat across the advertised key-exchange algorithms. |
| SSH Host Key | Worst Cat across the advertised host-key algorithms. |
| SSH Cipher | Worst Cat across the advertised ciphers. |
| SSH MAC | Worst Cat across the advertised MAC algorithms. |
Quantum safety here is a conjunction: one classical algorithm still on offer is enough to fail it.
SSH negotiates four independent algorithm lists, which is why it has four separate criteria where TLS has one. The four SSH criteria are No Analysis for a TLS endpoint by design — a TLS suite has no separately negotiated MAC or host key to rate. Selecting an SSH criteria therefore narrows the reported population to endpoints that actually carry SSH handshake data, so that TLS endpoints do not swamp the chart with No Analysis.
Protocol-extension signals advertised inside the SSH key-exchange list are not algorithms and are excluded from every rating and chart. An endpoint whose advertised algorithms are all unknown to the table is No Analysis; nothing is guessed.
Source-code criteria
A source-code record is a file, and its algorithms sit one per finding. It is therefore scored per finding, not per file.
| Criteria | Rule |
|---|---|
| Algorithm Strength | The Cat of the algorithm resolved at that call site. |
| Quantum Safe | The PQ-safety of that algorithm. |
Only two criteria apply: a call site says nothing about where a key is stored or whether it is reused.
Consequences, declared rather than hidden:
A file with thirty findings contributes thirty units — thirty table rows, and thirty to a chart bar.
A file with no findings contributes nothing, not a No Analysis row. A file the scanner found no cryptography in is not unrated material; it is not material.
Every source-code row still addresses the file's record, so two rows from one file share an identifier.
Responses state the counting unit — documents, findings, or both — so a number is never ambiguous about what it counted.
Source-code results are scoped to the newest scan of each repository. Repeated scans of one repository would otherwise count it once per scan it has ever had.
Host and enterprise scoring
This is the only place per-material levels are rolled up into a 0-100 score. It is used by the host risk chart and the host and enterprise analysis endpoints.
Step 1 — level histogram
Every scored record is attributed to its host. For each host and each criteria, count how many records landed at each level.
The denominator is every document on the host, not only those this criteria could rate. So the percentages for a criteria that speaks for a small slice of a host legitimately sum to less than 100. This is intentional — it dilutes a criteria with narrow coverage — but a reader must interpret it that way.
A Critical key-reuse contribution is counted once per host per key hash. Repeated copies of the same reused key on one host do not multiply the penalty.
Step 2 — the score
With L₁ to L₄ as the percentage of the host's documents at each level:
at_risk_percent = L1 + L2 + L3 # everything not Safe
base_score = L1 x 1.0 + L2 x 0.7 + L3 x 0.2
at_risk_bonus = 20 if at_risk_percent >= 70
= 12 if at_risk_percent >= 50
= 0 otherwise
density_bonus = d1 + d2 where
d1 = 15 if L1 >= 30 ; 10 if L1 >= 20 ; 5 if L1 >= 10 ; else 0
d2 = 10 if L2 >= 50 ; 7 if L2 >= 30 ; 5 if L2 >= 20 ; else 0
raw_score = base_score + at_risk_bonus + density_bonus
final_score = raw_score if raw_score <= 80
= 80 + (raw_score - 80) / 2 if raw_score > 80
final_score = min(final_score, 100)
Reading the weights: level 1 counts in full, level 2 at 70 per cent, level 3 at 20 per cent, level 4 not at all. The two bonuses then penalise breadth — a lot of the estate is at risk — and density — a lot of it is at the worst level. The compression above 80 stops the top of the scale saturating: a host has to be badly wrong in more than one way to reach 100.
Step 3 — score to criticality
Critical if score >= 71
High if score >= 41
Medium if score >= 21
Low if score >= 1
Safe otherwise
This five-bucket ladder includes Medium and is a different scale from the per-material one. A host at Medium is not a material at some level between High and Low; it is a composite.
A host's overall criticality is the band of the mean final score across every criteria scored on it. A host that appeared in the population but for which no criteria produced any level at all is reported as No Analysis, not as Safe.
Worked example
A host with 10 documents. Key Strength produced 3 Critical, 2 High, 1 Low, 4 Safe.
L = [30.0, 20.0, 10.0, 40.0]
at_risk = 30 + 20 + 10 = 60.0
base = 30x1.0 + 20x0.7 + 10x0.2 = 46.0
at_risk_bonus = 60 is >= 50 and < 70 = 12
density = L1 30 >= 30 -> 15 ; L2 20 >= 20 -> 5 = 20
raw = 46 + 12 + 20 = 78.0
final = 78 <= 80, so unchanged = 78
criticality = 78 >= 71 = Critical
Crypto-agility scoring
Agility answers a different question from criticality: not "how weak is this host" but "how readily could it move".
The population is keys and certificates that carry both a host and an algorithm reference the table rates. For each host, take the set of distinct algorithms present. With n distinct algorithms, p of them PQ-safe, q = n - p not, and T the number of PQ-safe algorithms in the whole table:
PQC_score = p / n x 100
Hybrid_score = p / n x 100
Variety_score = min(100, p / T x 100)
score = 0.5 x PQC_score + 0.3 x Hybrid_score + 0.2 x Variety_score
penalties:
if p == 0: score -= 50 # nothing PQ-safe at all
else: score -= 5 x q # 5 per distinct non-PQ-safe algorithm
if any algorithm present has Cat 1: score -= 20
score = clamp(score, 0, 100)
The flat 50 and the per-algorithm penalty are mutually exclusive: a host with nothing PQ-safe takes the flat penalty, not both.
| Score | Statement |
|---|---|
| 81-100 | High crypto-agility |
| 51-80 | Partial crypto-agility |
| 31-50 | Low crypto-agility |
| 0-30 | No agility |
| No rated algorithms | No Data |
Agility runs good-to-bad, so its bands take the severity colours in reverse: best is green, worst is red. Enterprise agility is the mean host score across every host with rated algorithms.
PQC posture classification
Here the unit is the host, not the material. For each host, collect the PQ-safety flag of every rated thing in scope — the distinct algorithms on its keys and certificates, and the distinct cipher suites on its endpoints — then:
no flags at all -> No Analysis
every flag true -> PQC-Safe
at least one true and at least one false -> PQC Hybrid
all false, and any Cat 1 present -> Critical
all false, none Cat 1 -> Vulnerable
Fixed output order: Critical, Vulnerable, PQC Hybrid, PQC-Safe, No Analysis.
A matched row with no strength category is treated as Cat 1, so an unrated-but-matched algorithm lands in Critical rather than quietly improving the picture.
The per-type PQC chart can be filtered to high-risk types only, which shows a type's chart when Critical and Vulnerable hosts together reach 30 per cent of that type's hosts. That is the default, so a type where posture is already good does not occupy space.
Point-in-time analysis
Time-series widgets report the posture as it stood at each point, rather than applying today's rating to yesterday's data. Three rules govern this:
A material's state is inherited across quiet intervals. A material that did not change between two scans held its previous state throughout, and is reported that way rather than disappearing from the series.
Resolved and reactivated transitions are honoured. A material resolved in March does not contribute to April, and one reactivated in May contributes again from May.
Population-derived criteria — key reuse in particular — are recomputed at each point, because a key's reuse rating depends on what else existed at that time, not on what exists now.
Scoring and policy are different questions
Criticality asks "how strong is this, on our scale". Policy asks "is this permitted by a named standard". They use the same ranking data but answer independently: a material can be Low criticality and still Fail a policy that requires the target state, and a material can be Safe and still Fail a policy that mandates a specific algorithm family. Use criticality to prioritise remediation and policy to demonstrate conformance. The shipped baselines are listed in the Built-in Standards catalogue.