Skip to content

feat(crypto): conforma integration - #2725

Draft
gildub wants to merge 16 commits into
guacsec:mainfrom
gildub:TC-conforma-integration
Draft

gildub wants to merge 16 commits into
guacsec:mainfrom
gildub:TC-conforma-integration

Conversation

@gildub

@gildub gildub commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Implements https://redhat.atlassian.net/browse/TC-5851

  1. Conforma policy evaluation engine (service/conforma.rs — new)
  • Integrates the Conforma CLI container (quay.io/conforma/cli:latest) as the policy evaluation engine
  • Starts a containerized Conforma server via podman run --network=host (required for rootless podman + slirp4netns)
  • Allocates a free local port via TcpListener::bind("0.0.0.0:0") before passing it to the container
  • Mounts the policy directory with :ro,z (SELinux-compatible) so policy files are accessible
  • Polls GET /ready until the server is up, then posts the algorithm list to /v1/validate/input
  • Parses [node_id:] prefixes embedded in Conforma msg fields to recover per-algorithm verdicts (Conforma strips all other fields from deny/warn results)
  • Stops the container after evaluation
  1. PolicyEvaluator trait abstraction (service/evaluator.rs — new)
  • Defines a PolicyEvaluator async trait (Send + Sync) with a single evaluate(&[AlgorithmInput]) -> Result<EvaluatorReport, Error> method
  • ConformaClient implements it; future evaluators (OPA, Cedar, etc.) can be plugged in without changing CryptoService
  • Enables a policy broker pattern — multiple engines can coexist as the policy ecosystem evolves
  1. Removed hardcoded Rust policy reimplementation (service/policy.rs)
  • evaluate_algorithm and its helpers (AlgorithmProps, is_pqc_safe, is_weak, is_sha1) were a static Rust mirror of the Rego rules, used as an interim solution before Conforma
  • These are removed entirely — the Rego policy in etc/conforma/policy/policy.rego is now the single authoritative source for PQC verdicts, executed by Conforma
  • The .rego file was also relocated from modules/fundamental/src/crypto/policy.rego to etc/conforma/policy/policy.rego, reflecting its role as runtime configuration rather than source code
  1. CryptoService restructured (service/mod.rs)
  • Holds evaluator: Option<Box> — present only when CONFORMA_POLICY is configured
  • evaluate_policy() calls Conforma, then persists verdicts to the DB via sbom_crypto.policy_verdict; commits the transaction when done
  • list_algorithms() reads stored policy_verdict from the DB and populates policy_status on each CryptoAlgorithmSummary — no Conforma call at read time
  • fetch_policy_summary() — new, aggregates stored verdicts from DB for the KPI cards (GET, no Conforma call)
  1. DB persistence (migration/ + entity/)
  • New migration m0002390_add_crypto_policy_verdict.rs adds a nullable policy_verdict TEXT column to sbom_crypto
  • entity/src/sbom_crypto.rs updated with pub policy_verdict: Option
  • Verdicts stored as "compliant", "warning", or "non_compliant"; NULL means not yet evaluated
  1. New GET /api/v3/crypto/policy/summary endpoint
  • Reads stored verdicts from DB and returns aggregate counts (total / compliant / warning / non_compliant)
  • Does not call Conforma — pure DB read used by the UI KPI cards
  • Cleanly separates "read stored results" from "trigger evaluation"
  1. Post-ingest automatic evaluation (sbom/endpoints/mod.rs)
  • The SBOM upload handler fires a tokio::spawn background task after tx.commit()
  • If CONFORMA_POLICY is configured, runs evaluate_policy for the newly ingested SBOM and commits the verdicts
  • Never blocks the upload response; failures are logged as warnings only
  1. Rego policy (etc/conforma/policy/policy.rego + etc/conforma/policy.yaml)
  • deny rules: SHA-1, MD5, RC4, RC2, DES, RSA ≤ 1024-bit, DSA ≤ 1024-bit → non_compliant
  • warn rules: all classical (non-PQC-safe) algorithms → warning
  • _is_pqc_safe: ML-KEM, KYBER, ML-DSA, DILITHIUM, SLH-DSA, SPHINCS
  • node_id embedded as [node_id:] prefix in each message so trustify can match verdicts back to individual assets
  1. Server configuration (server/src/profile/api.rs)
  • --conforma-policy CLI arg / CONFORMA_POLICY env var — absolute path to a local Conforma policy YAML file
  • Passed through to CryptoService::new(); when absent the evaluator is None and the evaluate endpoint returns 500
  1. Model and endpoint updates
  • CryptoAlgorithmSummary includes policy_status: Option (None = not yet evaluated)
  • evaluate_policy endpoint now uses db::ReadWrite (required to persist verdicts)
  • crypto::endpoints::configure accepts both db_rw and db_ro — read endpoints use the read-only connection, the evaluate endpoint uses the read-write one

When CONFORMA_POLICY is not provided, the application degrades gracefully in stages:

  • SBOM ingest — the if svc.has_evaluator() guard is false, the tokio::spawn is never created, ingest completes normally with no evaluation side-effect
  • GET /api/v3/crypto/algorithm — works fine; all items return policy_status: null since policy_verdict is NULL in the DB; the UI shows -- in the Policy column
  • GET /api/v3/crypto/policy/summary — works fine; returns { total: N, compliant: 0, warning: 0, non_compliant: 0 } since no verdicts are stored; KPI cards show 0%
  • POST /api/v3/crypto/policy/evaluate — returns 500 with "CONFORMA_POLICY is not configured"; this is intentional as calling evaluate without a policy engine configured is an explicit error, not a silent fallback

So the application is fully usable without Conforma for SBOM ingestion and browsing; it just has no policy verdicts. The 500 on the evaluate endpoint is a clear signal that the operator needs to configure CONFORMA_POLICY to enable that feature.

Summary by Sourcery

Integrate configurable Conforma policy evaluation into cryptographic asset processing and persist its verdicts for API and UI consumption.

New Features:

  • Integrate Conforma as the configurable cryptographic policy evaluation engine through a pluggable evaluator abstraction.
  • Persist per-algorithm policy verdicts and expose stored verdicts through algorithm listings and a policy summary endpoint.
  • Trigger policy evaluation asynchronously after SBOM ingestion when Conforma is configured.

Enhancements:

  • Replace the hardcoded Rust policy implementation with Rego policies as the authoritative source for PQC readiness decisions.
  • Allow crypto ingestion and read operations to function without policy configuration while clearly failing explicit evaluation requests.

Build:

  • Add Conforma policy files, deployment configuration, and cryptographic test fixtures.

Deployment:

  • Add CONFORMA_URL server configuration for connecting to the Conforma service.

Documentation:

  • Update the OpenAPI specification for nullable policy status, revised crypto summaries, and the new policy summary endpoint.

Tests:

  • Add coverage for persisted verdicts, policy summaries, evaluator-backed classifications, and operation without Conforma configuration.

Chores:

  • Add a database migration and entity field for stored cryptographic policy verdicts.

@gildub
gildub force-pushed the TC-conforma-integration branch 3 times, most recently from af4820f to 5722496 Compare October 1, 2026 12:49

@rh-jfuller rh-jfuller 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.

@gildub have you considered registering conforma as a semantic validator (like scheck and csaf validator) ... instead of bolting on into the endpoint itself ? That would mean we have clear abstraction and sets up conforma usage elsewhere.

@gildub
gildub force-pushed the TC-conforma-integration branch 2 times, most recently from 575202f to dfcdc79 Compare October 1, 2026 19:11
@gildub

gildub commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor Author

@rh-jfuller,

Semantic validators (scheck, csaf-validator) are coupled to the ingest event, they run once when the document arrives and that's it. That's fine for validation only depending on document content itself, which never changes after ingest.

But Conforma evaluations depend on two independent variables:

  • The SBOM: fixed after ingest
  • The policy: will changes over time as policy management feature is added

Because the policy can change independently of the SBOM, re-evaluation is a first-class operation, not an edge case. Embedding Conforma into the semantic validator pattern would make re-evaluation awkward, since you'd have to fake a re-ingestion to trigger it.

Keeping it as a separate, triggerable evaluation service that can be invoked:

  • Automatically after ingest against active policies
  • On-demand when a policy is added or changed against existing SBOMs

Meanwhile I have been thinking about future policy evaluators and the need to add abstract within the crypto/policy domain. The rationale is that although Conforma (Rego policy) is a mature policy validation solution, a future is coming with CEL (per-artifact checks), Datalog/graph-based (cross-artifact reasoning), CUE (niche but elegant schema-plus-constraint validation), Cedar and others.

A PolicyEvaluator will allow Conforma to be swappable.

Something like :

trait PolicyEvaluator: Send + Sync {
    async fn evaluate(
        &self,
        algorithms: &[AlgorithmInput],
    ) -> Result<PolicyReport, Error>;
}

// Today
struct ConformaEvaluator { policy_path: String, ... }
impl PolicyEvaluator for ConformaEvaluator { ... }

// Tomorrow
struct OpaEvaluator { ... }         // direct OPA without Conforma
struct StyraEvaluator { ... }       // commercial DAS
struct CedarEvaluator { ... }       // AWS Cedar
impl PolicyEvaluator for OpaEvaluator { ... }

The policy broker to sit on top of this:

struct PolicyBroker {
      evaluators: HashMap<EvaluatorKind, Box<dyn PolicyEvaluator>>,
  }

And the policies table gains an evaluator_kind field — so each stored policy declares not just what to evaluate (the Rego/policy content) but which engine evaluates it. The broker routes accordingly.

This will also allow to connect directly to the coming policy management feature:

  • A policy record stores: name, source URL, auth config, etc and evaluator kind
  • When evaluation is triggered (at ingest or on policy change), the broker picks the right engine for each active policy
  • Results are stored per (sbom_id, policy_id, node_id) regardless of which engine produced them

The current ConformaClient in the PR is the first concrete implementation of PolicyEvaluator.
The trait boundary is what you'd want to draw now (only Conforma exists today) and the rest of the architecture (broker, policy management, ingestion hook) can be built against the abstraction rather than against Conforma directly.

The question is about adding such abstract now to allow easy future evolution.
I believe this a small price to pay now for flexibility.

@gildub

gildub commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

@rh-jfuller, I added a commit with the policy evaluator abstract.

@guacsec guacsec deleted a comment from sourcery-ai Bot Oct 1, 2026
@gildub
gildub force-pushed the TC-conforma-integration branch from c9f78b0 to d6eab7a Compare October 1, 2026 21:17
@gildub
gildub requested a review from jcrossley3 October 1, 2026 23:51
@gildub
gildub marked this pull request as ready for review October 2, 2026 00:10
@gildub gildub changed the title [WIP] feat(crypto): conforma integration feat(crypto): conforma integration Oct 2, 2026
@sourcery-ai

sourcery-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR replaces the interim in-process crypto policy implementation with an optional Conforma/Podman evaluator, persists its per-algorithm verdicts in the database, exposes stored classifications and aggregate summaries through the API, and triggers evaluation asynchronously after SBOM ingestion while preserving normal operation when Conforma is not configured.

Sequence diagram for asynchronous SBOM Conforma evaluation

sequenceDiagram
    participant Client
    participant Upload as SBOM_upload
    participant DB
    participant Crypto as CryptoService
    participant Conforma as ConformaClient
    participant Podman

    Client->>Upload: upload()
    Upload->>DB: commit()
    Upload-->>Client: HTTP 201
    Upload->>Crypto: has_evaluator()
    Crypto-->>Upload: evaluator configured
    Upload->>Crypto: evaluate_policy(sbom_id, transaction)
    Crypto->>Conforma: evaluate(algorithms)
    Conforma->>Podman: podman run --network=host
    Podman-->>Conforma: container_id
    Conforma->>Conforma: wait_ready()
    Conforma->>Podman: GET /ready
    Conforma->>Podman: POST /v1/validate/input
    Podman-->>Conforma: violations and warnings
    Conforma->>Conforma: parse_finding()
    Conforma-->>Crypto: EvaluatorReport
    Crypto->>DB: update policy_verdict
    Crypto-->>Upload: evaluation result
    Upload->>DB: commit()
Loading

File-Level Changes

Change Details Files
Integrate Conforma as an optional, containerized policy evaluation backend behind an asynchronous evaluator abstraction.
  • Launch the Conforma CLI server with Podman, mounted policy files, dynamic port allocation, readiness polling, and cleanup.
  • Submit algorithm inputs to Conforma and recover per-asset findings from node IDs embedded in result messages.
  • Define the PolicyEvaluator trait and wire ConformaClient into CryptoService when configuration is present.
modules/fundamental/src/crypto/service/conforma.rs
modules/fundamental/src/crypto/service/evaluator.rs
modules/fundamental/src/crypto/service/mod.rs
modules/fundamental/Cargo.toml
Cargo.lock
Move cryptographic policy decisions from Rust code into the authoritative Conforma Rego policy.
  • Add PQC-safe, warning, and non-compliance rules for weak algorithms and undersized RSA/DSA keys.
  • Relocate the policy into Conforma runtime configuration and remove the hardcoded Rust evaluator and its unit tests.
  • Configure the policy bundle and document the node ID message convention used for result correlation.
etc/conforma/policy/policy.rego
etc/conforma/policy.yaml
modules/fundamental/src/crypto/service/policy.rs
Persist policy verdicts and expose stored results through crypto APIs.
  • Add a nullable verdict column and initialize newly ingested cryptographic assets without a verdict.
  • Persist compliant, warning, or non-compliant classifications during evaluation.
  • Populate algorithm listings from stored verdicts and add a database-only aggregate policy summary endpoint.
migration/src/m0002390_add_crypto_policy_verdict.rs
migration/src/lib.rs
entity/src/sbom_crypto.rs
modules/ingestor/src/graph/sbom/common/cryptographic_asset.rs
modules/fundamental/src/crypto/model.rs
modules/fundamental/src/crypto/service/mod.rs
modules/fundamental/src/crypto/endpoints/mod.rs
Make policy evaluation optional while adding background evaluation after SBOM ingestion.
  • Pass CONFORMA_POLICY / --conforma-policy into crypto service construction.
  • Use read-write transactions for explicit evaluation and commit persisted verdicts.
  • Spawn non-blocking post-ingest evaluation only when configured, logging failures without failing ingestion.
  • Return a clear server error for explicit evaluation requests when no evaluator is configured.
server/src/profile/api.rs
modules/fundamental/src/endpoints.rs
modules/fundamental/src/crypto/endpoints/mod.rs
modules/fundamental/src/sbom/endpoints/mod.rs
Update endpoint and integration tests for persisted, evaluator-backed classifications and unconfigured behavior.
  • Add a mock evaluator for persistence and listing tests.
  • Verify SHA-1/non-compliant and classical/warning classifications are stored and returned.
  • Replace prior hardcoded-policy assertions with checks for the intentional 500 response when Conforma is absent.
modules/fundamental/src/crypto/endpoints/test.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="modules/fundamental/src/crypto/service/conforma.rs" line_range="111-122" />
<code_context>
+        self.wait_ready(&base_url).await?;
+
+        let client = reqwest::Client::new();
+        let response = client
+            .post(format!("{base_url}/v1/validate/input"))
+            .json(&input)
+            .send()
+            .await
+            .context("failed to reach Conforma evaluation endpoint")?;
+
+        response
+            .json()
+            .await
+            .context("failed to parse Conforma response")
+            .map_err(|e| crate::Error::Internal(e.to_string()))
+    }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The Conforma HTTP status is ignored before deserializing the response. An error response such as `{}` deserializes successfully because `RawConformaReport.filepaths` has a default empty value, causing every evaluated algorithm to fall through to `Compliant` and persist a false compliant verdict.

**Triggers:** When Conforma returns a non-success response with a JSON body that does not contain `filepaths`.

**Suggested fix:** Call `error_for_status()` before deserializing the response so HTTP failures are returned instead of treated as an empty successful report.
</issue_to_address>

### Comment 2
<location path="modules/fundamental/src/crypto/model.rs" line_range="30-32" />
<code_context>
 #[derive(Serialize, Deserialize, Debug, Clone, ToSchema)]
 pub struct CryptoSummary {
     pub total_algorithms: i64,
-    pub pqc_compliant: i64,
-    pub classical_share_pct: f64,
-    pub sboms_meeting_pqc: i64,
 }

 #[derive(Serialize, Deserialize, Debug, Clone, ToSchema)]
</code_context>
<issue_to_address>
**issue (broader_impact):** The existing `GET /v3/crypto/summary` response drops `pqc_compliant`, `classical_share_pct`, and `sboms_meeting_pqc`, returning only `total_algorithms`. Existing API consumers that read those fields receive missing values and the existing KPI contract is broken; the new policy summary endpoint does not preserve that response shape.

**Triggers:** When an existing client continues calling `GET /v3/crypto/summary`.

**Suggested fix:** Preserve the existing `CryptoSummary` fields and populate them from stored verdicts, or explicitly version the endpoint and update every consumer in the same change.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 2 findings to address first, and a faulty Conforma policy, parser, or container integration can persist incorrect cryptographic verdicts and expose them through the list and summary APIs; launching a podman container also introduces a production runtime dependency. Reverting removes the new behavior, and the stored verdicts are bounded and can be repaired by rerunning evaluation.

Blocking findings: modules/fundamental/src/crypto/service/conforma.rs:122, modules/fundamental/src/crypto/model.rs:32


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines +111 to +122
let response = client
.post(format!("{base_url}/v1/validate/input"))
.json(&input)
.send()
.await
.context("failed to reach Conforma evaluation endpoint")?;

response
.json()
.await
.context("failed to parse Conforma response")
.map_err(|e| crate::Error::Internal(e.to_string()))

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.

issue (bug_risk): The Conforma HTTP status is ignored before deserializing the response. An error response such as {} deserializes successfully because RawConformaReport.filepaths has a default empty value, causing every evaluated algorithm to fall through to Compliant and persist a false compliant verdict.

Triggers: When Conforma returns a non-success response with a JSON body that does not contain filepaths.

Suggested fix: Call error_for_status() before deserializing the response so HTTP failures are returned instead of treated as an empty successful report.

Comment on lines -30 to -32
pub pqc_compliant: i64,
pub classical_share_pct: f64,
pub sboms_meeting_pqc: i64,

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.

issue (broader_impact): The existing GET /v3/crypto/summary response drops pqc_compliant, classical_share_pct, and sboms_meeting_pqc, returning only total_algorithms. Existing API consumers that read those fields receive missing values and the existing KPI contract is broken; the new policy summary endpoint does not preserve that response shape.

Triggers: When an existing client continues calling GET /v3/crypto/summary.

Suggested fix: Preserve the existing CryptoSummary fields and populate them from stored verdicts, or explicitly version the endpoint and update every consumer in the same change.

@gildub
gildub requested a review from rh-jfuller October 2, 2026 00:19
@rh-jfuller

Copy link
Copy Markdown
Contributor

@rh-jfuller,

Semantic validators (scheck, csaf-validator) are coupled to the ingest event, they run once when the document arrives and that's it. That's fine for validation only depending on document content itself, which never changes after ingest.

But Conforma evaluations depend on two independent variables:

* The SBOM: fixed after ingest

* The policy: will changes over time as policy management feature is added

I think you are observing existing initial usage of schema validators and assuming its linked to just ingestion ... it is not.

Because the policy can change independently of the SBOM, re-evaluation is a first-class operation, not an edge case. Embedding Conforma into the semantic validator pattern would make re-evaluation awkward, since you'd have to fake a re-ingestion to trigger it.

then we should change semantic validators to enable that scenario instead of create a different codepath/abstraction.

Keeping it as a separate, triggerable evaluation service that can be invoked:

* Automatically after ingest against active policies

* On-demand when a policy is added or changed against existing SBOMs

I think all schema validators should be able to operate similarly ... lets discuss today how we can do that.

Meanwhile I have been thinking about future policy evaluators and the need to add abstract within the crypto/policy domain. The rationale is that although Conforma (Rego policy) is a mature policy validation solution, a future is coming with CEL (per-artifact checks), Datalog/graph-based (cross-artifact reasoning), CUE (niche but elegant schema-plus-constraint validation), Cedar and others.

lets talk about this as well. thx!

@rh-jfuller
rh-jfuller marked this pull request as draft October 2, 2026 15:30
@rh-jfuller

rh-jfuller commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

@gildub as per our recent discussion ... this PR is not going to work (for a few reasons) in terms of invoking a container to get CLI ... direct invoke of the conforma CLI was previously considered and something we want to avoid.

So we have to either:

  • conforma has no server daemon/REST API ... consider building a http wrapper over conforma (aka >ec validate input --server) and provide simple web interface which is spawned as part of infra and register conforma as a semantic validator (which accesses this REST endpoint). Though we have to be mindful that >ec validate input --server maybe unsafe and need a lot of wrapping.

or

  • enable validator registration of container invokes which in developer context runs in the same env as trustify and optionally we can schedule as a kubernetes job for prod deployments.

we are leaning towards the former (eg. separate pod running cli server).

today registering a validation service means it can be used in ingestion validation as well as direct invoke though either of the above approaches predicates some work for the current validation registration extensibility already built in trustify (eg. scheck and csaf validator) ... I will try to do that work first to support where we land in this PR.

the only other risk is possibility that any of these approaches break down with scale.

@rh-jfuller

Copy link
Copy Markdown
Contributor

#2733 implements registration for conforma validator

@gildub

gildub commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

@rh-jfuller,

Conforma does have API interface [1] and that's the one we're using in this PR :
The only constraint at the moment, is current Conforma server is attached to a given policy at launch time. As discussed, we're going to ask Conforma team to change such constraint.

Therefore policy validation will still occur through Conforma API interface meanwhile through the incoming validator abstract update.

That said and as discussed, the local container invocation is going to be removed and will be replaced with a compose script for dev and helm chart for prod.

[1] https://github.com/conforma/cli/blob/main/cmd/validate/input.go#L120-L132.

@gildub
gildub force-pushed the TC-conforma-integration branch from 8d9441d to 2e8782c Compare October 5, 2026 09:28

@jcrossley3 jcrossley3 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.

Looks good, but I agree there is some appeal to fitting this into the existing semantic validation framework as shown in #2733

Comment thread modules/fundamental/src/crypto/service/mod.rs Outdated
@gildub
gildub force-pushed the TC-conforma-integration branch from 2e8782c to b3a60c0 Compare October 5, 2026 22:39

This branch has not been deployed

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants