MeshKit

Sharing

Share encrypted content with recipient identities.

Sharing gives another MeshKit identity a way to open encrypted content without sending plaintext. MeshKit does this with a share capsule: metadata that points at a CID and wraps the data key for one or more recipient identities.

Do not model MeshKit identities as email addresses by default. An identity is an application-level encryption identity. Your app decides how to bind it to users, devices, DIDs, passkeys, wallets, or an internal directory.

Share A File

import { meshkit } from "@meshkit/meshkit";

const mesh = await meshkit({ identity: "owner" });

await mesh.identity.create("alice");

const file = await mesh.files.put("roadmap.md", "# Roadmap");

const capsule = await mesh.share.file(file).with("alice", {
  expiresIn: "7d",
  allowDownload: true,
});

await mesh.share.send(capsule, "alice");

const opened = await mesh.share.openCapsule(capsule, { as: "alice" });

console.log(await opened.text());

How Sharing Works

owner stores encrypted file
-> owner creates capsule for recipient public key
-> provider stores or queues capsule metadata
-> recipient opens capsule as their MeshKit identity
-> MeshKit checks expiry, revocation, policy, vault, and capabilities
-> MeshKit unwraps the data key and decrypts the content

Sharing creates access to encrypted bytes that already exist. It does not copy plaintext into a mailbox.

API

await mesh.share.file(file).with(recipient, options);
await mesh.share.openCapsule(capsule, options);
await mesh.share.revoke(capsuleId);
ParameterTypeRequiredDescription
share.file(file).with(recipient, options)MeshFile | string, string | string[], ShareOptionsFile and recipient yesCreates and stores a ShareCapsule for the target CID
share.openCapsule(capsule, options)ShareCapsule | string, OpenOptionsYesChecks expiry, revocation, policy, vault, and capability requirements before decrypting
share.send(capsule, recipient)ShareCapsule, stringYesQueues a capsule in the provider mailbox for a recipient
share.revoke(capsuleId)stringYesMarks the capsule revoked for future opens

What To Persist

  • Source content CID
  • Capsule ID
  • Recipient identity
  • Expiry or policy ID
  • Revocation state
  • Vault or capability references, if used

Failure Modes

Error or symptomMeaningFix
identity_not_foundRecipient key is not local and no directory resolved itCreate, import, publish, or resolve the identity first
recipient_not_authorized or key_unwrap_failedThe opener does not have a valid wrapped keyOpen as the intended identity or create a new capsule
share_expiredCapsule expiry passedCreate a fresh capsule or extend access
share_revokedCapsule was revokedCreate a new share if access should resume
policy_provider_requiredCapsule depends on an external policy providerConfigure the same policy provider before opening
capability_requiredCapsule requires a capability tokenPass the token issued by the vault or capability owner

Revocation Boundary

Revocation blocks future opens through MeshKit checks. It cannot erase plaintext that the recipient already decrypted, copied, cached, or exported. Design product UX and compliance language around that boundary.

Production Notes

  • Use a real identity directory or app-owned contact model before sharing with production users.
  • Persist capsule IDs and recipient state so you can audit, revoke, and retry.
  • Do not log wrapped keys, capability tokens, policy secrets, or decrypted content.
  • Validate the provider supports capsules and mailbox records if you use share.send.

Next Steps

On this page