Where Do the Documents Go? Storage Architecture for Government-Grade Legal Aid on Solana

For government IT architects, compliance officers, and legal tech teams evaluating where sensitive legal aid documents should live — and who should control them.
Every government digitization project hits the same wall: where do the documents go? The credential can be on-chain. The payment can be instant. But the case file — the scanned application, the eligibility proof, the court order — that's the artifact that makes compliance officers lose sleep. It contains PII. It falls under GDPR Article 5(1)(c). It's subject to national data residency laws. And it needs to survive for decades.
Adduce doesn't dodge this question. We designed an entire storage architecture around it.
The Rule: No Personal Data Touches the Public Ledger
This is the foundational constraint. Every storage decision in Adduce derives from one principle: the blockchain stores proofs, never documents. The on-chain footprint of a legal aid case contains exactly four things:
| On-Chain Data | Type | Size | Contains PII? |
|---|---|---|---|
document_hash | SHA-256 | 32 bytes | No — one-way hash |
lawyer_commitment | SHA-256(pubkey || salt) | 32 bytes | No — salted hash |
commitment_root | Poseidon hash | 32 bytes | No — ZK commitment |
citizen_id_hash | SHA-256(national_id) | 32 bytes | No — irreversible hash |
The total on-chain footprint of a citizen's identity across the entire case lifecycle is 128 bytes of hashes. No names. No addresses. No income data. No birthdates. A verifier with unlimited compute cannot extract the original values from these commitments. This isn't a policy — it's a mathematical guarantee.
The Three Storage Layers
Adduce splits document storage into three distinct layers, each with a different trust model, durability guarantee, and compliance profile:
Layer 1: Government Database (Citizen Data)
Personal data — the applicant's name, income, family status, national ID — never leaves the government's existing document management system. This is deliberate. Governments have spent decades building GDPR-compliant DMS infrastructure. They have data residency controls, access logging, retention policies. Adduce doesn't replace any of that. It plugs in alongside it.
Layer 2: Government-Certified Infrastructure (Encrypted Documents)
The case file itself — the scanned certificate, the court order, supporting documents — is encrypted end-to-end and stored on government-certified infrastructure. Not Arweave. Not a public decentralized network. The encrypted documents live on whatever certified storage the jurisdiction already operates: BundesCloud (Germany), Nubo (France), AWS GovCloud, or a ministry's own DMS.
Why? Because storing encrypted case documents permanently on a decentralized network fails in three critical ways for government deployments:
1. Right to Erasure (GDPR Article 17): Arweave is permanent. If a court orders deletion, you cannot comply. Many EU Data Protection Authorities consider encrypted personal data still personal data — because the decryption key exists somewhere.
2. Harvest Now, Decrypt Later: X25519 key exchange is not quantum-resistant. Encrypted case files stored permanently become readable if quantum computing breaks ECDH in 15-20 years. Government documents have 30-75 year retention requirements.
3. Procurement Certification: EU governments require BSI C5 (Germany), SecNumCloud (France), or equivalent certifications. Arweave has none. A procurement officer rejects this on page 1.
The encryption pipeline remains the same — the only difference is where the encrypted envelope is stored:
// 1. Derive X25519 keys from Ed25519 wallets
const lawyerEncKeys = deriveEncryptionKeypair(lawyerKeypair.secretKey);
// 2. ECDH key agreement (court x lawyer)
// Shared secret = court_private x lawyer_public
// AES key = SHA-256(shared_secret)
// 3. Encrypt with AES-256-GCM
const envelope = encryptDocument(
documentBuffer,
lawyerEncKeys.publicKey, // Only this lawyer can decrypt
courtKeypair.secretKey // Court is the sender
);
// 4. Store encrypted envelope on government infrastructure
// NOT on Arweave — on BundesCloud, Nubo, GovCloud, etc.
// The storage backend is swappable. The encryption is not.
// 5. Anchor integrity proof on Arweave via Irys
// Only the HASH goes to Arweave — not the document
const proofReceipt = await irys.upload(JSON.stringify({
plaintext_hash: envelope.plaintextHash,
ciphertext_hash: envelope.ciphertextHash,
timestamp: Date.now(),
}), { tags });
Key properties of encrypted document storage:
| Property | Value | Why It Matters |
|---|---|---|
| Encryption | X25519 ECDH + AES-256-GCM | Only the assigned lawyer's wallet can decrypt |
| Storage location | Government-certified infrastructure | Meets BSI C5, SecNumCloud, FedRAMP requirements |
| Deletable | Yes — per retention policy | GDPR Article 17 compliance: can destroy after case lifecycle |
| Data residency | National (government-controlled) | Documents stay within jurisdictional borders |
| Auth tag | 16-byte GCM authentication | Detects any bit-level modification of ciphertext |
| Cost | Government existing infrastructure | No additional storage vendor required |
Layer 2b: Arweave via Irys (Integrity Proofs Only)
Arweave's role is narrower and more powerful than document storage: it anchors permanent integrity proofs. Only the document hash, ciphertext hash, and timestamp go to Arweave — never the document itself. This proof survives permanently, even after the encrypted document is destroyed per retention policy. Twenty years later, an auditor can verify that a document existed, was unmodified at the time of anchoring, and was issued by an authorized court — without needing the document itself.
| What goes to Arweave | What does NOT go to Arweave |
|---|---|
| SHA-256 plaintext hash (32 bytes) | Encrypted document blob |
| SHA-256 ciphertext hash (32 bytes) | Encryption keys or key material |
| Timestamp | Case metadata or PII |
| Case ID reference | Lawyer identity or wallet address |
Cost: $0.004 per proof anchor. Pay once. Permanent. Tamper-proof. Content-addressable. No monthly fees. This is what Arweave was built for — not encrypted PII storage, but immutable proof-of-existence.
Layer 3: Solana (Hashes + Compressed Audit Logs)
The on-chain layer stores two things: the document hash (anchored via the anchor_document instruction) and compressed audit logs via Light Protocol.
// Anchor program instruction: anchor_document
pub fn anchor_document(
ctx: Context<AnchorDocument>,
_case_id: String,
document_hash: [u8; 32], // SHA-256 of plaintext
lawyer_salt: [u8; 32], // Proves lawyer identity
) -> Result<()> {
// 1. Verify: SHA256(lawyer_pubkey || salt) == case.lawyer_commitment
// 2. Verify: case status is Open or InProgress
// 3. Verify: SAS attestation still exists (not revoked)
// 4. Store: document_hash on CaseFile PDA
// 5. Update: status to InProgress
}
The lawyer must cryptographically prove they are the assigned counsel before they can anchor any document. The salt is never stored — only the commitment hash. This means even if someone reads the on-chain data, they cannot determine which lawyer is assigned to which case without the salt.
Why Not Just Use GCP or AWS?
Most government digitization projects default to a hyperscaler. Germany uses BundesCloud (based on OpenStack). France uses Nubo. The EU is pushing GAIA-X. The question Adduce faces is: why not just store everything on GCP and call it a day?
| Dimension | GCP / AWS GovCloud Alone | GovCloud + Adduce Layer |
|---|---|---|
| Document storage | Plaintext in cloud bucket, protected by IAM | Encrypted on same infrastructure, hash-anchored on Solana |
| Integrity proof | CloudTrail logs (proprietary, deletable by admin) | On-chain hash + Arweave anchor (permanent, tamper-proof) |
| Cross-border verification | Requires bilateral data processing agreements | Verify hash on-chain from any jurisdiction, zero data transfer |
| Tampering detection | Admin access can modify objects silently | Any modification breaks the on-chain hash — instantly detectable |
| Deletion compliance | Deletable per retention policy | Documents deletable, proofs permanent (by design) |
| Audit after destruction | Impossible once deleted | On-chain proof survives — verify integrity even after document destroyed |
| Proof cost | Included in cloud bill | $0.004 per anchor (one-time, permanent) |
The critical insight: Adduce doesn't replace government cloud storage — it makes it auditable. The documents stay on GovCloud, BundesCloud, or whatever certified infrastructure the jurisdiction uses. Adduce adds a cryptographic integrity layer: a 32-byte hash on Solana and a permanent proof on Arweave. The document can be deleted per retention policy. The proof that it once existed, was authentic, and was unmodified — that survives forever.
The Plug-and-Play Model
Adduce doesn't demand that governments abandon their existing storage. The architecture is designed as a plug-in layer that sits alongside whatever the government already uses:
Government Existing Infrastructure
SAP DMS / National Cloud / GCP GovCloud
Citizen personal data (stays here, GDPR-managed)
Encrypted case documents (stays here, deletable per retention)
Adduce Layer (plugs in)
Solana (on-chain)
SAS Attestation PDA ($0.004) - credential
CaseFile PDA - document_hash + lawyer_commitment
Light Protocol - compressed audit logs ($0.0038)
Arweave via Irys (proof layer)
Integrity proofs only - hashes + timestamps ($0.004)
NO encrypted documents, NO PII, NO ciphertext
SDK (@adduce/sdk)
npm install - connects to deployed program
The storage backend for encrypted documents is whatever the government already uses. Adduce never touches it directly. The SDK takes a document hash as input — it doesn't care whether the document lives on BundesCloud, Nubo, GovCloud, or a ministry's local NAS. The storage backend is swappable. The cryptographic proof layer is not.
The Case Lifecycle: What Happens to Documents
Government documents have a lifecycle. They aren't permanent — they have legally mandated retention periods, after which they must be destroyed. The storage architecture must respect this:
DURING CASE PROCEEDINGS
Encrypted documents --> Government-certified storage
Document hashes --> Solana (CaseFile PDA)
Integrity proofs --> Arweave via Irys (permanent)
Audit logs --> Light Protocol compressed (permanent)
Credential --> SAS attestation PDA
AFTER CASE CONCLUSION
Final record + full on-chain audit log --> Government archive
Encrypted working copies --> Deleted from interim storage
On-chain hashes --> Permanent (proof of integrity survives)
SAS attestation --> Deleted (revocation)
Arweave proofs --> Permanent (proof-of-existence survives)
AFTER RETENTION PERIOD EXPIRES
Government archive copies --> Destroyed per schedule
On-chain hashes + Arweave proofs --> Still permanent
Result: "This document existed, was authentic, and was
issued by this court on this date" — provable forever,
even after the document itself no longer exists
This is the correct model. Documents are temporary. Proofs are permanent. A government auditor can verify 20 years later that a legal aid certificate was issued, was unmodified, and was authorized by the right court — without needing the certificate itself. The hash proves it. The Arweave anchor timestamps it. The Solana transaction log shows every state change. The document is gone, but the truth survives.
Access Control: Who Can Decrypt What
Document access in Adduce is controlled by cryptography, not by access control lists:
| Actor | Can Decrypt? | Why |
|---|---|---|
| Assigned lawyer | Yes | Holds the recipient Ed25519 private key |
| Court authority | No (after encryption) | Used ephemeral key — shared secret discarded |
| Cloud storage admin | No | Only sees ciphertext on government infrastructure |
| Arweave node operators | N/A | Only hold proof hashes — no encrypted documents |
| Solana validators | No | Only see 32-byte hashes |
| New lawyer (after reassignment) | Yes (new envelope) | reassign_lawyer triggers re-encryption for new recipient |
| Auditor | No (verifies hash only) | Compares on-chain hash against document hash — integrity check without content access |
When a lawyer is reassigned via the reassign_lawyer instruction, the old lawyer's access is cryptographically revoked — not by deleting a permission, but because the new encrypted envelope on government storage is re-encrypted for the new lawyer's wallet. The old envelope is deleted. The new lawyer gets a fresh envelope encrypted for their key. The on-chain hash remains unchanged because the underlying document hasn't changed — only the encryption wrapper.
The Cost Reality at Government Scale
Storage costs are where the compressed architecture shines. Using Light Protocol's ZK compression, Adduce reduces on-chain storage costs by 98.7% compared to standard Solana PDAs:
Add the Arweave proof anchor ($0.004) and the SAS credential issuance ($0.004), and the total Adduce cost per legal aid case is under $0.02 — not counting government storage, which already exists and is already paid for. For context, the administrative overhead of processing a single paper legal aid certificate in Germany — printing, mailing, filing, reconciling — costs an estimated $15-25 per case. The Adduce infrastructure cost is a rounding error on top of what governments already spend.
Government Storage Laws: What Actually Matters
Three regulatory frameworks shape how governments can store legal documents:
1. GDPR Article 5(1)(c) — Data Minimization
Store only what you need. Adduce stores 128 bytes of irreversible hashes on-chain. Zero PII. The minimization isn't a design choice — it's a cryptographic constraint. You couldn't store personal data on-chain through Adduce even if you wanted to.
2. eIDAS 2.0 — Digital Identity Wallets (Deadline: December 2026)
EU member states must support selective disclosure in digital identity wallets. Adduce's Groth16 ZK proofs already implement this: prove "jurisdiction is DE and credential is not expired" without revealing tier, identity, or exact dates.
3. National Data Residency Laws
Some jurisdictions require that citizen data stays within national borders. Adduce handles this cleanly: citizen data stays in the government's existing DMS (which already complies). The on-chain layer contains no citizen data — only hashes. And if the encrypted documents must also stay national, swap Arweave for the national cloud. The architecture doesn't care where the ciphertext lives — only that the hash matches.
Conclusion: Documents Are Temporary. Proofs Are Permanent.
The hard part was never where to put the bytes. Governments have GCP. They have national clouds. They have filing cabinets that have worked for centuries. The hard part is proving that a document is authentic, unmodified, and issued by the right authority — across borders, without trusting a single server, and without exposing the citizen's identity. And doing this in a way that survives even after the document itself is destroyed per retention policy.
That's what the storage architecture solves. Not by replacing what governments already have, but by adding a cryptographic proof layer that makes their existing documents verifiable, portable, and tamper-proof — and that outlives the documents themselves.
Encrypted documents belong on government-certified infrastructure — deletable, auditable, compliant. Integrity proofs belong on Arweave and Solana — permanent, tamper-proof, borderless.
The documents stay where governments put them. The proofs go on-chain. The documents can be destroyed. The truth survives.