CoRIM verifier#
Note: The CoRIM verifier is experimental. It is the direction for NVIDIA’s attestation-verification workflow, but its behavior, interfaces, supported evidence, and EAR output may change.
The CoRIM verifier is the SDK’s parallel path to the legacy TCG RIM-based verifier. It appraises a Conceptual Message Wrapper (CMW) against CoRIM reference manifests and returns an Entity Attestation Result (EAR). It follows CoRIM draft 11 and implements a subset of that draft. See Supported CoRIM CDDL for the constructs that are appraised, parsed, ignored, or rejected. The feature first shipped in NVIDIA Attestation SDK 2.0.0.
The legacy path continues to use the legacy TCG RIM workflow and returns a claims collection with a detached EAT.
CMW evidence --> local CoRIM verifier --> EAR JSON --> relying-party policy
\
+--> signed EAR JWT --> remote relying party
Standards direction and scope#
This path uses IETF RATS concepts at its integration boundary: CMW carries
evidence, CoRIM supplies reference values, ConciseEvidence can carry device
evidence, and EAR carries the appraisal result.
The current implementation accepts JSON CMW input;
CMW CBOR is reserved but not implemented. GPU and SPDM input media types,
EAR profiles, and ear_nvidia_* extension claims are NVIDIA-specific.
Live GPU evidence collection through NVML does not yet support current-generation devices because their CoRIMs are not published. Support follows once those CoRIMs are available.
Processing flow#
An Environment-Claim Tuple (ECT) ties measurements to an environment, and the Appraisal Claims Set (ACS) holds those ECTs during appraisal. The verifier normalizes evidence, certificate extensions, CoEV, and CoRIM reference triples into ECTs before comparing them.
The verifier runs these stages in order:
Read the JSON CMW collection: evidence, nonce, certificates, appraisal settings, and hints.
Authenticate each evidence item: signature, certificate chain, nonce, and OCSP when revocation checking is on.
Convert the authenticated evidence into evidence ECTs and read its
rim-locators.DiceTcbInfoextensions in the validated certificate chain contribute ECTs, if present.Resolve each locator against the URL policy and rewrites, then fetch the signed CoRIM from the CoRIM store or RIM service.
Convert those documents into reference ECTs and dependency triples.
Compare evidence ECTs against reference ECTs and evaluate the dependency graph.
Emit the attestation result.
Dependency triples connect a domain environment to its trustee environments. The verifier evaluates trustees first, marks a domain failed when one of its trustees fails, and rejects dependency cycles.
Evidence inputs#
The verifier accepts these evidence forms:
Source |
Evidence mapping |
RIM discovery |
|---|---|---|
EAT |
TCG DICE Concise Evidence from the |
|
SPDM 1.1 with embedded CoEV |
The verifier authenticates the SPDM measurement transcript and turns the embedded TCG DICE Concise Evidence into ECTs. |
|
SPDM 1.1 with fetched CoEV |
A RIM service can return CoEV alongside the CoRIM. The verifier checks the CoEV signature and turns its measurements into ECTs. |
Locator is constructed with attester-specific code. |
X.509 |
|
Certificate extensions supply no locator. |
Authentication runs before CoRIM comparison. The verifier checks the evidence signature and the certificate chain, checks a per-item nonce when one is supplied, and runs OCSP checks when revocation checking is on.
DiceTcbInfo conversion#
Certificate-chain conversion follows
draft-ietf-rats-evidence-trans-02 §4.2.
type, vendor, model, layer, and index populate the environment class map,
a DiceUeid extension populates the instance identifier,
and version, svn, vendorInfo, fwid, and the operational flags
populate the measurement values.
MultiDiceTcbInfo produces one ECT for each contained DiceTcbInfo entry.
The implementation departs from §4.2 as follows:
Draft rule |
Implementation |
|---|---|
Step 3.iii copies every FWID in the list. |
Only the first FWID becomes a digest. The rest are logged and dropped. |
Step 3.iii copies |
Dropped. The verifier does not support integrity registers at this time. |
Step 4 sets |
Not set. Authority tracking is not implemented. |
Step 3.iv reads |
Read in positive polarity, following TCG DICE Attestation Architecture v1.2 §A.1. The draft text contradicts the bit names. |
Step 3.iv reads a flag bit only where the mask sets it. |
A |
Step 3.iii copies |
The OID is translated to a Named Information identifier. See below. |
The draft sets no width limit on |
Each must fit an unsigned 32-bit integer. |
Step 3.ii takes the UEID from the certificate’s |
Same, and a certificate without that extension falls back to a chain-level UEID. |
FWID.hashAlg cannot be copied literally.
DICE carries a DER object identifier,
while CoRIM defines digest.alg as int / text,
so every implementation has to choose one of those two forms.
This verifier emits the integer:
the NIST OIDs for SHA-256, SHA-384, and SHA-512
become Named Information hash identifiers 1, 7, and 8.
Any other hash OID fails the conversion.
SPDM and Concise Evidence conversion#
SPDM and CoEV evidence follows TCG DICE Concise Evidence Binding for SPDM v1.1. CoEV parsing is permissive: an unsupported field is logged and skipped.
An SPDM 1.1 transcript is the GET_MEASUREMENTS request
followed by the MEASUREMENTS response.
Its trailing 96 bytes are an ECDSA P-384 signature over the rest,
checked against the companion certificate chain.
SHA-384 and P-384 are assumed for every chain.
The request nonce becomes eat_nonce,
and freshness is compared only when the caller supplies a per-item nonce.
The measurement hash algorithm is absent from the transcript,
so the verifier infers it from the digest length and defaults to SHA-384.
The table of contents is a #6.570-tagged value
in the measurement manifest at index 0xFD.
A transcript without one is legitimate.
CoEV item |
Status |
Implemented behavior |
|---|---|---|
|
Appraised |
One to eight tagged concise evidence documents. |
|
Appraised |
Up to eight locator maps. Their URIs join the RIM locator list. |
|
Appraised |
One to 100 records, each with one environment and one to 50 measurements. Each record becomes one evidence ECT. |
|
Ignored |
Identity, dependency, membership, CoSWID, and attest-key triples are logged and skipped. A map carrying no triple at all fails the evidence item. |
|
Parsed |
A tagged UUID, retained and reported. |
|
Parsed |
Retained. Comparison rules do not vary by profile. |
Extension keys |
Ignored |
Unknown keys are tolerated. A schema-defined key that lands in the extension array is reported as malformed. |
A measurement can carry spdm-indirect (§7.1) in place of its value.
Each index names an SPDM measurement block
whose DMTF value type selects the target field:
DMTF value type |
Target |
|---|---|
|
A digest under the derived hash algorithm. |
|
|
|
|
Any other value |
|
RIM discovery and validation#
The verifier uses RIM locations in this order:
rim-locatorsextracted from primary evidence.A platform-specific synthesized locator when the required evidence facts and
hints.fwversionare available.One or more fallback locators configured on the verifier.
The verifier checks each locator against its URL policy before retrieval. A configured URL rewrite redirects an allowed locator to a mirror or local test file, and the original locator must still pass the policy.
CoRIM signature verification is on by default: the verifier checks the COSE Sign1 signature against the configured CoRIM root and records the signing certificate status. Revocation checks are on by default as well. Disabling signature verification accepts unsigned CoRIM payloads. Use this mode only for testing. A CoRIM that fails to fetch, verify, or parse leaves its evidence item unaffirmed.
Supported CoRIM CDDL#
The tables below separate data that affects appraisal from data the verifier only parses or ignores.
Status values:
Appraised: the value affects reference matching or dependency evaluation.
Verified: the value takes part in a cryptographic or freshness check.
Parsed: the verifier keeps or reports the value, and it does not affect the appraisal decision.
Ignored: the verifier accepts the value and discards it.
Rejected: the verifier returns a schema or unsupported-feature error.
Support for additional CoRIM constructs will be added in future releases based on need.
CoRIM envelope and map#
CDDL item |
Status |
Implemented behavior |
|---|---|---|
|
Verified |
Enabled by default. The payload must decode as a tagged unsigned CoRIM map. |
|
Parsed |
Required around the unsigned CoRIM payload. |
|
Parsed |
Text and 16-byte UUID identifiers are accepted and reported in the verifier claims. |
|
Appraised |
One to 25 tags are accepted. Per-tag behavior is listed below. |
|
Rejected |
Chained dependent CoRIM processing is not implemented. |
|
Parsed |
URI and tagged OID values are accepted. The local verifier applies generic comparison rules to every profile. |
|
Parsed |
Integer |
|
Parsed |
Entity name, optional registration identifier, and roles are retained. They do not affect comparison. |
|
Rejected |
The CDDL decoder accepts extension keys, but wrapper construction rejects them as unsupported. |
Tag types and CoMID fields#
CDDL item |
Status |
Implemented behavior |
|---|---|---|
|
Appraised |
Reference and dependency triples are extracted. |
|
Ignored |
The tag is accepted but contributes no ECTs. |
|
Ignored |
The tag is accepted but contributes no ECTs. |
|
Parsed |
Retained as tag metadata. |
|
Parsed |
Text and UUID identifiers are accepted. |
|
Ignored |
Accepted by the schema but not used by the verifier model. |
|
Parsed |
Entity name, optional registration identifier, and roles are retained. |
|
Rejected |
Linked-tag traversal is not implemented. |
|
Appraised |
Supported triple categories are listed below. |
|
Rejected |
The CDDL decoder accepts extension keys, but wrapper construction rejects them as unsupported. |
Triple categories#
Triple CDDL item |
Status |
Implemented behavior |
|---|---|---|
|
Appraised |
Each reference ECT supplies an environment and one to 50 reference measurements. |
|
Ignored |
Accepted but does not affect appraisal. |
|
Rejected |
Identity processing is not implemented. |
|
Rejected |
Attestation-key processing is not implemented. |
|
Appraised |
Each domain environment can name one to 64 trustee environments. |
|
Rejected |
Membership processing is not implemented. |
|
Rejected |
CoSWID triple processing is not implemented. |
|
Ignored |
Accepted but does not affect appraisal. |
|
Ignored |
Accepted but does not affect appraisal. |
A CoRIM containing only ignored tag or triple types produces no reference ECTs and cannot affirm evidence.
Environment maps#
Reference environment fields constrain the evidence fields they name. A field the reference omits matches anything, and extra evidence fields never cause a mismatch.
All properties of the environment-map available as of draft 11 are supported.
Measurement maps and values#
measurement-map.mkey is optional and can be a tagged OID, tagged UUID,
unsigned integer, or text.
Each measurement key must be unique within an ECT.
Duplicate keys in a reference or evidence ECT are ambiguous and rejected.
This limitation may be relaxed in a future release.
CDDL item |
Status |
Implemented behavior |
|---|---|---|
|
Appraised |
The version value and version scheme must both match. Schemes 1 through 5, semver 16384, and arbitrary integer or text scheme identifiers are accepted. |
|
Appraised |
Exact SVN and minimum-SVN tag 553 are supported. An evidence SVN must be a concrete value. |
|
Appraised |
Integer and text algorithm identifiers are both accepted. Duplicate algorithms are rejected. |
|
Appraised |
Configured, secure, recovery, debug, replay-protected, integrity-protected, runtime-meas, immutable, tcb, and confidentiality-protected are supported. Only flags present in the reference constrain evidence. |
|
Appraised |
Tagged byte strings are compared exactly. Tagged masked values compare only bits selected by the mask. Value and mask lengths must match. |
|
Rejected |
The deprecated separate mask field is not supported. |
|
Rejected |
The comparison model has no MAC-address representation. |
|
Rejected |
The comparison model has no IP-address representation. |
|
Rejected |
The comparison model has no serial-number representation. |
|
Rejected |
The comparison model has no UEID measurement representation. |
|
Rejected |
The comparison model has no UUID measurement representation. |
|
Appraised |
Exact text comparison. |
|
Rejected |
Rejected in CoRIM. Accepted only when converting CoEV evidence, which also needs the referenced SPDM measurement record. |
|
Rejected |
Cryptographic-key claim comparison is not implemented. |
|
Rejected |
Integrity-register comparison is not implemented. |
|
Appraised |
A reference can contain an exact integer or a tagged inclusive range. A |
|
Rejected |
Authority tracking is not implemented. |
|
Rejected |
Arbitrary extension keys are absent from the generated CDDL and fail decoding. |
Appraisal behavior#
Root environment OID#
The verifier identifies a root environment from environment.class.class-id.
The class identifier must be a tagged OID under the NVIDIA CoRIM arc:
1.3.6.1.4.1.5703.1300.<path>.1.<leaf>
<path> holds zero or more arcs,
the penultimate arc must be 1,
and <leaf> can be any arc.
After fallback handling, evidence must contain exactly one recognized root. A compatible reference environment with a root OID anchors the appraisal scope. The scope contains the root and every trustee reachable through dependency triples. Environments outside the appraisal scope do not contribute to the final attestation results.
The root also names the purpose of the appraisal.
A purpose is a measurement keyed by the text purpose
whose name value labels the device state that the root describes,
so one device can have several roots for several operating modes.
This allows different operating modes to describe different TCBs through domain-dependency triples.
When neither evidence nor reference ECTs contain a recognized root,
the verifier injects the synthetic root
1.3.6.1.4.1.5703.1300.999.1.1
with a purpose value of DEFAULT.
The synthetic root depends on every reference environment.
This fallback does not apply when only one side lacks a root.
ACS processing#
The verifier implements this subset of ACS processing:
Check |
Behavior |
|---|---|
Environment identity |
Reference fields constrain evidence fields. Extra evidence identity fields are ignored. Duplicate evidence environments are rejected. |
Reference measurements |
Every reference measurement key must exist and match in the selected evidence ECT. Extra evidence measurements are permitted. |
Alternative configurations |
Multiple reference ECTs for one environment are treated as alternatives. Any matching alternative can corroborate the environment. |
ECT merging |
Compatible or disjoint reference ECTs for one environment would need merging, which is not implemented, so the verifier rejects them. |
Root selection |
The root and its transitive trustees define the in-scope outcomes. Multiple recognized evidence roots are rejected. |
Dependencies |
The domain dependency graph is evaluated in reverse topological order. Cycles and dependencies without a corresponding reference environment are rejected. Trustee failure propagates to the dependent domain. |
Unmatched evidence |
An evidence environment with no applicable reference is reported as unmatched. |
Purpose |
Checked on the root as described under Root environment OID. |
Authority |
Authority tracking is not yet implemented. |
CMW input#
The verifier consumes a JSON Conceptual Message Wrapper (CMW) collection. Each record is a two-element array containing a media type and a base64url-encoded payload.
cmw = {
"__cmwc_t": "tag:nvidia.com,2026:verifier-input/profiles/base/pre-1.0.0",
? "nonce": nonce-record,
? "appraisal-settings": json-record,
+ tstr => evidence-item,
}
evidence-item = {
"__cmwc_t": "tag:nvidia.com,2026:evidence-item/v1",
"evidence": evidence-record,
? "nonce": nonce-record,
? "certificate": certificate-record,
? "hints": json-record,
* tstr => any,
}
evidence-record = [
media-type: tstr,
payload: base64url,
]
nonce-record = [
media-type: "application/octet-stream",
nonce: base64url,
]
certificate-record = [
media-type: "application/vnd.nvidia.pem-cert-chain",
certificate-chain: base64url,
]
json-record = [
media-type: "application/json",
json: base64url,
]
base64url = tstr
A collection must contain at least one evidence item.
Every collection-level key other than __cmwc_t, nonce,
and appraisal-settings labels an evidence item, for example gpu0.
Those three reserved names cannot label evidence.
The evidence media type selects the handler,
and an unsupported media type fails that item.
Evidence formats that do not carry their own certificate chain
need the certificate record.
After base64url decoding, the recognized JSON settings and hints have this shape:
appraisal-settings-json = {
? "ars": {
? "digest-algos": [* (int / tstr)],
* tstr => any,
},
* tstr => any,
}
hints-json = {
? "fwversion": tstr,
* tstr => any,
}
ars.digest-algos selects the input digests that the attestation result carries.
Name SHA-256, SHA-384, or SHA-512
by Named Information identifier or algorithm name.
Output CDDL#
EAR format reference is the source of truth for the claims currently emitted by the verifier. Custom implementations should ensure that the EAR profile is understood before applying policy.
ear = {
"eat_profile": "tag:nvidia.com,2026:ear/profiles/composite/generic/pre-1.0.0",
"iat": int,
"nbf": int,
"exp": int,
? "iss": tstr,
? "jti": tstr,
"ear_verifier_id": verifier-id,
? "ear_nvidia_inputs": input-summary,
? "eat_nonce": base64url,
"ear_status": ear-status,
"submods": { * tstr => ear-submodule },
}
ear-status = "affirming" / "contraindicated"
verifier-id = {
"developer": "https://developer.nvidia.com/attestation",
"build": tstr,
}
input-summary = {
"digests": [+ input-digest],
}
input-digest = {
"alg": "sha-256" / "sha-384" / "sha-512",
"val": base64url,
}
ear-submodule = {
"eat_profile": "tag:nvidia.com,2026-05:ear/profiles/gpu/1.0.0",
? "evidence_profile": tstr,
"ear_status": ear-status,
? "ear_nvidia_purpose": tstr,
? "eat_nonce": base64url,
"ear_verifier_claims": verifier-claims,
? "ear_attester_claims": { + tstr => tstr },
? "ear_nvidia_error_details": [+ error-detail],
}
verifier-claims = {
"ear_nvidia_evidence": evidence-result,
? "ear_nvidia_rims": [+ rim-result],
? "ear_nvidia_evidence_rim_cmp": comparison-result,
}
evidence-result = {
"signature_verified": bool,
? "parsed": bool,
? "nonce_match": bool,
? "cert_chain": [+ certificate-result],
? "akpub": tstr,
}
rim-result = {
"fetched": bool,
"locator": tstr,
"parsed": bool,
? "signature_verified": bool,
? "id": tstr,
? "cert_chain": [+ certificate-result],
? "error": error-detail,
}
certificate-result = {
"expired": bool,
"expiration_date": tstr,
"cert_check_status": tstr,
? "ocsp_response_status": bool,
? "ocsp_response_produced_at": tstr,
? "ocsp_crl_status": tstr,
? "revocation_reason": tstr,
? "ocsp_response_revoked_at": tstr,
? "ocsp_nonce_matches": bool,
? "ocsp_crl_response_expired": bool,
? "ocsp_crl_response_expiration_date": tstr,
}
comparison-result = {
"matched_env": [* environment],
"mismatched_env": [* environment],
"unmatched_env": [* environment],
}
environment = {
? "class": {
? "class_id": tstr,
? "vendor": tstr,
? "model": tstr,
? "layer": uint,
? "index": uint,
},
? "instance": tstr,
? "group": tstr,
}
error-detail = {
"code": int,
"message": tstr,
? "details": tstr,
? "related_envs": [+ environment],
}
base64url = tstr
The verifier returns the ear object as JSON
and as the claim set of an Entity Attestation Result (EAR) JWT.
The JWT protected header and signature fall outside this CDDL.
An optional member is omitted when its processing stage produces no value.
Result semantics#
Each evidence label becomes a submodule in the result.
A submodule is affirming only when evidence authentication succeeds,
no error diagnostic is present,
a compatible reference root anchors the single evidence root,
and the root plus every environment reachable through its dependency graph passes.
Outcomes outside the rooted subtree do not change the status.
Every other completed appraisal is contraindicated.
The top-level status is the least favorable submodule status.
The result includes:
evidence signature and certificate-chain information;
every requested CoRIM locator and its fetch, parse, signature, and certificate status;
matched, mismatched, and unmatched environments;
whether ECTs derived from certificate-chain
DiceTcbInfomatched;attester claims extracted from claims-from-evidence ECTs;
structured verifier errors and comparison diagnostics;
optional input digests selected by
ars.digest-algos.
Evidence claims passed to the relying party#
Only ECTs with a claims-from-evidence environment OID
produce dynamic attester claims.
Accepted top-level EAT fields stay parser inputs and never become claims.
A value reaches ear_attester_claims only when
a claims-from-evidence ECT encodes it.
The certificate-derived hwmodel fallback below is the one exception.
The OID must be under the NVIDIA CoRIM arc,
with 2 as its penultimate arc:
1.3.6.1.4.1.5703.1300.<path>.2.<leaf>
Each claims-from-evidence ECT must contain exactly one measurement. Its measurement key must be text and becomes the claim name in the EAR. Exactly one of these measurement values supplies the claim value:
Measurement value |
EAR value |
|---|---|
|
The text value. |
|
The bytes interpreted as UTF-8 text. |
|
The version value without its scheme. |
Claim names and values are strings. Invalid UTF-8, a duplicate claim name, or an invalid claims-from-evidence ECT fails appraisal.
A claim is corroborated when a compatible reference ECT
has a passing comparison.
A claim with no compatible reference or a failing comparison
is uncorroborated.
Forwarded claim values appear in
submods.<label>.ear_attester_claims.
Environment comparison results appear separately in
ear_verifier_claims.ear_nvidia_evidence_rim_cmp.
Claim names come from the measurement keys rather than a fixed list.
When no evidence claim is named hwmodel,
the verifier adds one from the validated end-entity certificate’s
DMTF otherName product field.
An evidence-supplied hwmodel takes precedence.
The corroborated root purpose is emitted separately as ear_nvidia_purpose.
AR4SI trustworthiness vectors are not supported. Appraisal policy identifiers are not emitted.
Local appraisal workflow#
Initialize the SDK once, collect evidence with a nonce, and build a CMW:
nvat_nonce_t nonce = NULL;
nvat_gpu_evidence_source_t source = NULL;
nvat_gpu_evidence_t *evidence = NULL;
size_t evidence_count = 0;
nvat_cmw_collection_t cmw = NULL;
nvat_str_t serialized_cmw = NULL;
nvat_rc_t rc = nvat_nonce_create(&nonce, 32);
if (rc == NVAT_RC_OK)
rc = nvat_gpu_evidence_source_nvml_create(&source);
if (rc == NVAT_RC_OK)
rc = nvat_gpu_evidence_collect(source, nonce, &evidence, &evidence_count);
if (rc == NVAT_RC_OK)
rc = nvat_cmw_collection_create_from_gpu_evidence(
&cmw, evidence, evidence_count, nonce);
if (rc == NVAT_RC_OK)
rc = nvat_cmw_collection_serialize(
cmw, NVAT_CMW_FORMAT_JSON, &serialized_cmw);
For an existing SPDM measurement transcript and PEM certificate chain, use
nvat_cmw_collection_create_from_spdm_transcript() instead. Pass the
expected nonce when the application requires freshness checking.
Create a CoRIM store and an AIA OCSP client before creating the verifier:
nvat_corim_store_t store = NULL;
nvat_ocsp_client_t aia_ocsp = NULL;
nvat_local_corim_verifier_t verifier = NULL;
rc = nvat_corim_store_create(&store, service_key, http_options);
if (rc == NVAT_RC_OK)
rc = nvat_ocsp_client_create_aia(
&aia_ocsp, NULL, service_key, http_options, NULL, NULL, 0);
if (rc == NVAT_RC_OK)
rc = nvat_local_corim_verifier_create(&verifier, &store, aia_ocsp);
The verifier takes ownership of store on success. CoRIM signature and
certificate revocation verification are enabled by default. URL rewrites and
additional allowed prefixes must be configured on the store before it is passed
to the verifier. Use the signature and revocation toggles only with controlled
test artifacts. See Configure the CoRIM verifier for
store caching, source configuration, fallbacks, input digests, and HTTP/TLS
settings.
Create EAR signing options and appraise the serialized CMW:
nvat_ear_signing_options_t signing = NULL;
nvat_str_t ear_jwt = NULL;
nvat_str_t ear_json = NULL;
char *cmw_data = NULL;
size_t cmw_len = 0;
rc = nvat_detached_eat_options_create(
&signing, signing_key_pem, "https://verifier.example.com", "key-1");
if (rc == NVAT_RC_OK)
rc = nvat_str_get_data(serialized_cmw, &cmw_data);
if (rc == NVAT_RC_OK)
rc = nvat_str_length(serialized_cmw, &cmw_len);
if (rc == NVAT_RC_OK)
rc = nvat_local_corim_verifier_verify_cmw(
verifier, (const uint8_t *)cmw_data, cmw_len, NVAT_CMW_FORMAT_JSON,
signing, &ear_jwt, &ear_json);
Sign production EARs with a signing key. The issuer should be the HTTPS
verifier base URL that the relying party will select, and kid must identify
the corresponding JWKS key. Unsigned alg=none EARs are for tests only.
Relying-party policy#
For a locally produced EAR, apply Rego directly to the returned JSON. The
complete EAR JSON object is supplied to the policy as input. The policy must
declare package policy and define nv_match as a boolean decision. The SDK
evaluates that rule at data.policy.nv_match:
nvat_relying_party_policy_t policy = NULL;
char *json = NULL;
rc = nvat_relying_party_policy_create_rego_from_str(&policy, policy_text);
if (rc == NVAT_RC_OK)
rc = nvat_str_get_data(ear_json, &json);
if (rc == NVAT_RC_OK)
rc = nvat_apply_relying_party_policy_to_ear(policy, json);
NVAT_RC_RP_POLICY_MISMATCH means the policy rejected the appraisal. It does
not mean that EAR generation or signature verification failed.
Signed EARs at a remote relying party#
EAR JSON received across a process or network boundary is untrusted. Send the compact JWT and authenticate it before evaluating policy:
nvat_str_t verified_ear_json = NULL;
char *json = NULL;
rc = nvat_verify_ear(
signed_ear_jwt, verifier_base_url, service_key, expected_nonce,
http_options, NULL /* jwt_validation_options */, &verified_ear_json);
if (rc == NVAT_RC_OK)
rc = nvat_str_get_data(verified_ear_json, &json);
if (rc == NVAT_RC_OK)
rc = nvat_apply_relying_party_policy_to_ear(policy, json);
nvat_str_free(&verified_ear_json);
The relying party selects a non-empty HTTPS verifier URL. The SDK obtains its
JWKS from <verifier_base_url>/.well-known/jwks.json, verifies the JWT
signature and issuer, and returns EAR JSON only after authentication succeeds.
It does not validate EAR schema or decide whether the appraisal is acceptable.
service_key is optional. It is sent only to HTTPS nvidia.com hosts and
subdomains, and is suppressed for other verifier URLs. If expected_nonce is
provided, the signed eat_nonce must match it. The returned EAR string is NULL
on every failure and must be released with nvat_str_free() on success.
CLI equivalent#
The command-line version of this flow is documented in the
CoRIM workflow:
collect-evidence-v2, attest-v2, then
verify-token --token-type ear at a relying-party boundary.