Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

How to Design Private Social Feeds with Selective Disclosure

This guide details the construction of a social feed where users control exactly who sees each post. It combines on-chain access rules (e.g., token holdings) with off-chain encrypted content storage. The system uses cryptographic commitments to prove a post exists and access control lists to manage the distribution of decryption keys for different audience segments.
Chainscore © 2026
introduction
INTRODUCTION

How to Design Private Social Feeds with Selective Disclosure

Learn how to build social applications where users control exactly who sees their content, using cryptographic primitives and decentralized protocols.

Traditional social media platforms operate on a centralized model of data custody and access control. Your posts, likes, and network are stored on a company's servers, with visibility governed by opaque platform rules. Selective disclosure flips this model, empowering users to cryptographically prove specific attributes about themselves or their relationships to unlock content, without revealing their entire identity or social graph. This guide explores the architectural patterns for building private social feeds using zero-knowledge proofs, decentralized identifiers (DIDs), and encrypted data stores.

The core challenge is enabling meaningful social interaction—such as proving you follow someone or are part of a specific group—while maintaining privacy. Verifiable Credentials (VCs) and zero-knowledge proofs (ZKPs) are key technologies here. For example, a user could hold a VC issued by a friend, proving a mutual "follow" relationship. To view a private post, the user generates a ZKP that demonstrates they possess a valid follow credential from the poster, without revealing which specific credential or their own DID. Frameworks like Semaphore or zkSNARKs circuits in Circom can implement such group signaling and anonymous authentication.

Data storage and encryption are equally critical. The social feed's content—posts, comments, media—must be stored in a way that is persistently available yet only decryptable by authorized parties. Content-addressable storage networks like IPFS or Arweave provide decentralization, while end-to-end encryption schemes, such as using libp2p's Noise protocol or XChaCha20-Poly1305, ensure data confidentiality. Encryption keys can be derived from or shared via decentralized key management systems or access control conditions executed on-chain or via Lit Protocol.

Implementing a private feed requires a modular architecture: 1) An identity layer (DIDs, VCs), 2) A privacy/proof layer (ZKPs, ring signatures), 3) A storage layer (encrypted, decentralized storage), and 4) An orchestration layer (smart contracts for access rules). A developer might use Ceramic Network for mutable identity data, Semaphore for anonymous group membership proofs, store encrypted content on IPFS, and log access permissions on a low-cost chain like Polygon. The user's client app assembles proofs and fetches/decrypts content based on verified credentials.

This approach enables powerful use cases beyond private posts: token-gated communities where membership is private, anonymous voting within a DAO, or sharing sensitive information exclusively with verified professionals. By moving from platform-managed access to user-centric, cryptographically-enforced disclosure, developers can create social experiences that prioritize autonomy, minimize data leakage, and foster trust. The following sections will detail the implementation steps, from setting up a ZK circuit for relationship proofs to building a React frontend that interacts with these decentralized components.

prerequisites
FOUNDATIONAL KNOWLEDGE

Prerequisites

Before building private social feeds, you need a solid grasp of the core cryptographic primitives and decentralized protocols that enable selective data disclosure.

To implement selective disclosure, you must understand zero-knowledge proofs (ZKPs). ZKPs, particularly zk-SNARKs and zk-STARKs, allow a user to prove they possess certain information (e.g., they are over 18, hold a specific NFT) without revealing the underlying data. For social feeds, this enables privacy-preserving access control. Familiarity with circuits, as used in frameworks like Circom or Halo2, is essential for defining the logic of these proofs. You'll also need to understand the concept of a verifier contract on-chain that can validate these proofs.

Your application will need a decentralized identity layer. The World Wide Web Consortium (W3C) Verifiable Credentials (VCs) data model is the industry standard. A VC is a tamper-evident credential issued by one entity (an issuer) to a holder. In our context, a user might hold a VC proving their membership in a DAO. The Decentralized Identifier (DID) specification complements this, providing a persistent, verifiable identifier not reliant on a central registry. Protocols like Ceramic Network or Veramo provide tooling to manage DIDs and VCs in a user-centric way.

Data storage and access control are critical. You cannot store private user data on a public blockchain. Instead, you will use decentralized storage networks like IPFS or Arweave for persistent, content-addressed storage. To manage encryption, you need a key management strategy. This often involves using a user's blockchain wallet (via EIP-191 signed messages or EIP-712 typed data) to derive encryption keys, or employing protocols like Lit Protocol for conditional decryption based on on-chain state or ZKP verification.

Finally, you must choose a blockchain environment for your verifier logic and potentially for anchoring DIDs. Ethereum and EVM-compatible L2s (like Arbitrum, Optimism) are common choices due to their extensive tooling and the Ethereum Attestation Service (EAS) for on-chain attestations. For higher throughput, you might consider zkRollups or app-chains using SDKs like Polygon CDK or Arbitrum Orbit. Your tech stack will likely include a frontend library (React, Vue), a wallet connector (Wagmi, RainbowKit), and a backend service for indexing and relaying encrypted data.

system-architecture
SYSTEM ARCHITECTURE OVERVIEW

How to Design Private Social Feeds with Selective Disclosure

A technical guide to architecting decentralized social applications where users control who sees their content and metadata.

A private social feed with selective disclosure requires a fundamental shift from traditional centralized models. Instead of a single database, data is stored across a decentralized network, encrypted, and accessed via cryptographic keys. The core architectural components are: a decentralized data layer (like IPFS, Arweave, or Ceramic) for storage, an access control layer using public-key cryptography, and a client-side application that handles encryption and key management. This ensures the platform operator never has access to plaintext user data, shifting trust from institutions to code.

Selective disclosure is powered by asymmetric encryption and zero-knowledge proofs (ZKPs). When a user posts content, it is encrypted with a symmetric content key. This content key is then encrypted to the public keys of each authorized viewer, a pattern known as hybrid encryption. For more complex policies—like proving you are over 18 without revealing your birthdate—ZKPs (e.g., using Circom or Noir) allow users to generate verifiable credentials. The proof is posted on-chain or to a decentralized ledger, enabling trustless verification of attributes without exposing the underlying data.

The on-chain component typically manages social graphs and access policies via smart contracts. A contract on a blockchain like Ethereum or a rollup (e.g., Base, Arbitrum) can store mappings of user relationships (followers/following) and publish encrypted policy pointers. For example, a contract event might emit the IPFS Content Identifier (CID) of a post alongside the Ethereum address of the poster and a list of authorized viewer addresses. This creates an immutable, permissionless record of social actions while keeping the actual content private and off-chain.

Client applications are responsible for key management, which is the most critical user experience challenge. Users must securely store their private keys, often using mnemonic phrases or social recovery wallets (like Safe). The app fetches encrypted data CIDs from the blockchain, retrieves the ciphertext from the decentralized storage layer, and decrypts it locally using the user's private key. Libraries like libp2p for networking and ethers.js or viem for blockchain interaction are essential here. The client never sends private keys to a server.

To scale this architecture, consider layer-2 solutions for social graph updates to reduce gas costs and latency. Content Delivery Networks (CDNs) like Cloudflare's IPFS Gateway can cache popular encrypted content for faster retrieval, though they don't compromise privacy. For key recovery, integrate decentralized identifier (DID) methods such as did:key or did:ethr, which can be resolved to public keys. This architecture enables applications like private group chats, token-gated communities, and credential-based feeds, putting users in full control of their social data.

core-components
PRIVATE SOCIAL FEEDS

Core Components

Build private social feeds using cryptographic primitives for selective data disclosure. These components form the foundation for user-controlled social graphs and content sharing.

step1-onchain-commitment
FOUNDATION

Step 1: Publishing an On-Chain Commitment

The first step in designing a private social feed is to create an immutable, public anchor for your content without revealing the data itself. This is achieved by publishing a cryptographic commitment on-chain.

A commitment scheme is a cryptographic primitive where one party commits to a chosen value while keeping it hidden, with the ability to reveal it later. In the context of a private social feed, you commit to the hash of your post's content. Publishing this hash—specifically, a cryptographic digest like keccak256(content)—onto a blockchain (e.g., Ethereum, Arbitrum, Base) creates a permanent, timestamped, and verifiable record. This on-chain hash acts as a public pointer that proves the existence and integrity of your content at a specific point in time, without exposing the content's details.

The technical process involves your client application (like a React frontend) generating the commitment. You take the plaintext post data, serialize it, and hash it using a secure algorithm. This hash is then sent as part of a transaction to a smart contract designed to store commitments. A simple Solidity function for this might be:

solidity
function publishCommitment(bytes32 _contentHash) public {
    commitments[msg.sender].push(_contentHash);
    emit NewCommitment(msg.sender, _contentHash);
}

This transaction costs gas, but it is minimal because you are only storing a single 32-byte hash. The emitted event allows off-chain indexers to easily track new posts.

This on-chain commitment serves multiple critical functions. First, it provides data integrity: any tampering with the original content will result in a different hash, breaking the cryptographic link to the on-chain proof. Second, it establishes non-repudiation: you cannot later deny authoring the post, as your blockchain signature is attached to the transaction. Finally, it creates a public sequencing layer, ordering all posts in a decentralized, censorship-resistant manner. The content itself remains off-chain, stored privately by the author or in a decentralized storage network like IPFS or Arweave, with only its hash exposed.

step2-encrypt-store
PRIVACY ENGINE

Step 2: Encrypting and Storing Content Off-Chain

This step details the cryptographic process for securing user posts and the architectural decision to store encrypted data off-chain, ensuring privacy and scalability.

The core of a private social feed is end-to-end encryption (E2EE). Before any content is stored, the client application encrypts it using a symmetric key. For a post intended for a specific audience, the system generates a unique Content Encryption Key (CEK). This CEK is then used with a secure algorithm like AES-256-GCM to encrypt the post's text, media links, or metadata. The output is ciphertext—unreadable data that can only be decrypted with the same CEK.

Storing this encrypted data directly on a blockchain like Ethereum is prohibitively expensive and exposes metadata. Instead, the ciphertext is stored off-chain in a decentralized storage network. IPFS (InterPlanetary File System) and Arweave are common choices. When content is uploaded to IPFS, it returns a Content Identifier (CID), a unique hash that acts as a permanent pointer to the data. Only this small CID—not the content itself—is stored on-chain, often within an NFT or a smart contract event, linking the on-chain record to the off-chain payload.

The critical challenge is key management: how do you securely share the CEK with authorized viewers without a trusted server? This is solved with asymmetric cryptography. The sender encrypts the CEK for each recipient using their public key. This creates a set of encrypted key shares. These shares can be stored alongside the CID in the on-chain record or in a dedicated decentralized key management service. When a user wants to view a post, their client fetches the ciphertext from IPFS using the CID, retrieves the key share encrypted for them, decrypts it with their private key to get the CEK, and finally decrypts the post content.

step3-define-acl
IMPLEMENTATION

Step 3: Defining the Access Control List (ACL)

An Access Control List (ACL) is the rulebook for your private social feed, programmatically defining who can see which posts. This step translates your privacy model into executable logic.

The ACL is the core of selective disclosure. It's a function that takes a post and a viewer's identity (like their wallet address or a verifiable credential) and returns a boolean: true for access granted, false for denied. Instead of storing private data on-chain, you store encrypted content off-chain (e.g., on IPFS or Ceramic) and store the decryption key or a content identifier on-chain, guarded by the ACL. This pattern, used by protocols like Lit Protocol, ensures data privacy while leveraging blockchain for immutable permission logic.

Design your ACL around attributes, not just identities. Instead of hardcoding addresses, check for verifiable traits. For example, an ACL could grant access if the viewer holds a specific NFT (ownerOf), is part of a token-gated DAO (via ERC-20 balance), or possesses a credential from a trusted issuer (like a Verifiable Credential). This makes your feed dynamic and composable. A post tagged #DAO-Internal might use an ACL that checks viewerBalance >= 1 DAO_TOKEN.

Implement the ACL as a smart contract function. Here's a simplified Solidity example for a token-gated rule:

solidity
function canViewPost(uint256 postId, address viewer) public view returns (bool) {
    // Retrieve the required token address and threshold for this post
    (address token, uint256 minBalance) = getPostRules(postId);
    // Check the viewer's balance
    IERC20 tokenContract = IERC20(token);
    return tokenContract.balanceOf(viewer) >= minBalance;
}

This function is called by your frontend or a middleware layer before attempting to fetch and decrypt the corresponding post content.

For more complex social graphs, consider context-aware rules. An ACL could allow access if the viewer is a followerOf the poster (checking an on-chain social graph contract) or if the post is a comment on a thread where the viewer has already participated. Projects like Lens Protocol and Farcaster implement sophisticated graph-based ACLs within their smart contracts, enabling fine-grained social privacy.

Finally, optimize for gas and user experience. Evaluating multiple on-chain checks can be expensive. Use indexers (like The Graph) to pre-compute access states off-chain and serve them via a fast API. For users, implement key derivation so approved viewers can automatically derive the decryption key without manual steps, creating a seamless experience similar to SSL/TLS handshakes for the decentralized web.

step4-key-distribution
IMPLEMENTING SELECTIVE DISCLOSURE

Step 4: Distributing Decryption Keys

This step details the secure mechanisms for sharing encrypted content keys with authorized recipients in a private social feed.

After a post is encrypted, its symmetric content encryption key (CEK) must be securely delivered to the intended audience. Directly sharing the key with each follower is inefficient. Instead, leverage public-key cryptography. Encrypt the CEK with the public key of each authorized recipient. This creates a unique, recipient-specific ciphertext of the CEK. For a post visible to 100 followers, you would generate 100 encrypted key packages. This approach ensures that only users with the corresponding private key can decrypt the CEK and, subsequently, the post content.

To manage this efficiently at scale, use a key encapsulation mechanism (KEM). In practice, this often means using a hybrid encryption scheme. For example, you can encrypt the CEK once with a randomly generated key-encryption key (KEK). Then, encrypt this KEK for each recipient using their public key, such as their secp256k1 Ethereum address or ed25519 public key. The encrypted post is stored on-chain or on a decentralized storage network like IPFS, while the array of encrypted keys can be stored as metadata or in a smart contract. This pattern minimizes on-chain data while maintaining access control.

Implementing this requires careful key management. For Ethereum-based identities, you can use EIP-712 structured data signing to verify ownership. A practical flow: a user's client fetches the encrypted post and the list of encrypted keys. It attempts to decrypt each key package with the user's private wallet signature until one succeeds, revealing the CEK. Libraries like eth-sig-util or ethers.js provide methods for this asymmetric decryption. Always perform this decryption client-side to never expose private keys.

For dynamic groups, consider proxy re-encryption (PRE) as an advanced alternative. With PRE, a trusted proxy (operated by a network of nodes) can transform an encryption intended for the poster into an encryption for a follower, without ever seeing the plaintext key. This allows for post-hoc sharing without the original poster being online. Protocols like NuCypher (now part of Threshold Network) and Lit Protocol implement PRE, enabling functionalities like granting access to a new follower for all your past posts with a single transaction.

Access control logic must be explicit. A smart contract can act as the source of truth for permissions. Before serving an encrypted key, a client or server should verify the requester's eligibility against the contract state. This ensures that revoked permissions (e.g., after an 'unfollow') are enforced immediately. The contract might store a Merkle root of allowed identifiers, allowing for efficient proofs. This decouples the encryption logic from the authorization logic, creating a more robust and upgradeable system.

Finally, consider user experience and key recovery. If a user loses their wallet, they lose access to private posts. Social recovery schemes or encrypted backup solutions like storing a sharded backup of private keys with trusted contacts (using Shamir's Secret Sharing) can mitigate this. The goal is to create a system that is cryptographically secure without placing an impossible burden on the end-user, ensuring that private social data remains both accessible to friends and protected from adversaries.

PRIVACY ARCHITECTURE

Encryption and Key Management Method Comparison

A comparison of cryptographic approaches for private social feed data, balancing user experience, security, and decentralization.

Feature / MetricSymmetric Encryption (AES-GCM)Asymmetric Encryption (ECC)Proxy Re-Encryption (PRE)Zero-Knowledge Proofs (ZKPs)

Primary Use Case

Encrypting data-at-rest for a single key holder

Establishing secure channels and key exchange

Delegating decryption rights without exposing keys

Proving data attributes without revealing data

Key Management Burden

User stores single secret key

User manages public/private key pair

User holds private key, proxy holds re-encryption key

User holds private witness, verifier holds public params

Selective Disclosure Granularity

Per-user, per-message

Per-attribute, per-proof statement

Typical Latency for Decryption

< 1 ms

5-10 ms

10-50 ms (incl. proxy)

100-2000 ms (proof generation)

On-Chain Suitability (Gas Cost)

High (encrypted data is large)

Medium (public keys are small)

Low (only re-encryption keys needed)

Very High (proof verification gas)

Resilience to Key Loss

❌ Total data loss

❌ Total data loss

❌ Loss of original private key breaks delegation

âś… Proofs independent of original data

Common Implementation

Lit Protocol (for key gen), IPFS + AES

XMTP, PGP, Waku

NuCypher, Oasis Network, Lit (via PKP)

Semaphore, RLN, zk-SNARKs circuits

Best For

Simple, private user diaries or vaults

End-to-end encrypted direct messages

Social feeds where users grant access to followers

Anonymous signaling, reputation, or private group membership

step5-client-retrieval
IMPLEMENTATION

Client-Side Retrieval and Decryption

This step details how to fetch encrypted content from a decentralized storage network and decrypt it locally, ensuring data privacy is maintained until the user's device.

Once a user authenticates, the client application must retrieve the encrypted content they are authorized to view. This typically involves querying a smart contract or an indexer for a list of content identifiers (CIDs) stored on a decentralized network like IPFS or Arweave. The client fetches the raw encrypted data from these CIDs. Crucially, the decryption keys are never stored on-chain or with the service provider; they are derived locally from the user's wallet or session. This architecture ensures that the platform itself cannot read user data, enforcing privacy by design.

The core of this process is the decryption operation. Using a library like libsodium-wrappers or the Web Crypto API, the client uses the user's private key or a derived symmetric key to decrypt the content. For example, a post encrypted with a user's public key can only be decrypted by their corresponding private key, which never leaves their wallet (e.g., MetaMask or WalletConnect session). The code snippet below illustrates a simplified decryption flow using a symmetric key derived from a shared secret.

javascript
async function decryptContent(encryptedData, recipientPrivateKey, senderPublicKey) {
  // Derive a shared secret and symmetric key
  const sharedSecret = crypto.box.before(senderPublicKey, recipientPrivateKey);
  const symmetricKey = await deriveSymmetricKey(sharedSecret);
  // Decrypt the data
  const nonce = encryptedData.slice(0, crypto_secretbox_NONCEBYTES);
  const ciphertext = encryptedData.slice(crypto_secretbox_NONCEBYTES);
  const decryptedBytes = crypto_secretbox_open_easy(ciphertext, nonce, symmetricKey);
  return new TextDecoder().decode(decryptedBytes);
}

Handling different access levels is key. A feed might contain a mix of public posts (stored in plaintext), posts for specific followers (encrypted to each follower's key), and private group posts (encrypted to a shared group key). The client logic must identify the encryption scheme for each piece of content and apply the correct decryption method. Failed decryption attempts for content the user cannot access should be silent, preserving privacy by not revealing why access was denied. This selective disclosure is fundamental to creating a truly private social experience.

Performance optimization is a practical concern. Fetching and decrypting numerous items can be slow. Implement strategies like caching decrypted content locally (using the browser's IndexedDB), lazy-loading content as the user scrolls, and pre-fetching metadata to determine accessibility before downloading large encrypted blobs. The goal is to balance the overhead of client-side cryptography with a responsive user experience, making privacy-feasible at scale.

DEVELOPER FAQ

Frequently Asked Questions

Common technical questions and solutions for building private social feeds using selective disclosure protocols like Farcaster Frames, Lens Open Actions, and decentralized storage.

Selective disclosure is a cryptographic principle that allows a user to prove specific claims from a larger set of credentials without revealing the entire dataset. In private social feeds, this enables granular privacy controls.

Core Mechanism: A user can prove they are over 18, located in a specific country, or hold a certain NFT to access a gated post, without exposing their exact birthdate, full location history, or entire wallet contents.

Protocol Examples:

  • Verifiable Credentials (VCs): W3C standard for attestations.
  • Zero-Knowledge Proofs (ZKPs): Used by protocols like Sismo and Polygon ID to generate proofs of membership or reputation.
  • Farcaster Frames: Can integrate ZK proofs to gate frame interactions based on user-held credentials.

This shifts the paradigm from all-or-nothing data sharing to minimal, context-specific disclosure, which is crucial for compliant and user-trusted applications.