Inspiration
Medical records are among the most sensitive data a person has, yet "decentralized" health platforms often leak it by design. IPFS content is retrievable by anyone who has the CID, access grants tend to be permanent with no audit trail, and AI features that read uploaded documents can be hijacked by prompt injection hidden in the text. We wanted to see if patients could truly own their data, with security we could prove by attacking our own system.
What it does
MediChain Shield is a security layer for decentralized medical records.
- Client-side encryption: records are encrypted in the browser with AES-256-GCM before upload, so IPFS and our servers only ever see ciphertext.
- Wallet-derived keys: a patient's encryption keys come from their wallet signature. No passwords, and no keys held by the server.
- Time-bound, revocable access: patients grant a doctor access with an expiry (90 days at most) through an EIP-712-signed smart contract. Grants can be revoked at any time.
- Tamper-evident audit trail: every grant, revoke and access is logged on-chain.
- AI safety guard: the drug and allergy conflict checker defends against prompt injection with a deterministic pre-check, delimited LLM analysis and schema-validated output. It falls back across free LLM tiers and works offline.
- Attack demos: five scripted attacks (stolen CID, expired grant, signature replay, forged grant, prompt injection) are all blocked.
How we built it
- Frontend: Next.js and React with a headless crypto layer: Web Crypto (AES-256-GCM), HKDF-SHA256 key derivation, and X25519 sealed-box key wrapping via libsodium.
- Contracts: Solidity with Hardhat and OpenZeppelin. AccessRegistry uses EIP-712 signatures, per-signer nonces against replay, owner-only grants, expiry enforcement, and custom errors for gas efficiency.
- Backend: Express with Helmet, strict CORS, multi-tier rate limiting (IP, wallet, endpoint), and Zod validation on every route.
- Storage: IPFS (Kubo), ciphertext only, behind an adapter with memory and filesystem fallbacks.
- AI guard: Gemini free tier, then Groq free tier, then local heuristics. The heuristic pre-check flags attacks before any LLM call.
- Testing: 131+ automated tests across the crypto engine, contracts and AI guard, plus five attack scripts.
- Cost: everything runs on free tiers and testnet, at $0.
AI tools used: [list the tools you actually used, and what for].
Challenges we ran into
- Deriving keys from a wallet signature: getting a deterministic, safe keypair without storing anything required careful design (versioned messages, HKDF, in-memory-only keys).
- Revocation limits: on-chain revocation can't make someone forget data they already decrypted. We used expiring grants and per-record keys to limit the damage, and we document the limit openly.
- Prompt injection in clinical text: medical notes are free text, so instructions can hide in them. We had to combine deterministic checks, delimited prompts and strict output validation.
- Free-tier constraints: rate limits and public RPC limits pushed us toward adapters, caching and offline fallbacks.
- Adding security without disturbing the app: the Shield layer had to sit alongside the existing app as headless hooks and additive endpoints.
Accomplishments that we're proud of
- All five attack demos are blocked, and each is reproducible with one command.
- 131+ passing tests, including tamper detection, wrong-key failures, replay rejection and injection samples.
- Server-side code never sees plaintext or keys.
- The whole system works at $0, and the AI features still work when every LLM tier is unavailable.
- A written threat model and an honest list of limitations.
What we learned
- Encryption alone isn't enough. Access control, expiry and auditability matter just as much.
- Attacking your own system is the fastest way to find weak assumptions.
- LLM features need to treat input as untrusted, with structured outputs and deterministic checks ahead of the model.
- Being open about limitations makes a security project more credible.
What's next for MediChain Shield
- Key rotation on revoke, so a revoked party can't reuse a cached key.
- Recovery for lost wallets, such as social recovery.
- Persistent nonce and cache storage (for example Redis) in place of in-memory stores.
- Upgradeable contracts and an independent security audit.
- Emergency "break-glass" access with loud logging.
- A hosted demo and a clinician-facing pilot with synthetic data.
Built With
- eip-712
- ethers.js
- express.js
- gemini-api
- groq
- hardhat
- helmet
- ipfs
- libsodium
- metamask
- next.js
- node.js
- openzeppelin
- pino
- polygon
- react
- shadcn-ui
- solidity
- tailwindcss
- typescript
- vitest
- web-crypto-api
- zod
Log in or sign up for Devpost to join the conversation.