Privacy Controls
IPFS was designed for open sharing, and its addressing model quietly assumes it: a CID is derived from the content, so anyone who learns the CID can ask the network for the bytes. For a public dataset that's the whole appeal. For a pre-publication genome it's a problem, and "just don't share the CID" is not a privacy model.
Ekayana layers three real controls on top, in increasing order of strength:
- Gateway access control - session tokens, UCAN capabilities, IP allowlisting, geolocation restrictions. This stops the platform's own gateway from serving unauthorized reads.
- Permission management - every grant is a signed UCAN naming specific actions (read, write, delete, share, admin), time-bound, attenuable, and revocable.
- Content encryption - payloads are sealed before they reach IPFS, with a fresh ML-KEM-1024-wrapped key per object; client side encryption is available for zero-knowledge workflows.
The first two depend on the platform enforcing rules. The third doesn't - and that distinction is the backbone of the rest of this page.
Encrypt then store
The strongest privacy control is the one that does not depend on an access-control list being enforced correctly. Private payloads are encrypted before upload, so the CID addresses ciphertext:
Consequences worth being precise about:
- A leaked CID is not a leaked dataset. Any node replicating the block holds bytes that are useless without the ML-KEM decapsulation key.
- The AEAD binds the payload to its owner. Associated data ties each sealed payload to the identity it was stored for, so a ciphertext lifted into another account will not open.
- Tampering is detected, not silently served. AES-256-GCM is authenticated; a modified block fails to decrypt rather than returning corrupted data.
- Legacy content still works. Sealed payloads carry a version marker, so pre-existing plaintext content is served unchanged during migration.
On the "right to be forgotten". IPFS content is immutable and may be replicated beyond your control, so deletion cannot be guaranteed by unpinning alone. Encrypting at rest makes erasure effective rather than merely best-effort: destroying the key renders every surviving replica permanently unreadable. This is why nothing personal is ever anchored on-chain - only public keys, opaque fragments, and URIs.
See Post-Quantum Security for the algorithms and key management, and UCAN Authorization for how a content key is delegated to a recipient inside the capability token itself.
Implementing Privacy Controls
Encryption is a property of the write path
There is no "encrypt: true" flag to remember. Payloads written through the encrypted path are sealed automatically: a fresh AES-256-GCM content key per object, itself wrapped to the server's ML-KEM-1024 key. Reads decrypt transparently, and an object stored as plaintext before the encryption layer existed is detected and passed through unchanged - so both coexist without a migration.
The associated data binds each object to its owner, so a sealed payload cannot be replayed into another account's context even by someone holding the ciphertext.
Access control is capability based
Access is granted by minting a scoped, revocable UCAN capability - not by editing an ACL:
curl -X POST https://api.ekayana.com/api/share/file \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"cid": "QmXyz...",
"recipient_did": "did:bio:user:7",
"capabilities": ["read"],
"expiration_days": 7
}'Revoke with DELETE /api/share/revoke/{token_hash}. Revocation cascades: the proof chain is walked on every validation, so withdrawing a grant also invalidates everything delegated beneath it.
What this gives you under GDPR
| Requirement | Mechanism |
|---|---|
| Data minimisation | Only public keys, fragments, and URIs are ever anchored on-chain |
| Purpose limitation | Capabilities name one resource and one action set |
| Storage limitation | Every grant carries a signed expiry |
| Right to erasure | Delete unpins the platform copy; destroying the key renders surviving replicas unreadable |
| Integrity & confidentiality | AES-256-GCM at rest, post-quantum key wrapping |
Honest limit: IPFS is a public network. Once a plaintext object has been fetched by a third party, no API can recall it. That is precisely why personal and pre-publication data is encrypted before it reaches IPFS - erasure then depends on key destruction, which you control, rather than on cooperation from every node that ever cached the content.