You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Both certification guides had claims that are wrong on current releases. Every claim was checked against primary sources (the crates, @icp-sdk/core 6.1.0, ic-gateway, the interface spec, icp-cli v1.5.0 cli.md), and every code block was compiled and run against a local network. The skill side of the same fixes is dfinity/icskills#407.
Wrong, now fixed:
"Certified data is cleared on upgrade" (5 places): it survives upgrades (abstract-behavior.md, confirmed locally). What is lost is a heap tree, so Rust rebuilds it in post_upgrade, and Motoko's CertTree.Store needs no hook.
Header name:IC-Certificate-Expression is really IC-CertificateExpression (gateway spec, crate constant, served headers).
icp canister call … get without --query: icp-cli sends an update call by default, so no certificate comes back.
Client verification code: it did not type-check against @dfinity/certificate-verification 4 (Uint8Array, not ArrayBuffer). lookupResultToBuffer treated Unknown as absent; it now switches on the lookup_path status.
The "custom HTTP client" case needs @dfinity/response-verification, not certificate-verification. This is now a "who verifies what" table (HTTP gateway, update calls, Candid queries, raw hosts).
The ic-asset-certification example did not compile (missing candid, 404 needs StatusCode). Its uncertified 404 was rejected by the gateway; it now uses a certified 404.html fallback.
Rust example: it lacked export_candid!(), so icp deploy failed. It now uses ic-certification 4 / ic-cdk 0.20.
The single-value Motoko example never certified its initial value, so a query before the first write failed verification (certified data starts empty).
Motoko CertTree example did not compile (CertTree.Ops must be transient). The deprecated postupgrade hook is removed, and remove becomes delete to match the test commands.
allow_raw_access: false: redirects with 308, but raw.icp.net lands on <id>.icp0.io, and only mainnet raw hosts are recognized.
Asset canister certified headers: also Cache-Control (with max_age) and Content-Encoding.
Intro: it linked "boundary nodes" to the API boundary nodes, which verify nothing.
Root key:shouldFetchRootKey is replaced by the ic_env cookie / icp network status --json.
Links: the js.icp.build link is dropped (that site does not document this package), and certified-counter (dfx, fetchRootKey) is replaced by motoko/cert-var.
After review:
The gateway guarantee is scoped to verifying hostnames.
The two certification headers are described accurately (certificate and witness vs CEL expression).
certified_data_set is described as allowed in every replicated context, per the spec.
Structural note: the asset and Rust examples stay inline even though they exceed the 30-line guideline, as before. They could move to dfinity/examples with #region markers.
Fixes claims that were wrong or outdated: certified data survives upgrades,
the certification header is IC-CertificateExpression, icp canister call needs
--query to return a certificate, and raw-access redirects land on icp0.io.
Code examples now compile and verify against ic-cdk 0.20, the 4.x
certification crates and @dfinity/certificate-verification 4.
Scope the gateway guarantee to verifying hostnames, describe what each
certification header carries, name every context certified_data_set
allows, and state that the Rust example keeps its tree on the heap only.
… root key
certified_data_set is allowed in init, upgrade hooks, updates, reply and reject
callbacks and system tasks, not in cleanup callbacks or any query. The ic_env
root key is only trustworthy on a verifying hostname.
certified_data_set now lists the spec's allowed contexts explicitly, including pre_upgrade and the low-Wasm-memory hook, and excludes cleanup callbacks and queries.
The ic_env root key is scoped to verifying hostnames; a client verifying raw responses needs an independently obtained key.
This helper is presented as the verifier for the Motoko getter above, but that getter returns certificate : ?Blob. Its generated response therefore has an optional certificate, so it cannot be passed to this { certificate: Uint8Array } parameter without an unchecked unwrap. Accept the nullable field and fail explicitly when the getter was not executed as a query before calling Certificate.create.
Both verification helpers accept the ?blob certificate that the Motoko getters return (Uint8Array | null), and fail with a clear message when it is null (the getter was not called as a query). Verified against live Rust and Motoko canisters, including the null case.
This helper is presented after both implementations, but the Motoko CertTree getter returns value : ?Blob, which bindgen exposes as Uint8Array | null; the declared string | null input therefore does not type-check with that example. Normalize the blob value before comparing it, or explicitly scope the helper to the Rust getter.
“The response can be passed as is” is not true for the Motoko CertTree response linked from this section: its value : ?Blob becomes Uint8Array | null, while the helper accepts string | null. Clarify that only the certificate and witness already match, and that blob values must be decoded first.
The witness helper accepts both getters' responses as returned: the Rust opt text value and the Motoko CertTree?Blob value (Uint8Array | null, decoded as UTF-8). The frontend guide no longer claims the response passes "as is" without saying which fields.
Verified with the raw responses of both live canisters, including an absent key and a tampered value.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Both certification guides had claims that are wrong on current releases. Every claim was checked against primary sources (the crates,
@icp-sdk/core6.1.0, ic-gateway, the interface spec, icp-cli v1.5.0cli.md), and every code block was compiled and run against a local network. The skill side of the same fixes is dfinity/icskills#407.Wrong, now fixed:
abstract-behavior.md, confirmed locally). What is lost is a heap tree, so Rust rebuilds it inpost_upgrade, and Motoko'sCertTree.Storeneeds no hook.IC-Certificate-Expressionis reallyIC-CertificateExpression(gateway spec, crate constant, served headers).icp canister call … getwithout--query: icp-cli sends an update call by default, so no certificate comes back.@dfinity/certificate-verification4 (Uint8Array, notArrayBuffer).lookupResultToBuffertreatedUnknownas absent; it now switches on thelookup_pathstatus.@dfinity/response-verification, notcertificate-verification. This is now a "who verifies what" table (HTTP gateway, update calls, Candid queries, raw hosts).ic-asset-certificationexample did not compile (missingcandid,404needsStatusCode). Its uncertified 404 was rejected by the gateway; it now uses a certified404.htmlfallback.export_candid!(), soicp deployfailed. It now usesic-certification4 /ic-cdk0.20.CertTreeexample did not compile (CertTree.Opsmust betransient). The deprecatedpostupgradehook is removed, andremovebecomesdeleteto match the test commands.allow_raw_access: false: redirects with308, butraw.icp.netlands on<id>.icp0.io, and only mainnet raw hosts are recognized.Cache-Control(withmax_age) andContent-Encoding.shouldFetchRootKeyis replaced by theic_envcookie /icp network status --json.js.icp.buildlink is dropped (that site does not document this package), andcertified-counter(dfx,fetchRootKey) is replaced bymotoko/cert-var.After review:
certified_data_setis described as allowed in every replicated context, per the spec.static-site/how-it-works.mdhas the same wording; it is fixed upstream in docs: say the gateway forwards the certificate on raw hosts certified-assets#139 and already synced tomainin chore: sync static-site docs to dfinity/certified-assets 853c291 #409.Structural note: the asset and Rust examples stay inline even though they exceed the 30-line guideline, as before. They could move to
dfinity/exampleswith#regionmarkers.