[{"data":1,"prerenderedAt":698},["ShallowReactive",2],{"navigation":3,"/sdks/conformance-vectors":258,"/sdks/conformance-vectors-surround":693},[4,22,63,85,115,131,219,245],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Getting Started","/getting-started","1.getting-started",[9,13,17],{"title":10,"path":11,"stem":12},"Introduction","/getting-started/introduction","1.getting-started/1.introduction",{"title":14,"path":15,"stem":16},"Quick Start","/getting-started/quick-start","1.getting-started/2.quick-start",{"title":18,"path":19,"stem":20},"Key Concepts","/getting-started/key-concepts","1.getting-started/3.key-concepts",false,{"title":23,"path":24,"stem":25,"children":26,"page":21},"Guides","/guides","2.guides",[27,31,35,39,43,47,51,55,59],{"title":28,"path":29,"stem":30},"Quick Share Guide","/guides/quick-share","2.guides/1.quick-share",{"title":32,"path":33,"stem":34},"Slack Integration","/guides/slack-integration","2.guides/2.slack-integration",{"title":36,"path":37,"stem":38},"Enterprise Setup","/guides/enterprise-setup","2.guides/3.enterprise-setup",{"title":40,"path":41,"stem":42},"Creating a Share","/guides/creating-a-share","2.guides/4.creating-a-share",{"title":44,"path":45,"stem":46},"Zero-Knowledge Custody","/guides/zero-knowledge-custody","2.guides/5.zero-knowledge-custody",{"title":48,"path":49,"stem":50},"Secure Requests","/guides/secure-requests","2.guides/6.secure-requests",{"title":52,"path":53,"stem":54},"Receiving a Secure Request","/guides/receiving-a-secure-request","2.guides/7.receiving-a-secure-request",{"title":56,"path":57,"stem":58},"SecurePaste","/guides/securepaste","2.guides/8.securepaste",{"title":60,"path":61,"stem":62},"Notifications","/guides/notifications","2.guides/9.notifications",{"title":64,"icon":65,"path":66,"stem":67,"children":68,"page":21},"Account","i-lucide-user-cog","/account","3.account",[69,73,77,81],{"title":70,"path":71,"stem":72},"Signing In","/account/signing-in","3.account/1.signing-in",{"title":74,"path":75,"stem":76},"Plans and Share Allowance","/account/plans-and-share-allowance","3.account/2.plans-and-share-allowance",{"title":78,"path":79,"stem":80},"Billing and Subscription","/account/billing-and-subscription","3.account/3.billing-and-subscription",{"title":82,"path":83,"stem":84},"Plans and Limits","/account/plans-and-limits","3.account/4.plans-and-limits",{"title":86,"icon":87,"path":88,"stem":89,"children":90,"page":21},"Teams","i-lucide-users","/teams","4.teams",[91,95,99,103,107,111],{"title":92,"path":93,"stem":94},"Teams and Contexts","/teams/teams-and-contexts","4.teams/1.teams-and-contexts",{"title":96,"path":97,"stem":98},"Members, Roles and Seats","/teams/members-roles-and-seats","4.teams/2.members-roles-and-seats",{"title":100,"path":101,"stem":102},"Joining a Team","/teams/joining-a-team","4.teams/3.joining-a-team",{"title":104,"path":105,"stem":106},"Custom Branding","/teams/custom-branding","4.teams/4.custom-branding",{"title":108,"path":109,"stem":110},"Policy and Audit","/teams/policy-and-audit","4.teams/5.policy-and-audit",{"title":112,"path":113,"stem":114},"Zero-Knowledge for Teams","/teams/zero-knowledge-for-teams","4.teams/6.zero-knowledge-for-teams",{"title":116,"path":117,"stem":118,"children":119,"icon":130},"Help","/help","5.help/0.index",[120,122,126],{"title":121,"path":117,"stem":118},"Help and Support",{"title":123,"path":124,"stem":125},"Link Not Working","/help/link-not-working","5.help/1.link-not-working",{"title":127,"path":128,"stem":129},"Error Messages","/help/error-messages","5.help/2.error-messages","i-lucide-life-buoy",{"title":132,"path":133,"stem":134,"children":135},"API Reference","/api","6.api/0.index",[136,137,141,167,189,193,211,215],{"title":132,"path":133,"stem":134},{"title":138,"path":139,"stem":140},"Authentication","/api/authentication","6.api/1.authentication",{"title":142,"path":143,"stem":144,"children":145},"Shares","/api/shares","6.api/2.shares/0.index",[146,147,151,155,159,163],{"title":142,"path":143,"stem":144},{"title":148,"path":149,"stem":150},"Create a share","/api/shares/create","6.api/2.shares/1.create",{"title":152,"path":153,"stem":154},"List shares","/api/shares/list","6.api/2.shares/2.list",{"title":156,"path":157,"stem":158},"Retrieve a share","/api/shares/retrieve","6.api/2.shares/3.retrieve",{"title":160,"path":161,"stem":162},"Expire a share","/api/shares/delete","6.api/2.shares/4.delete",{"title":164,"path":165,"stem":166},"Client-side encryption","/api/shares/client-side-encryption","6.api/2.shares/5.client-side-encryption",{"title":168,"path":169,"stem":170,"children":171},"Secure requests","/api/requests","6.api/3.requests/0.index",[172,173,177,181,185],{"title":168,"path":169,"stem":170},{"title":174,"path":175,"stem":176},"Create a request","/api/requests/create","6.api/3.requests/1.create",{"title":178,"path":179,"stem":180},"List and retrieve requests","/api/requests/list","6.api/3.requests/2.list",{"title":182,"path":183,"stem":184},"Read submissions","/api/requests/submissions","6.api/3.requests/3.submissions",{"title":186,"path":187,"stem":188},"Expire or delete a request","/api/requests/delete","6.api/3.requests/4.delete",{"title":190,"path":191,"stem":192},"Stats","/api/stats","6.api/4.stats",{"title":194,"path":195,"stem":196,"children":197},"Webhooks","/api/webhooks","6.api/5.webhooks/0.index",[198,199,203,207],{"title":194,"path":195,"stem":196},{"title":200,"path":201,"stem":202},"Event reference","/api/webhooks/events","6.api/5.webhooks/1.events",{"title":204,"path":205,"stem":206},"Verifying signatures","/api/webhooks/verifying-signatures","6.api/5.webhooks/2.verifying-signatures",{"title":208,"path":209,"stem":210},"Delivery and retries","/api/webhooks/delivery-and-retries","6.api/5.webhooks/3.delivery-and-retries",{"title":212,"path":213,"stem":214},"MCP server","/api/mcp","6.api/6.mcp",{"title":216,"path":217,"stem":218},"Errors and Rate Limits","/api/errors-and-limits","6.api/7.errors-and-limits",{"title":220,"path":221,"stem":222,"children":223},"SDKs","/sdks","7.sdks/0.index",[224,225,229,233,237,241],{"title":220,"path":221,"stem":222},{"title":226,"path":227,"stem":228},"Node SDK","/sdks/node","7.sdks/1.node",{"title":230,"path":231,"stem":232},"Python SDK","/sdks/python","7.sdks/2.python",{"title":234,"path":235,"stem":236},"Go SDK","/sdks/go","7.sdks/3.go",{"title":238,"path":239,"stem":240},"Rust SDK","/sdks/rust","7.sdks/4.rust",{"title":242,"path":243,"stem":244},"Conformance vectors","/sdks/conformance-vectors","7.sdks/5.conformance-vectors",{"title":246,"path":247,"stem":248,"children":249,"page":21},"Security","/security","8.security",[250,254],{"title":251,"path":252,"stem":253},"Encryption","/security/encryption","8.security/1.encryption",{"title":255,"path":256,"stem":257},"Compliance","/security/compliance","8.security/2.compliance",{"id":259,"title":242,"api":260,"body":261,"description":687,"extension":688,"links":260,"meta":689,"navigation":690,"path":243,"seo":691,"stem":244,"__hash__":692},"docs/7.sdks/5.conformance-vectors.md",null,{"type":262,"value":263,"toc":680},"minimark",[264,268,271,276,284,372,394,397,401,443,459,475,496,510,533,537,545,560,563,599,603,606,638,641,645,652,659,662,676],[265,266,267],"p",{},"The CredenShare application and the four SDKs share no code. That is deliberate: a package the production application depended on would be a supply-chain surface, and for a product whose claim is that we cannot read your data, it is the wrong surface to open.",[265,269,270],{},"The cost of that decision is drift between five independent implementations. Drift here does not produce a test failure — it produces content that can never be decrypted. The mitigation is a specification plus a fixture that every implementation must reproduce byte for byte.",[272,273,275],"h2",{"id":274},"what-ships","What ships",[265,277,278,279,283],{},"Every client embeds the same fixture ",[280,281,282],"strong",{},"inside the installed artifact",", so you can check the exact build you installed rather than a copy in a repository you are trusting to match.",[285,286,287,303],"table",{},[288,289,290],"thead",{},[291,292,293,297,300],"tr",{},[294,295,296],"th",{},"Client",[294,298,299],{},"Path",[294,301,302],{},"Mechanism",[304,305,306,325,338,353],"tbody",{},[291,307,308,312,318],{},[309,310,311],"td",{},"Node",[309,313,314],{},[315,316,317],"code",{},"conformance-vectors.json",[309,319,320,321,324],{},"imported with ",[315,322,323],{},"with { type: 'json' }",", so it works where there is no filesystem",[291,326,327,330,335],{},[309,328,329],{},"Python",[309,331,332],{},[315,333,334],{},"vectors.v1.json",[309,336,337],{},"package data",[291,339,340,343,347],{},[309,341,342],{},"Go",[309,344,345],{},[315,346,334],{},[309,348,349,352],{},[315,350,351],{},"//go:embed",", so it travels inside the compiled binary",[291,354,355,358,363],{},[309,356,357],{},"Rust",[309,359,360],{},[315,361,362],{},"src/vectors.v1.json",[309,364,365,368,369],{},[315,366,367],{},"include_str!",", re-exported as ",[315,370,371],{},"conformance::VECTORS_JSON",[373,374,377],"callout",{"color":375,"icon":376},"info","i-lucide-info",[265,378,379,380,382,383,385,386,389,390,393],{},"The Node package names its copy ",[315,381,317],{},"; the other three use ",[315,384,334],{},". ",[280,387,388],{},"The bytes are identical"," — 7,849 bytes, SHA-256 ",[315,391,392],{},"91e70661be51edbc4522d202c533292d1eac92691d1fbb02e9eaa13eb23a582c"," in all four. Only the filename differs, which matters if you are hashing the path in CI.",[265,395,396],{},"Each repository pins that digest in its own test suite, so editing the fixture in one client fails that client's build rather than silently redefining the standard.",[272,398,400],{"id":399},"running-it","Running it",[402,403,408],"pre",{"className":404,"code":405,"filename":311,"language":406,"meta":407,"style":407},"language-bash shiki shiki-themes github-light github-dark github-dark","npx --package @credenshare/sdk credenshare-conformance\nnode dist/conformance-cli.js          # from a built clone\n","bash","",[315,409,410,430],{"__ignoreMap":407},[411,412,415,419,423,427],"span",{"class":413,"line":414},"line",1,[411,416,418],{"class":417},"shcOC","npx",[411,420,422],{"class":421},"suiK_"," --package",[411,424,426],{"class":425},"sfrk1"," @credenshare/sdk",[411,428,429],{"class":425}," credenshare-conformance\n",[411,431,433,436,439],{"class":413,"line":432},2,[411,434,435],{"class":417},"node",[411,437,438],{"class":425}," dist/conformance-cli.js",[411,440,442],{"class":441},"sCsY4","          # from a built clone\n",[402,444,446],{"className":404,"code":445,"filename":329,"language":406,"meta":407,"style":407},"python -m credenshare.conformance\n",[315,447,448],{"__ignoreMap":407},[411,449,450,453,456],{"class":413,"line":414},[411,451,452],{"class":417},"python",[411,454,455],{"class":421}," -m",[411,457,458],{"class":425}," credenshare.conformance\n",[402,460,462],{"className":404,"code":461,"filename":342,"language":406,"meta":407,"style":407},"go run github.com/CredenShare/credenshare-sdk-go/cmd/credenshare-conformance@latest\n",[315,463,464],{"__ignoreMap":407},[411,465,466,469,472],{"class":413,"line":414},[411,467,468],{"class":417},"go",[411,470,471],{"class":425}," run",[411,473,474],{"class":425}," github.com/CredenShare/credenshare-sdk-go/cmd/credenshare-conformance@latest\n",[402,476,478],{"className":404,"code":477,"filename":357,"language":406,"meta":407,"style":407},"cargo run --bin credenshare-conformance     # from a clone only\n",[315,479,480],{"__ignoreMap":407},[411,481,482,485,487,490,493],{"class":413,"line":414},[411,483,484],{"class":417},"cargo",[411,486,471],{"class":425},[411,488,489],{"class":421}," --bin",[411,491,492],{"class":425}," credenshare-conformance",[411,494,495],{"class":441},"     # from a clone only\n",[265,497,498,499,502,503,506,507,509],{},"All four take ",[315,500,501],{},"-v"," for one line per check — under cargo write ",[315,504,505],{},"-- -v",", since a bare ",[315,508,501],{}," is consumed by cargo itself. None needs a test runner, and all exit non-zero on failure, so they work as a deployment gate. Run one in the environment that will actually do the encrypting — a client that fails these produces content nothing else can read, and the failure is otherwise invisible until somebody opens a link.",[265,511,512,513,516,517,520,521,524,525,528,529,532],{},"Cargo does not expose a dependency's binary targets, so Rust projects that merely depend on the crate should call ",[315,514,515],{},"credenshare::conformance::run"," from their own test suite instead. All four expose the checks programmatically for that purpose — Node from its ",[315,518,519],{},"./conformance"," subpath export, Python as ",[315,522,523],{},"credenshare.conformance",", Go as ",[315,526,527],{},"ConformanceChecks()",", and Rust as ",[315,530,531],{},"conformance::run",".",[272,534,536],{"id":535},"the-24-checks","The 24 checks",[402,538,543],{"className":539,"code":541,"language":542,"meta":407},[540],"language-text","hkdf/empty salt, short info\nhkdf/16-byte salt\nhkdf/output longer than one SHA-256 block, exercising the counter\nfragment/encode\nfragment/decode\nfragment/rejects/0/missing-key\nfragment/rejects/1/malformed-key\nfragment/rejects/2/malformed-key\naccess_token\npasscode_verifier/0\npasscode_verifier/1\npasscode_verifier/2\ncontent/no passcode/encrypt\ncontent/no passcode/decrypt\ncontent/passcode mixed into info, not into the salt/encrypt\ncontent/passcode mixed into info, not into the salt/decrypt\ncontent/characters a JSON serialiser may mangle: HTML escapes, quotes, unicode/encrypt\ncontent/characters a JSON serialiser may mangle: HTML escapes, quotes, unicode/decrypt\nseed_keypair/recipient seed\nseed_keypair/ephemeral seed\ncustody_keypair\necdh_wrap/wrap\necdh_wrap/unwrap\necdh_wrap/roundtrip\n","text",[315,544,541],{"__ignoreMap":407},[265,546,547,548,551,552,555,556,559],{},"Five of those — ",[315,549,550],{},"fragment/decode",", the three ",[315,553,554],{},"content/*/decrypt"," cases and ",[315,557,558],{},"ecdh_wrap/unwrap"," — read material the fixture generator produced, rather than checking a client against itself. Those are the ones that actually demonstrate interoperability: passing them means this client can read what another one wrote. The remaining nineteen catch drift earlier and more precisely, which is why both directions are there.",[265,561,562],{},"Three cases are worth singling out. The first two were written into the original fixture as pins on the parts of the spec easiest to get wrong; the third was added later, and caught a live bug immediately:",[564,565,566,580,591],"ul",{},[567,568,569,574,575,579],"li",{},[280,570,571],{},[315,572,573],{},"hkdf/empty salt, short info"," — an empty salt is a zero-",[576,577,578],"em",{},"length"," byte string, not a block of zero bytes. An implementation that pads an absent salt produces different output. Pinned preemptively.",[567,581,582,587,588,590],{},[280,583,584],{},[315,585,586],{},"content/passcode mixed into info, not into the salt"," — the passcode belongs in the HKDF ",[315,589,375],{},", never in the salt. Also pinned preemptively.",[567,592,593,598],{},[280,594,595],{},[315,596,597],{},"characters a JSON serialiser may mangle"," — HTML-escapable characters, quotes and non-ASCII text. The fixture was all ASCII until this case was added, and it immediately caught a real divergence: one client was escaping every non-ASCII character on the wire.",[272,600,602],{"id":601},"what-it-does-not-cover","What it does not cover",[265,604,605],{},"Worth stating plainly, because a green run is easy to over-read:",[564,607,608,614,620],{},[567,609,610,613],{},[280,611,612],{},"No webhook signatures."," Signature verification is tested in each repository's own suite, not by this fixture.",[567,615,616,619],{},[280,617,618],{},"No HTTP surface"," — no endpoints, status codes, error codes, pagination or idempotency behaviour.",[567,621,622,625,626,629,630,633,634,637],{},[280,623,624],{},"No field-member preservation."," The fixture's field arrays carry only ",[315,627,628],{},"key",", ",[315,631,632],{},"value"," and ",[315,635,636],{},"type",", so nothing here would notice a client that dropped a member a newer sender had added. Go and Rust used to drop them and all 24 checks still passed; both preserve them now, and the gap in the fixture is unchanged.",[265,639,640],{},"A passing run means the cryptography and the wire encodings are right. It does not mean the client is complete.",[272,642,644],{"id":643},"the-generator","The generator",[265,646,647,648,651],{},"The fixture is produced by a script that implements the specification from scratch against ",[315,649,650],{},"node:crypto"," and imports nothing from the application. That independence is the point: a generator built on the app's own crypto would merely restate whatever the app does, and an app bug would become the standard every SDK is held to.",[265,653,654,655,658],{},"Vectors are ",[280,656,657],{},"data",". They are vendored and compared, never imported — data crosses the boundary between public and private code, and code does not.",[660,661],"hr",{},[373,663,665],{"color":375,"icon":664},"i-lucide-arrow-right",[265,666,667,668,675],{},"If you are implementing a client for a language we do not ship, ",[669,670,674],"a",{"href":671,"rel":672},"https://credenshare.io/contact",[673],"nofollow","get in touch"," — we would rather know about it than have it drift.",[677,678,679],"style",{},"html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":407,"searchDepth":414,"depth":432,"links":681},[682,683,684,685,686],{"id":274,"depth":432,"text":275},{"id":399,"depth":432,"text":400},{"id":535,"depth":432,"text":536},{"id":601,"depth":432,"text":602},{"id":643,"depth":432,"text":644},"The fixture every CredenShare client must reproduce — what it covers, how to run it, and what it deliberately does not test.","md",{},true,{"title":242,"description":687},"byPWIuWnFH7ui5jiY_Zn9YyS004dRcGIgtGo_C_w7ik",[694,696],{"title":238,"path":239,"stem":240,"description":695,"children":-1},"The official Rust client — encrypts locally, assembles the link, verifies webhooks. Crypto usable without the HTTP stack.",{"title":251,"path":252,"stem":253,"description":697,"children":-1},"How CredenShare encrypts and protects your shared credentials.",1788908851477]