365Architect

CNSA 2.0 Validator — Compliance Validation Engine

The CNSA 2.0 Validator is the compliance verification engine that evaluates cryptographic assets (CBOMs) against the NSA's Commercial National Security Algorithm Suite 2.0 (CNSA 2.0) requirements. It produces binary verdicts, per-asset classifications, gap analyses, and timeline-aware roadmaps — all driven by Knowledge Base profiles.


Table of Contents

  1. What It Does
  2. Why It's Needed
  3. Architecture Overview
  4. Installation
  5. How to Run / Use
  6. User Manual
  7. Developer Manual
  8. Code Examples
  9. API Reference
  10. Configuration Options
  11. Value Showcase

What It Does

The CNSA 2.0 Validator takes a CBOM (Cryptography Bill of Materials) and evaluates every cryptographic asset against the CNSA 2.0 profile:

Capability Description
Profile Factory CnsaProfileFactory programmatically defines the CNSA 2.0 profile as KB-encoded data — no hardcoded checks
Validator Engine CnsaValidator iterates all CBOM components and classifies each asset
Per-Asset Verdicts Each asset receives a Compliant, NonCompliant, or Indeterminate verdict with detailed reasoning
Gap Analysis Non-compliant and indeterminate assets generate CnsaGapItem entries with requirements, deadlines, and recommended actions
Timeline Awareness Validates against CNSA 2.0's phased deadlines: Procurement (2027), Key Establishment (2030), General Phase-Out (2033), NSM-10 Goal (2035)
Fail-Safe for Unknown Algorithms Any algorithm not recognized by the Knowledge Base yields Indeterminatenever a silent pass
Low-Confidence Flagging Assets detected with Low confidence are flagged separately for manual review
Reproducible Evidence Each validation run produces a CnsaEvidence record for audit trails
Certificate Validation Validates certificate signing algorithms against CNSA 2.0 requirements
Parameter Set Checking Enforces CNSA 2.0 minimum parameter sets: ML-KEM-1024 (not 512/768), ML-DSA-87 (not 44/65), AES-256 (not 128/192)

CNSA 2.0 Approved Algorithms

Algorithm Role FIPS Standard Status
ML-KEM-1024 Key Encapsulation FIPS 203 ✅ Required
ML-DSA-87 Digital Signature FIPS 204 ✅ Required
AES-256 Symmetric Encryption FIPS 197 ✅ Required
SHA-384 Hash FIPS 180-4 ✅ Approved
SHA-512 Hash FIPS 180-4 ✅ Approved
LMS Firmware/Software Signing NIST SP 800-208 ✅ Approved
XMSS Firmware/Software Signing NIST SP 800-208 ✅ Approved

Why It's Needed

The Problem

National Security Systems (NSS) and organizations handling classified or sensitive data must comply with CNSA 2.0 timelines:

  • 2027: All new software/firmware signing must use CNSA 2.0
  • 2030: All new key establishment must transition to quantum-safe
  • 2033: All remaining systems must be migrated
  • 2035: NSM-10 full compliance goal

Without automated validation:

  • Manual code reviews miss cryptographic assets buried in dependencies
  • Teams don't know which algorithms they need to migrate and by when
  • Unknown algorithms (e.g., from third-party libraries) silently pass reviews
  • Parameter set violations (using ML-KEM-768 instead of ML-KEM-1024) go undetected
  • There's no reproducible evidence of compliance status for auditors

The Value Proposition

Stakeholder Benefit
ISSOs / ISSMs Binary compliant/non-compliant verdict with evidence suitable for RMF packages
System Architects Gap analysis shows exactly which assets need migration, why, and by when
Developers Per-asset verdicts with recommended PQC targets — no crypto expertise required
Compliance Officers CNSA 2.0 timeline awareness with phased deadline tracking
Auditors Reproducible evidence. Run the same CBOM through the validator — same result every time.

The CNSA 2.0 Validator turns a 200-page advisory into an automated, per-asset compliance decision that runs in milliseconds.


Architecture Overview

Rendering diagram...

Verdict Decision Tree

For each CBOM component:
│
├── Asset is a Certificate?
│   ├── Signature algo is RSA/ECDSA/DSA? → NonCompliant
│   └── Otherwise → Compliant
│
├── Algorithm is in CNSA 2.0 approved list?
│   ├── Parameter check: meets ML-KEM-1024/ML-DSA-87/AES-256 minimum?
│   │   ├── Yes → Compliant (with low-confidence flag if applicable)
│   │   └── No  → NonCompliant (parameter set too low)
│   └── Not in approved list
│
├── Algorithm is known to be CNSA-excluded?
│   └── NonCompliant (excluded: RSA, ECDSA, SLH-DSA, DES, MD5, low param sets)
│
├── Algorithm is known in KB (but not CNSA-approved)?
│   └── NonCompliant (known, needs review)
│
└── Algorithm is completely unknown to KB?
    └── Indeterminate (FAIL-SAFE: never a silent pass)

Installation

The CNSA 2.0 Validator is part of CipherShift365.Core.Analysis:

BASH
dotnet add package CipherShift365.Core.Analysis
XML
<PackageReference Include="CipherShift365.Core.Analysis" Version="1.0.0" />

Dependencies

CipherShift365.Core.Analysis
  ├── CipherShift365.Core.Runtime (KB types, contracts, CBOM model)
  ├── Microsoft.CodeAnalysis.CSharp (Roslyn source analysis)
  ├── Microsoft.CodeAnalysis.CSharp.Workspaces
  └── Microsoft.Extensions.Logging.Abstractions

Targets net10.0.


How to Run / Use

Quick Start: Validate a CBOM

CSHARP
using CipherShift365.Core.Runtime;
using CipherShift365.Core.Analysis;
using CipherShift365.Core.Analysis.Cnsa;

// 1. Load the Knowledge Base
var loader = new KbLoader(encryptionKey, signingKey);
var result = loader.Load(File.ReadAllBytes("kb.cskb"));
var kb = new SignedKnowledgeBase(result.Content!);

// 2. Create the CNSA 2.0 profile
var (profile, entries, timeline) = CnsaProfileFactory.Create();

// 3. Run an analysis to produce a CBOM (or load one)
var analysisEngine = new AnalysisEngine(new RiskModel());
var ctx = new AnalysisContext("./src/MyApp", kb, new IdentityService());
var analysis = await analysisEngine.AnalyzeAsync(ctx);

// 4. Validate against CNSA 2.0
var validator = new CnsaValidator(kb, profile, timeline);
var validationResult = validator.Validate(analysis.Cbom!);

// 5. Inspect the results
Console.WriteLine($"Overall: {validationResult.OverallVerdict}");
Console.WriteLine(validationResult.Summary);

Standalone Validation

CSHARP
// If you already have a CBOM (e.g., from a file)
var cbom = CbomSerializer.Deserialize<Cbom>(json);

var (profile, _, timeline) = CnsaProfileFactory.Create();
var validator = new CnsaValidator(kb, profile, timeline);
var result = validator.Validate(cbom);

// Check the verdict
if (result.OverallVerdict == CnsaVerdict.Compliant)
    Console.WriteLine("PASS: All crypto assets are CNSA 2.0 compliant.");
else if (result.OverallVerdict == CnsaVerdict.NonCompliant)
    Console.WriteLine($"FAIL: {result.AssetVerdicts.Count(a => a.Verdict == CnsaVerdict.NonCompliant)} non-compliant assets.");
else
    Console.WriteLine($"INDETERMINATE: {result.IndeterminateCount} assets need manual review.");

User Manual

Understanding the Verdicts

Compliant

The algorithm is on the CNSA 2.0 approved list and meets all parameter set requirements. Example:

Algorithm: ML-KEM-1024
Verdict: Compliant
Reason: Algorithm 'ML-KEM-1024' is CNSA 2.0 approved for Key Establishment.

NonCompliant

The algorithm is known and explicitly not compliant. Examples:

Algorithm: RSA
Verdict: NonCompliant
Reason: Algorithm 'RSA' is NOT CNSA 2.0 approved.
Requirement: CNSA 2.0 algorithm approval
Deadline: 2033-01-01
PqcTarget: ML-DSA-87

Algorithm: ML-KEM-768
Verdict: NonCompliant
Reason: ML-KEM variant is CNSA 2.0 approved but parameter set 'ML-KEM-768' is too low.
Requirement: CNSA 2.0: parameter set minimum
PqcTarget: ML-KEM-1024

Indeterminate (Fail-Safe)

The algorithm is not recognized by the Knowledge Base. The validator refuses to pass it. Example:

Algorithm: CustomCryptoV3
Verdict: Indeterminate
Reason: Algorithm 'CustomCryptoV3' is not recognized — manual review required.
Requirement: CNSA 2.0: unclassified algorithm

This is a critical security property: unknown does not mean safe. An attacker who introduces a novel or obfuscated algorithm cannot hide behind a silent pass.

CNSA 2.0 Timeline

Milestone Deadline Description
Procurement Gate 2027-01-01 All new software/firmware signing must use CNSA 2.0 approved algorithms
Key Establishment 2030-01-01 All new key establishment (KEM) must transition to ML-KEM-1024
General Phase-Out 2033-01-01 All remaining systems must be migrated to CNSA 2.0
NSM-10 Goal 2035-01-01 NSM-10 National Security Systems full compliance

The validator maps each asset to its relevant deadline based on its cryptographic role:

  • Signature assets → Procurement Gate (2027)
  • Key Establishment assets → Key Establishment deadline (2030)
  • All others → General Phase-Out (2033)

Gap Analysis Output

Each non-compliant asset generates a CnsaGapItem:

CSHARP
foreach (var gap in result.Gaps)
{
    Console.WriteLine($"Asset: {gap.AssetIdentifier}");
    Console.WriteLine($"  Algorithm: {gap.Algorithm}");
    Console.WriteLine($"  Gap: {gap.GapDescription}");
    Console.WriteLine($"  Requirement: {gap.Requirement}");
    Console.WriteLine($"  Action: {gap.RecommendedAction}");
    Console.WriteLine($"  Deadline: {gap.Deadline}");
}

This bridges the gap from "we're non-compliant" to "here's exactly what to fix, by when, and how."

Low-Confidence Flagging

When the analysis engine detects a crypto asset with Low confidence, the CNSA Validator flags it:

Algorithm: ML-KEM-1024
Verdict: Compliant
Reason: Algorithm 'ML-KEM-1024' is CNSA 2.0 approved for Key Establishment. [FLAGGED: low-confidence finding — verify manually]

The CnsaValidationResult includes LowConfidenceFlaggedCount so you can track how many assets need manual verification even if they pass automated checks.


Developer Manual

Class Hierarchy

CnsaProfileFactory (static)
  ├── ProfileName: "CNSA 2.0"
  ├── ProfileVersion: "2024-09"
  ├── ProfileSource: "CNSSP-15 Annex B / NSA CNSA 2.0 Advisory"
  └── Create() → (ComplianceProfile, IReadOnlyList<KbEntry>, IReadOnlyList<CnsaTimelineEntry>)

CnsaValidator
  ├── Constructor: IKnowledgeBase, ComplianceProfile, IReadOnlyList<CnsaTimelineEntry>
  ├── Validate(Cbom) → CnsaValidationResult
  ├── (private) ComputeOverallVerdict()
  ├── (private) EvaluateAsset() → AssetEvaluation
  ├── (private) EvaluateCertificate() → AssetEvaluation
  ├── (private) CheckParameters() → (verdict, reason, requirement)
  ├── (private) IsCnsaExcluded() → bool
  ├── (private) MapAlgorithmToRole() → string
  ├── (private) GetRelevantDeadline() → string?
  ├── (private) GetPqcTarget() → string?
  └── (private) GetRecommendedAction() → string?

CnsaValidationResult (record)
  ├── OverallVerdict: CnsaVerdict
  ├── AssetVerdicts: IReadOnlyList<CnsaAssetVerdict>
  ├── Gaps: IReadOnlyList<CnsaGapItem>
  ├── Evidence: CnsaEvidence
  ├── Timeline: IReadOnlyList<CnsaTimelineEntry>
  ├── Summary: string
  ├── IndeterminateCount: int
  └── LowConfidenceFlaggedCount: int

CnsaAssetVerdict (record)
  ├── AssetIdentifier, Algorithm, Verdict, Reason
  └── Requirement?, Deadline?, Confidence?, PqcTarget?

CnsaGapItem (record)
  ├── AssetIdentifier, Algorithm, GapDescription, Requirement
  └── RecommendedAction?, Deadline?

CnsaEvidence (record)
  ├── ProfileName, ProfileVersion, KbVersion
  ├── EvaluatedAt, DrivingAssets, ProfileSource

CnsaTimelineEntry (record)
  ├── Category, Deadline, Description

CnsaVerdict (enum)
  ├── Compliant
  ├── NonCompliant
  └── Indeterminate

The Validation Algorithm (Detailed)

Validate(Cbom cbom):
  assetVerdicts = []
  gaps = []
  drivingAssets = []
  indeterminateCount = 0
  lowConfidenceCount = 0

  for each component in cbom.Components:
    if component.CryptoProperties is null → skip (not a crypto asset)

    assetId = component.BomRef ?? component.Name
    algorithm = component.Name
    confidence = extract from component.Properties (CipherShiftAnnotations.PropConfidence)

    if confidence == Low → lowConfidenceCount++

    eval = EvaluateAsset(algorithm, cryptoProperties, confidence)

    if eval.IsIndeterminate → indeterminateCount++

    deadline = GetRelevantDeadline(cryptoProperties)  // Timelines-aware
    pqcTarget = GetPqcTarget(algorithm)

    assetVerdicts += new CnsaAssetVerdict(assetId, algorithm, eval.Verdict, eval.Reason,
        eval.Requirement, deadline, confidence, pqcTarget)

    if eval.Verdict != Compliant:
      gaps += new CnsaGapItem(assetId, algorithm, eval.Reason, eval.Requirement,
          GetRecommendedAction(algorithm, cryptoProperties), deadline)

  overallVerdict = ComputeOverallVerdict(assetVerdicts)
  // NonCompliant > Indeterminate > Compliant (worst-case wins)

  evidence = new CnsaEvidence(profile.Name, profile.Version, kb.Version,
      UtcNow, drivingAssets, CnsaProfileFactory.ProfileSource)

  return new CnsaValidationResult(overallVerdict, assetVerdicts, gaps, evidence,
      timeline, summary, indeterminateCount, lowConfidenceCount)

Fail-Safe Implementation

The critical fail-safe is the last branch of EvaluateAsset:

CSHARP
// If algorithm is not in approved list, not excluded, and not in KB:
return new AssetEvaluation(CnsaVerdict.Indeterminate,
    $"Algorithm '{algorithm}' is not recognized — manual review required.",
    "CNSA 2.0: unclassified algorithm", isIndeterminate: true);

There is no code path that returns Compliant for an unrecognized algorithm. This prevents:

  1. Novel attacks using custom crypto implementations
  2. Typos or mis-identified algorithms slipping through
  3. New NIST finalists that haven't been added to the KB yet (they'll be flagged, not silently approved)

The IsIndeterminate flag on AssetEvaluation is used for counting but does not affect verdict computation — all indeterminate assets are counted and included in the summary.

Overall Verdict Computation

CSHARP
static CnsaVerdict ComputeOverallVerdict(IReadOnlyList<CnsaAssetVerdict> assets)
{
    if (assets.Count == 0) return CnsaVerdict.Compliant;
    if (assets.Any(a => a.Verdict == CnsaVerdict.NonCompliant)) return CnsaVerdict.NonCompliant;
    if (assets.Any(a => a.Verdict == CnsaVerdict.Indeterminate)) return CnsaVerdict.Indeterminate;
    return CnsaVerdict.Compliant;
}

Priority: NonCompliant > Indeterminate > Compliant. One non-compliant asset makes the entire system non-compliant.

Adding a New CNSA-Excluded Algorithm

CSHARP
// In CnsaValidator.IsCnsaExcluded(), add a new case:
private static bool IsCnsaExcluded(string algorithm)
{
    var upper = algorithm.ToUpperInvariant();
    return upper switch
    {
        // ... existing cases ...
        var a when a.StartsWith("CHACHA", StringComparison.Ordinal) => true, // NEW
        _ => false
    };
}

// Add the corresponding KB entry in CnsaProfileFactory.Create()
new("ChaCha20", CryptoRole.Symmetric, RiskLevel.QuantumVulnerable,
    Description: "Not CNSA 2.0 approved. Use AES-256.",
    StandardsReferences: new[] { "CNSA 2.0" },
    MigrationNotes: "Replace with AES-256-GCM.")

Data-Driven Design

All CNSA 2.0 rules are defined in CnsaProfileFactory.Create(), not hardcoded in the validator:

CSHARP
// ✅ Data-driven: the approved list is in the KB profile
var profile = new ComplianceProfile("CNSA 2.0", "2024-09",
    new[] { "ML-KEM-1024", "ML-DSA-87", "AES-256", "SHA-384", "SHA-512", "LMS", "XMSS" },
    RiskLevel.QuantumSafe);

// ❌ Anti-pattern avoided: no hardcoded lists in the validator
// if (algo == "ML-KEM-1024" || algo == "ML-DSA-87") ...

This means updating the CNSA guidance requires updating the KB, not the validator code.

Thread Safety

  • CnsaValidator is stateless after construction. Thread-safe for concurrent Validate() calls.
  • CnsaProfileFactory.Create() is a static method with no side effects. Thread-safe.
  • All result types (CnsaValidationResult, CnsaAssetVerdict, CnsaGapItem, CnsaEvidence) are immutable records.

Code Examples

Example 1: Full Compliance Pipeline

CSHARP
// Build the CNSA 2.0 profile
var (profile, entries, timeline) = CnsaProfileFactory.Create();

// Run analysis to produce a CBOM
var kb = new SignedKnowledgeBase(content);
var engine = new AnalysisEngine(new RiskModel());
var context = new AnalysisContext("./src", kb, new IdentityService());
var analysis = await engine.AnalyzeAsync(context);

// Validate
var validator = new CnsaValidator(kb, profile, timeline);
var result = validator.Validate(analysis.Cbom!);

// Print results
Console.WriteLine($"CNSA 2.0 Validation: {result.OverallVerdict}");
Console.WriteLine(result.Summary);
Console.WriteLine($"  Compliant: {result.AssetVerdicts.Count(a => a.Verdict == CnsaVerdict.Compliant)}");
Console.WriteLine($"  Non-Compliant: {result.AssetVerdicts.Count(a => a.Verdict == CnsaVerdict.NonCompliant)}");
Console.WriteLine($"  Indeterminate: {result.IndeterminateCount}");
Console.WriteLine($"  Low Confidence: {result.LowConfidenceFlaggedCount}");

if (result.Gaps.Count > 0)
{
    Console.WriteLine("\n--- GAP ANALYSIS ---");
    foreach (var gap in result.Gaps)
        Console.WriteLine($"  [{gap.Deadline ?? "N/A"}] {gap.AssetIdentifier}: {gap.GapDescription}");
}

Console.WriteLine("\n--- TIMELINE ---");
foreach (var t in result.Timeline)
    Console.WriteLine($"  {t.Deadline:yyyy-MM-dd} — {t.Category}: {t.Description}");

Example 2: Per-Asset Migration Roadmap

CSHARP
var result = validator.Validate(cbom);

Console.WriteLine("=== CNSA 2.0 Migration Roadmap ===\n");

// Sort non-compliant assets by deadline
var needsMigration = result.AssetVerdicts
    .Where(a => a.Verdict != CnsaVerdict.Compliant)
    .OrderBy(a => a.Deadline);

foreach (var asset in needsMigration)
{
    Console.WriteLine($"📦 {asset.AssetIdentifier}");
    Console.WriteLine($"   Algorithm: {asset.Algorithm}");
    Console.WriteLine($"   Verdict:   {asset.Verdict}");
    Console.WriteLine($"   Reason:    {asset.Reason}");
    Console.WriteLine($"   Migrate to: {asset.PqcTarget ?? "manual review needed"}");
    Console.WriteLine($"   Deadline:  {asset.Deadline ?? "unknown"}");
    Console.WriteLine();
}

// Summary for leadership
var byDeadline = needsMigration.GroupBy(a => a.Deadline);
Console.WriteLine("=== SUMMARY BY DEADLINE ===");
foreach (var group in byDeadline.OrderBy(g => g.Key))
    Console.WriteLine($"  {group.Key ?? "unknown"}: {group.Count()} assets");

Example 3: API Endpoint (Portal)

CSHARP
[HttpGet("cnsa/verdict")]
public async Task<IActionResult> GetCnsaVerdict([FromQuery] string project)
{
    // Load KB
    var kb = LoadKb();
    var (profile, _, timeline) = CnsaProfileFactory.Create();

    // Run analysis
    var engine = new AnalysisEngine(new RiskModel());
    var ctx = new AnalysisContext(project, kb, new IdentityService());
    var analysis = await engine.AnalyzeAsync(ctx);

    if (analysis.Cbom is null)
        return BadRequest("Analysis produced no CBOM.");

    // Validate
    var validator = new CnsaValidator(kb, profile, timeline);
    var result = validator.Validate(analysis.Cbom);

    return Ok(new
    {
        overallVerdict = result.OverallVerdict.ToString(),
        compliant = result.AssetVerdicts.Count(a => a.Verdict == CnsaVerdict.Compliant),
        nonCompliant = result.AssetVerdicts.Count(a => a.Verdict == CnsaVerdict.NonCompliant),
        indeterminate = result.IndeterminateCount,
        summary = result.Summary,
        gaps = result.Gaps.Select(g => new
        {
            g.AssetIdentifier, g.Algorithm, g.GapDescription,
            g.Requirement, g.RecommendedAction, g.Deadline
        }),
        timeline = result.Timeline
    });
}

Example 4: CI/CD Gate Integration

CSHARP
// Fail the build if CNSA 2.0 validation fails
var result = validator.Validate(cbom);

if (result.OverallVerdict != CnsaVerdict.Compliant)
{
    Console.Error.WriteLine("=== CNSA 2.0 VALIDATION FAILED ===");
    Console.Error.WriteLine(result.Summary);

    foreach (var gap in result.Gaps)
        Console.Error.WriteLine($"  GAP: {gap.AssetIdentifier} — {gap.RecommendedAction}");

    Environment.Exit(1); // Fail the build
}

Console.WriteLine("CNSA 2.0 validation passed.");

Example 5: Custom Profile Comparison

CSHARP
// Compare CNSA 2.0 against a hypothetical future profile
var (cnsaProfile, _, cnsaTimeline) = CnsaProfileFactory.Create();
var (customProfile, customEntries, customTimeline) = MyProfileFactory.Create();

var cnsaValidator = new CnsaValidator(kb, cnsaProfile, cnsaTimeline);
var customValidator = new CnsaValidator(kb, customProfile, customTimeline);

var cnsaResult = cnsaValidator.Validate(cbom);
var customResult = customValidator.Validate(cbom);

// Assets that pass CNSA but fail the stricter profile
var additionalFailures = customResult.AssetVerdicts
    .Where(c => c.Verdict != CnsaVerdict.Compliant)
    .Where(c => !cnsaResult.AssetVerdicts
        .Any(n => n.AssetIdentifier == c.AssetIdentifier && n.Verdict != CnsaVerdict.Compliant));

Console.WriteLine($"CNSA 2.0 violations: {cnsaResult.AssetVerdicts.Count(a => a.Verdict == CnsaVerdict.NonCompliant)}");
Console.WriteLine($"Additional custom violations: {additionalFailures.Count()}");

API Reference

CnsaProfileFactory (Static)

Member Type Description
ProfileName const string "CNSA 2.0"
ProfileVersion const string "2024-09"
ProfileSource const string "CNSSP-15 Annex B / NSA CNSA 2.0 Advisory"
Create() Static Method Returns (ComplianceProfile, IReadOnlyList<KbEntry>, IReadOnlyList<CnsaTimelineEntry>) — the profile, KB entries, and timeline

CnsaValidator

Member Type Description
CnsaValidator(IKnowledgeBase, ComplianceProfile, IReadOnlyList<CnsaTimelineEntry>) Constructor Creates a validator. Profile and timeline from CnsaProfileFactory.Create().
Validate(Cbom) Method Validates a CBOM. Returns CnsaValidationResult.

CnsaValidationResult

Property Type Description
OverallVerdict CnsaVerdict Aggregate verdict (worst-case: NonCompliant > Indeterminate > Compliant)
AssetVerdicts IReadOnlyList<CnsaAssetVerdict> Per-asset detailed verdicts
Gaps IReadOnlyList<CnsaGapItem> Gap analysis for all non-compliant/indeterminate assets
Evidence CnsaEvidence Reproducible validation evidence
Timeline IReadOnlyList<CnsaTimelineEntry> CNSA 2.0 phased deadlines
Summary string Human-readable summary (e.g., "CNSA 2.0 Validation: NonCompliant. 3 compliant, 2 non-compliant, 1 indeterminate. 3 gaps identified. 1 low-confidence finding(s) flagged.")
IndeterminateCount int Number of assets with indeterminate verdicts
LowConfidenceFlaggedCount int Number of assets with low-confidence detection

CnsaVerdict (Enum)

Value Description
Compliant Asset meets all CNSA 2.0 requirements
NonCompliant Asset is known and does not meet CNSA 2.0 requirements
Indeterminate Asset is unknown — fail-safe. Manual review required.

CnsaAssetVerdict

Property Type Description
AssetIdentifier string CBOM component BomRef or name
Algorithm string Algorithm name
Verdict CnsaVerdict Compliant, NonCompliant, or Indeterminate
Reason string Detailed explanation of the verdict
Requirement string? CNSA 2.0 requirement being evaluated
Deadline string? Relevant CNSA 2.0 deadline (ISO date)
Confidence Confidence? Detection confidence (from analysis)
PqcTarget string? Recommended PQC migration target

CnsaGapItem

Property Type Description
AssetIdentifier string Which asset has the gap
Algorithm string Which algorithm
GapDescription string What the gap is
Requirement string What requirement is not met
RecommendedAction string? What to do about it
Deadline string? When it must be addressed

CnsaEvidence

Property Type Description
ProfileName string "CNSA 2.0"
ProfileVersion string "2024-09"
KbVersion KbVersion KB version used for validation
EvaluatedAt DateTimeOffset When validation ran
DrivingAssets IReadOnlyList<string> Asset identifiers driving the evaluation
ProfileSource string Authority document reference

CnsaTimelineEntry

Property Type Description
Category string Milestone category (e.g., "ProcurementGate", "KeyEstablishment")
Deadline DateTimeOffset Compliance deadline
Description string Human-readable requirement

Configuration Options

Profile Selection

CSHARP
// Default CNSA 2.0 profile
var (profile, entries, timeline) = CnsaProfileFactory.Create();

// Or use a custom profile from the KB
var customProfile = kb.ComplianceProfiles.First(p => p.Name == "Custom Profile");
var validator = new CnsaValidator(kb, customProfile, myTimeline);

KB Version Management

The validator records which KB version was used:

CSHARP
var evidence = result.Evidence;
Console.WriteLine($"Validated with KB v{evidence.KbVersion} (profile v{evidence.ProfileVersion})");

// Store evidence for auditors
File.WriteAllText("cnsa-evidence.json", JsonSerializer.Serialize(evidence));

Custom Timeline

You can provide a custom timeline instead of the CNSA 2.0 defaults:

CSHARP
var customTimeline = new[]
{
    new CnsaTimelineEntry("InternalGate", new DateTimeOffset(2026, 6, 1, 0, 0, 0, TimeSpan.Zero),
        "Internal PQC migration deadline."),
    new CnsaTimelineEntry("ExternalGate", new DateTimeOffset(2028, 1, 1, 0, 0, 0, TimeSpan.Zero),
        "Customer-facing PQC requirement."),
};

var validator = new CnsaValidator(kb, cnsaProfile, customTimeline);

Confidence Thresholds

The validator currently flags all Low confidence findings. For stricter handling:

CSHARP
// Custom wrapper that treats Low-confidence as failures
public static class StrictCnsaValidator
{
    public static CnsaValidationResult ValidateStrict(CnsaValidator inner, Cbom cbom)
    {
        var result = inner.Validate(cbom);
        if (result.LowConfidenceFlaggedCount > 0)
        {
            // Optionally promote low-confidence to failures
            // Currently, low-confidence findings are flagged but don't change the overall verdict
            // This is a policy choice you can implement in a wrapper
        }
        return result;
    }
}

Integration Points

Integration How
Compass CLI compass cnsa --profile CNSA.2.0 --project .
Guardian Gate Embedded in CI/CD pipeline — fail build on NonCompliant
Portal API GET /v1/cnsa/verdict?project=./src — returns verdict + gaps + timeline
PDF Reports CNSA verdict drives color-coded summary pages in branded PDFs
Custom scripts CnsaValidator is a standalone class — use in any .NET console app

Value Showcase

Before CNSA 2.0 Validator

Q: "Are our 15 microservices CNSA 2.0 compliant?"
A: "We cross-referenced our crypto inventory against the advisory. 
    It took 2 analysts 3 weeks. The spreadsheet is on SharePoint somewhere.
    Also, we're not sure about the third-party libraries."
Risk: HIGH — manual, slow, incomplete, not reproducible

After CNSA 2.0 Validator

Q: "Are our 15 microservices CNSA 2.0 compliant?"
A: "Ran Compass with CNSA 2.0 profile across all repos. 
    12 are Compliant. 2 have NonCompliant assets (RSA in legacy modules). 
    1 has Indeterminate (unknown NuGet crypto). 
    Gap analysis with deadlines and migration targets attached. 
    Evidence timestamped and signed. 
    Total time: 4 seconds."
Risk: LOW — automated, complete, reproducible with evidence

Quantitative Impact

Metric Without Validator With CNSA 2.0 Validator
Per-project compliance evaluation time ~2 days (manual) <1 second
Coverage Sampled (cannot review every asset) Every crypto asset in the CBOM
Unknown algorithm detection Manual guesswork Automatic fail-safe (Indeterminate)
Parameter set checking Requires crypto expertise Automatic (ML-KEM-1024 vs 768)
Audit evidence Manual spreadsheets Machine-verifiable CnsaEvidence record
Timeline tracking Spreadsheet column Automatic deadline mapping per asset

Example: Real Compliance Scenario

Organization: Government contractor managing 50 .NET microservices with 340 cryptographic assets.

Asset Type Count Compliant NonCompliant Indeterminate
Signatures (ML-DSA-87) 120 120 0 0
Signatures (RSA/ECDSA) 80 0 80 0
KEM (ML-KEM-1024) 60 60 0 0
KEM (ML-KEM-768) 15 0 15 0
Symmetric (AES-256) 40 40 0 0
Symmetric (AES-128) 10 0 10 0
Unknown (third-party) 15 0 0 15

Overall Verdict: NonCompliant (105 non-compliant, 15 indeterminate)

Gap Analysis Output: 120 gap items with prioritized deadlines:

  • 80 signature assets → Procurement Gate deadline (2027)
  • 15 KEM assets → Key Establishment deadline (2030)
  • 10 symmetric assets → General Phase-Out (2033)
  • 15 indeterminate → manual investigation required immediately

Migration Roadmap: Automatically generated with per-asset PQC targets (ML-DSA-87, ML-KEM-1024, AES-256).

This analysis, which previously took weeks of expert time, now runs in seconds on every commit.

Compliance Alignment

Framework How CNSA 2.0 Validator Helps
CNSA 2.0 (CNSSP-15 Annex B) Direct implementation of the advisory as automated validation
NSM-10 Timeline-aware validation aligned with NSM-10 milestones
NIST SP 800-53 (CA-7) Continuous monitoring of compliance posture
RMF (Risk Management Framework) Evidence package ready for security control assessment
NIST SP 800-161 Identifies supply chain crypto risks from third-party components

Note: The CNSA 2.0 Validator is built on the Knowledge Base and produces per-asset verdicts consumed by Guardian Gate for enforcement and Compass for reporting.

Share

Keyboard Shortcuts

⌘ K
Open search
/
Focus search
?
Show shortcuts
b
Toggle bookmark
Alt+←
Previous page
Alt+→
Next page
Esc
Close overlay