Skip to main content

Architecture Overview

SHIELD uses a hybrid architecture combining client-side encryption, decentralized storage, and on-chain access control to provide trustless secure file sharing.

System Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                          USER BROWSER                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐ │
│  │   Encrypt   │  │   SIWE      │  │  Contract   │  │  Decrypt    │ │
│  │  (Web Crypto)│ │   Sign      │  │   Calls     │  │  (Web Crypto)│ │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘ │
└─────────┼────────────────┼────────────────┼────────────────┼──────┘
          │                │                │                │
          ▼                │                │                ▼
┌─────────────────┐       │                │       ┌─────────────────┐
│      IPFS       │◀──────┘                └──────▶│      IPFS       │
│   (Pinata)      │                                │   (Pinata)      │
└─────────────────┘                                └─────────────────┘
          ▲                                                │
          │                                                │
          │                                                ▼
          │                              ┌─────────────────────────────┐
          │                              │         SHIELD API           │
          │                              │  ┌──────────┐ ┌──────────┐ │
          └──────────────────────────────│  │  Policy  │ │  Access  │ │
                                         │  │   Store  │ │   Logs   │ │
                                         │  └──────────┘ └──────────┘ │
                                         └──────────┬─────────────────┘


                                         ┌─────────────────────────────┐
                                         │     BASE BLOCKCHAIN         │
                                         │  ┌─────────────────────┐   │
                                         │  │   Shield Contract   │   │
                                         │  │  ┌───────────────┐  │   │
                                         │  │  │ AccessPolicy  │  │   │
                                         │  │  │   Mapping     │  │   │
                                         │  │  └───────────────┘  │   │
                                         │  └─────────────────────┘   │
                                         └─────────────────────────────┘

Components

Client-Side Encryption

All encryption happens in the browser using the Web Crypto API:
  • Algorithm: AES-GCM 256-bit
  • Key Generation: Crypto.getRandomValues (CSPRNG)
  • IV: 96-bit random nonce
  • Authentication: Built-in GCM tag
// Simplified encryption flow
const key = await crypto.subtle.generateKey(
  { name: 'AES-GCM', length: 256 },
  true,
  ['encrypt', 'decrypt']
);

const encrypted = await crypto.subtle.encrypt(
  { name: 'AES-GCM', iv },
  key,
  fileData
);

IPFS Storage

Encrypted content is stored on IPFS via Pinata:
  • Gateway: https://gateway.pinata.cloud/ipfs/{cid}
  • Persistence: Pinned via Pinata API
  • Content Addressing: CID uniquely identifies encrypted content
  • Decentralization: Content available through any IPFS node

Smart Contracts

The Shield contract on Base manages access policies:
NetworkContract Address
Base Mainnet0x4b8F46e5E3d95D78f30F80F1280fE7e5F92c8ce8
Key Functions:
  • createPolicy() - Store access conditions on-chain
  • logAttempt() - Record access attempts
  • isPolicyValid() - Check policy status

Backend API

Node.js/Next.js API for off-chain operations:
  • Policy Metadata: Maps policy ID to IPFS CID
  • Authentication: SIWE signature verification
  • Rate Limiting: Sliding window per IP/address
  • Session Management: JWT with 1-hour expiry

Data Flow

1

Generate Key

Browser generates AES-256 key using Web Crypto API
2

Encrypt Content

File/message encrypted locally, never leaves browser unencrypted
3

Upload to IPFS

Encrypted blob uploaded to Pinata, returns CID
4

Create Policy

User signs transaction to store access policy on Base
5

Store Metadata

Backend stores policy ID → CID mapping in PostgreSQL
6

Generate Link

URL created with policyId and secretKey (fragment)

Accessing Content

1

Verify SIWE

Recipient signs message proving wallet ownership
2

Check Policy

Backend queries contract: valid? expired? attempts?
3

Log Access

Recipient signs transaction calling logAttempt()
4

Fetch Content

Browser fetches encrypted blob from IPFS
5

Decrypt

Secret key from URL fragment decrypts content locally

Security Boundaries

ComponentTrust LevelData Access
BrowserTrustedUnencrypted content
IPFSUntrustedEncrypted content only
Smart ContractTrustlessPolicy metadata only
Backend APITrustedNon-sensitive metadata
SenderTrustedOriginal content
RecipientVerifiedDecrypted content

Technology Stack

LayerTechnology
FrontendNext.js 16, React 19, TypeScript, Tailwind CSS
StateReact Query, Wagmi, Viem
WalletRainbowKit, WalletConnect
CryptoWeb Crypto API (AES-GCM 256)
ContractsSolidity 0.8.24, Hardhat
NetworkBase (Ethereum L2)
StorageIPFS via Pinata
DatabasePostgreSQL (Neon)
HostingVercel