Skip to content

docs: data integrity security guide#82

Merged
marc0olo merged 2 commits into
mainfrom
docs/guides-security-data-integrity
Apr 16, 2026
Merged

docs: data integrity security guide#82
marc0olo merged 2 commits into
mainfrom
docs/guides-security-data-integrity

Conversation

@marc0olo
Copy link
Copy Markdown
Member

Summary

  • On-chain encryption with vetKeys: full Rust (ic-vetkeys KeyManager and direct management canister API) and Motoko implementations with mo:core imports; TypeScript frontend using @dfinity/vetkeys
  • Identity-based encryption (IBE): TypeScript patterns for encrypting to a principal without them being online
  • Certified variables overview pointing to the full implementation guide
  • Signature verification: IC ingress message schemes, X.509 certificate authority pattern using threshold signing keys
  • Deploy and test using icp CLI commands
  • All code verified against dfinity/cdk-rs management-canister-types (VetKDCurve, VetKDDeriveKeyArgs)

Sync recommendation

informed by dfinity/icskills — canister-security skill, vetkd skill; dfinity/cdk-rs — ic-management-canister-types; dfinity/examples — rust/vetkd, motoko/vetkd

@marc0olo
Copy link
Copy Markdown
Member Author

Review: Data Integrity

Must fix

  • Inline code blocks exceed 30-line limit: Per content-authoring.md, code snippets over 30 lines must link to dfinity/examples on GitHub rather than be inlined (when no #region markers exist). The following code blocks are over 30 lines: the Rust KeyManager init/get_encrypted_vetkey/get_vetkey_verification_key block (~56 lines), the management canister direct-call Rust block (~48 lines), the Motoko implementation block (~68 lines), and the TypeScript frontend block (~46 lines). Checked: no #region markers exist in .sources/examples/rust/vetkd or .sources/examples/motoko/vetkd. Since these are synthesis patterns (not verbatim from dfinity/examples), the appropriate fallback is to link to dfinity/vetkeys examples (which the page already does for IBE). Consider splitting the long Rust KeyManager block into shorter focused snippets, or adding a note in the PR description: "used inline code for vetKeys patterns — no #region markers in .sources/examples yet, patterns are from ic-vetkeys/icskills not directly from dfinity/examples." This documents the intentional deviation and is acceptable per the fallback policy.

  • encryption.md next-steps link targets an unwritten stub: The "Next steps" section links to ./encryption.md with description "full vetKeys encryption patterns including EncryptedMaps". That page is still a TODO stub. The link itself is valid (file exists), but the description overpromises — a reader clicking it will find no content. Either omit the description qualifier or note it as "coming soon."

Suggestions

  • Signature verification external link points only to Rust validator: The page says "See the independently verifying IC signatures documentation for details" after mentioning both the Rust crate AND the @dfinity/standalone-sig-verifier-web JavaScript library. The link only goes to the Rust side. Adding a separate link to the JS library (https://www.npmjs.com/package/@dfinity/standalone-sig-verifier-web or the portal's standalone-sig-verifier page) would be more complete, since developers choosing the JS path have no direct link from the page.

  • vetKeys note about API stability is missing from the page: The vetkd skill (and the vetKeys library itself) includes an important caveat that ic-vetkeys and @dfinity/vetkeys APIs may still change. The skill says: "Pin your dependency versions and check the DFINITY forum for any migration guides after upgrades." The page doesn't include this caveat anywhere. Given that the page shows version-pinned dependencies (ic-vetkeys = "0.6", ic-stable-structures = "0.7"), a brief callout that these versions should be re-checked periodically would help developers avoid surprise breakage.

  • test_key_1 works on mainnet too: The key names table says test_key_1 environment is "Local + mainnet (testing)" — this is correct. However, the inline prose "Use test_key_1 during development. Switch to key_1 before production deployment." could be read as implying test_key_1 only works locally. The table caption is correct; the prose could say "Use test_key_1 during development and mainnet testing. Switch to key_1 for production." to be clearer.

  • Certified variables section could mention post_upgrade requirement more prominently: The "Key rules" bullet list says "Re-certify data in post_upgrade — certified data is cleared on upgrade." This is good. But it's easy to miss. The certified-variables skill lists this as mistake docs: getting-started what-next page #7 with explicit emphasis. This is only a suggestion since the rule is present; it's already correct.

  • IBE section missing access-control warning: The vetkd skill (pitfall docs: timers guide #9) notes: "If you implement IBE manually (bypassing KeyManager/EncryptedMaps), your canister must enforce that vetkd_derive_key only returns the derived key to the authorized caller." The page shows an IBE TypeScript example without a corresponding canister-side snippet, so a developer following the IBE section alone wouldn't see the access control requirement. A brief note like "The canister must verify caller == recipient_principal before calling vetkd_derive_key" would close this gap.

Verified

  • All internal links resolve: ../../concepts/security.md, ../../concepts/vetkeys.md, ../backends/certified-variables.md, ./encryption.md — all four targets exist on disk.
  • Frontmatter complete: title, description, and sidebar.order all present. Description accurately matches body content.
  • No banned patterns: No dfx references, no mo:base imports, no internetcomputer.org/docs/ links, no docs.internetcomputer.org links.
  • Motoko imports correct: All imports use mo:core/... (Blob, Principal, Text). persistent actor used correctly.
  • Rust API paths correct: ic_cdk::management_canister::{VetKDCurve, VetKDDeriveKeyArgs, VetKDKeyId, VetKDPublicKeyArgs} is the correct (non-deprecated) import path, verified against .sources/examples/rust/vetkd/src/app_backend/src/lib.rs.
  • VetKDCurve enum variants correct: VetKDCurve::Bls12_381_G2 in the direct management canister Rust code (matches ic-management-canister-types/src/lib.rs); VetKDCurve::Bls12381G2 in the ic-vetkeys KeyManager code (matches icskills/vetkd/SKILL.md).
  • Cycle cost claims correct: test_key_1 ~10B cycles, key_1 ~26B cycles — both match vetkd skill's cost table (exact: 10_000_000_000 and 26_153_846_153).
  • ic-cdk auto-attaches cycles claim correct: Verified against .sources/cdk-rs/ic-cdk/src/management_canister.rs documentation — vetkd_derive_key does automatically calculate and attach required cycles.
  • CLI commands verified: icp network start -d, icp deploy backend, icp deploy backend -e ic, icp canister call backend getPublicKey '()' — all verified against .sources/icp-cli/docs/reference/cli.md. The -d flag is --background (correct).
  • Upstream comment present: At bottom of file: <!-- Upstream: informed by dfinity/portal — ...; dfinity/icskills — canister-security, vetkd, certified-variables; dfinity/examples — rust/vetkd, motoko/vetkd, rust/x509 -->.
  • Content brief coverage: All items from the brief are addressed — vetKeys encryption, IBE patterns, X.509 certificate handling, signature verification for external data, certified variables for data authenticity, and encrypted-notes example references.
  • Build passes: npm run build completes with 86 pages, no errors from this page.
  • x509 example claims accurate: The page correctly describes the x509 example's three-step pattern (verify CSR signature, verify ownership, sign child certificate) — confirmed against .sources/examples/rust/x509/src/x509_example_rust/src/wasm_only.rs.
  • toDerivedKeyMaterial() usage correct: Matches the vetkd skill's TypeScript pattern exactly.
  • Offline public key derivation API correct: MasterPublicKey.productionKey() and masterKey.deriveCanisterKey(canisterId) match the vetkd skill.
  • IBE TypeScript API correct: IbeCiphertext.encrypt, IbeCiphertext.deserialize, deserialized.decrypt(vetKey) all match the vetkd skill's IBE section.
  • Onchain/offchain spelling: Uses "onchain" (no hyphen) — correct per content-authoring.md rules.
  • No TODO/verification-flag comments left in page: Page is clean of authoring artifacts.

- Split code blocks exceeding 30-line limit into focused sub-30-line
  snippets with descriptive prose between them
- Fix encryption.md next-steps link description to say "coming soon"
  instead of overpromising on stub content
- Add API stability callout after prerequisites (ic-vetkeys/vetkeys
  APIs may still change; pin versions and check forum before upgrading)
- Clarify test_key_1 prose: "development and mainnet testing" vs "production"
- Add IBE access-control warning: verify caller == recipient_principal
  before calling vetkd_derive_key when not using KeyManager
- Add JS library link alongside Rust validator for signature verification
@marc0olo
Copy link
Copy Markdown
Member Author

<!-- feedback-addressed -->

Feedback addressed: PR #82 — Data Integrity guide

Changes applied

Must fix — code blocks exceeding 30-line limit:
The Rust KeyManager block (~57 lines), direct-call Rust block (~48 lines), Motoko block (~69 lines), TypeScript frontend block (~47 lines), and IBE TypeScript block (~31 lines) all exceeded the 30-line inline limit per content-authoring.md. Since these are synthesis patterns (not verbatim from dfinity/examples — confirmed: no #region markers exist in .sources/examples/rust/vetkd or .sources/examples/motoko/vetkd), each block was split into two focused sub-30-line snippets with brief connecting prose, following the fallback policy for synthesis patterns.

Must fix — encryption.md next-steps link overpromises:
Changed the description from "full vetKeys encryption patterns including EncryptedMaps" to "vetKeys encryption patterns including EncryptedMaps (coming soon)" to set correct expectations for the stub page.

Suggestion applied — API stability caveat:
Added a blockquote note after the Prerequisites section: "The ic-vetkeys crate and @dfinity/vetkeys package are published but their APIs may still change. Pin the versions above and check the DFINITY forum for migration guides before upgrading." Confirmed against vetkd skill (Mistake #1 and the top-level note).

Suggestion applied — test_key_1 prose clarity:
Changed "Use test_key_1 during development. Switch to key_1 before production deployment." to "Use test_key_1 during development and mainnet testing. Switch to key_1 for production." The table already correctly shows test_key_1 works on both local and mainnet; the prose now matches.

Suggestion applied — IBE access-control warning:
Added a blockquote before the IBE example: "If you implement IBE without using KeyManager or EncryptedMaps, your canister must verify that caller == recipient_principal before calling vetkd_derive_key." Verified against vetkd skill Pitfall #9.

Suggestion applied — JS signature verification link:
Added a link to @dfinity/standalone-sig-verifier-web on npm alongside the existing Rust validator link.

Changes skipped

Suggestion — certified variables post_upgrade prominence: The post_upgrade requirement is already present in the Key rules bullet list. The reviewer rated this as "only a suggestion since the rule is present; it's already correct." No change needed.

Build verification

npm run build completed successfully: 86 pages built, no errors from this page. A pre-existing build failure in docs/guides/backends/https-outcalls.mdx (references .sources/examples/motoko/send_http_get which is not cloned in this worktree) was confirmed unrelated to this PR's changes.

@marc0olo marc0olo merged commit 4c74299 into main Apr 16, 2026
1 check passed
@marc0olo marc0olo deleted the docs/guides-security-data-integrity branch April 16, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant