Xguard: AI Model Weight Protection
AI model weights represent millions of dollars in training compute. A single breach exposes the entire model. Xguard splits model weights across multiple storage nodes via XorIDA threshold sharing so that no single node holds enough data to reconstruct the model. Per-chunk HMAC integrity ensures tamper detection, full-model SHA-256 hash verification guarantees end-to-end authenticity.
Executive Summary
Xguard protects AI model weights from theft and tampering by splitting them across independent storage locations via XorIDA threshold sharing. No single storage node holds enough information to reconstruct the model.
Two functions cover the entire lifecycle: guardModel() splits model weights into XorIDA shares and distributes them across N storage nodes with K-of-N threshold reconstruction. reconstructModel() recombines any K shares to recover the original weights with full HMAC and SHA-256 integrity verification.
Each model weight array is automatically chunked into 4MB blocks to handle multi-gigabyte models efficiently. Every chunk gets its own HMAC-SHA256 signature before splitting. After reconstruction, the full model's SHA-256 hash is verified against the manifest to guarantee authenticity.
A 7GB frontier LLM splits into 1,750 chunks across 3 storage nodes (2-of-3 threshold). An attacker who compromises any single node learns nothing about the model weights — not computationally hard to break, but mathematically impossible.
Developer Experience
Xguard provides a minimal two-function API with detailed error codes and clear documentation. Split and reconstruct model weights in under 20 lines of code.
import { guardModel, reconstructModel } from '@private.me/modelguard'; // Load model weights (7GB transformer) const weights = await fs.readFile('fraud-detector-v3.bin'); const metadata = { name: 'fraud-detector-v3', version: '3.1.0', architecture: 'transformer', parameterCount: 125_000_000, modelSize: weights.byteLength, }; const config = { storageNodes: 3, threshold: 2 }; // Split across 3 nodes, any 2 can reconstruct const result = await guardModel(weights, metadata, config); if (!result.ok) throw new Error(result.error.message); const { manifest, shares } = result.value; // Store shares[chunkIndex][nodeIndex] to independent nodes await storeToNode(0, shares.map(c => c[0])); await storeToNode(1, shares.map(c => c[1])); await storeToNode(2, shares.map(c => c[2])); // Reconstruct from any 2 nodes const sharesFromNodes = [ await fetchFromNode(0), await fetchFromNode(2), ]; const rebuilt = await reconstructModel(manifest, sharesFromNodes); if (!rebuilt.ok) throw new Error(rebuilt.error.message); // rebuilt.value is identical to original weights console.assert(rebuilt.value.byteLength === weights.byteLength);
Error Handling
All operations return Result<T, ModelGuardError> with discriminated error codes for precise handling:
| Code | Category | When |
|---|---|---|
| INVALID_CONFIG | Configuration | storageNodes < 2, threshold < 2, threshold > storageNodes |
| SPLIT_FAILED | XorIDA | XorIDA splitting operation failure |
| HMAC_FAILED | Integrity | HMAC verification failed during chunk reconstruction |
| RECONSTRUCT_FAILED | XorIDA | XorIDA reconstruction or unpadding failure |
| INSUFFICIENT_SHARES | Configuration | Fewer shares than threshold provided for a chunk |
| INTEGRITY_FAILED | Verification | Full model SHA-256 hash mismatch after reconstruction |
The Problem
AI model weights represent the most valuable digital assets ever created. A frontier LLM costs $100M+ to train. Yet these weights sit in centralized storage systems vulnerable to theft, tampering, and insider threats.
The Old Way: Single-Point Storage
Traditional model storage concentrates all weights in a single location:
- Cloud buckets: S3, GCS, Azure Blob — complete model in one account
- Model registries: Hugging Face Hub, MLflow — full weights on one platform
- Encrypted archives: AES-256 protects data at rest, but the decryption key lives on the same system
- Insider threats: Any admin with bucket access can exfiltrate the entire model
The 2023 Meta LLaMA leak demonstrated the risk: a single compromised storage location exposed a $10M+ training investment to unrestricted distribution.
The New Way: XorIDA Threshold Splitting
Xguard eliminates the single point of failure by splitting model weights across independent storage nodes:
- No complete model anywhere: Each node stores only K-of-N shares — insufficient to reconstruct
- Information-theoretic security: Individual shares reveal zero information about the weights (XorIDA over GF(2))
- Fault tolerance: Model survives N-K node failures — any K nodes can reconstruct
- Geographic distribution: Shares stored across jurisdictions — one legal order cannot compel full disclosure
Real-World Use Cases
Xguard protects high-value models across industries where IP theft or tampering creates catastrophic risk.
Solution Architecture
Xguard implements a three-layer security architecture: chunking for scalability, XorIDA threshold sharing for information-theoretic protection, and dual-layer integrity verification (per-chunk HMAC + full-model SHA-256).
Chunked Processing
Multi-gigabyte models are automatically chunked into 4MB blocks (configurable). Each chunk is independently:
- HMAC-signed: HMAC-SHA256 generated before splitting for integrity verification
- PKCS#7 padded: Padded to XorIDA block size (nextOddPrime(N) - 1 bytes)
- XorIDA-split: Threshold shared across N storage nodes
- Indexed: chunkId, chunkIndex, totalChunks tracked per share
const config: ModelGuardConfig = { storageNodes: 3, // N shares produced per chunk threshold: 2, // K shares required to reconstruct chunkSize: 4_194_304 // 4MB chunks (optional, default) }; // 7GB model → 1,750 chunks × 3 shares = 5,250 total shares
Integrity Verification
Two-layer integrity checking prevents tampering:
Layer 1: Per-Chunk HMAC-SHA256
Before XorIDA splitting, each chunk is HMAC-signed with a randomly generated 32-byte key. The HMAC signature and key travel with each share. During reconstruction:
- Collect K shares for the chunk
- XorIDA reconstruct → padded plaintext
- PKCS#7 unpad → original chunk bytes
- Verify HMAC before proceeding — tampered chunks rejected immediately
Layer 2: Full-Model SHA-256
After all chunks are reconstructed and concatenated, the full model's SHA-256 hash is computed and compared against the manifest. This catches:
- Chunk reordering attacks: Swapping chunk order invalidates the final hash
- Missing chunks: Incomplete reconstruction detected
- Manifest tampering: Mismatched model metadata caught
Integration Patterns
Xguard integrates with existing model storage infrastructure via simple adapter patterns. No changes required to training pipelines or inference servers.
Pattern 1: Multi-Cloud Distribution
Split model weights across independent cloud providers for vendor lock-in avoidance and geographic redundancy.
const { manifest, shares } = (await guardModel(weights, metadata, { storageNodes: 3, threshold: 2 })).value; // Store shares to independent cloud providers await Promise.all([ uploadToS3('model-weights-node-0', shares.map(c => c[0])), uploadToGCS('model-weights-node-1', shares.map(c => c[1])), uploadToAzure('model-weights-node-2', shares.map(c => c[2])), ]); // Reconstruct from any 2 providers const [node0, node2] = await Promise.all([ downloadFromS3('model-weights-node-0'), downloadFromAzure('model-weights-node-2'), ]); const weights = (await reconstructModel(manifest, [node0, node2])).value;
Pattern 2: On-Premise + Cloud Hybrid
Distribute shares across on-premise data centers and cloud providers for regulatory compliance (data residency) + disaster recovery.
const { manifest, shares } = (await guardModel(weights, metadata, { storageNodes: 4, threshold: 3 })).value; await Promise.all([ uploadToOnPrem('datacenter-1', shares.map(c => c[0])), uploadToOnPrem('datacenter-2', shares.map(c => c[1])), uploadToS3('model-weights-node-2', shares.map(c => c[2])), uploadToGCS('model-weights-node-3', shares.map(c => c[3])), ]); // Survives single datacenter + single cloud provider failure
Pattern 3: CI/CD Model Registry
Integrate into ML training pipelines with automatic model weight protection on every checkpoint save.
import mlflow from modelguard import guard_model, upload_shares with mlflow.start_run(): model = train_transformer(...) weights = model.state_dict_bytes() # Guard before saving manifest, shares = guard_model(weights, metadata, config) # Upload shares to MLflow artifact store + backup locations upload_shares(manifest, shares, [ 'mlflow://artifacts/model-node-0', 's3://backup/model-node-1', 'gs://disaster-recovery/model-node-2', ]) mlflow.log_artifact('manifest.json')
Storage Distribution Strategies
Xguard share placement strategy determines threat resistance. Different industries require different storage topologies.
| Strategy | Configuration | Threat Model | Recovery |
|---|---|---|---|
| Multi-Cloud | 3 clouds, 2-of-3 | Single cloud provider breach, vendor lock-in | Survives 1 provider failure |
| Hybrid Cloud | 2 on-prem + 2 cloud, 3-of-4 | Data residency + disaster recovery | Survives 1 datacenter + 1 cloud failure |
| Geographic | 5 continents, 3-of-5 | Single jurisdiction legal order | Survives 2 region failures |
| Defense | SCIF + SIPRNET + air-gap, 3-of-4 | Nation-state espionage, physical intrusion | Survives 1 facility compromise |
| Maximum Fault Tolerance | 7 nodes, 4-of-7 | Catastrophic infrastructure failure | Survives 3 node failures |
Security Properties
Xguard provides information-theoretic security for model weights at rest. Individual shares reveal zero information about the original weights.
Information-Theoretic Security
XorIDA threshold sharing over GF(2) provides unconditional security:
- No computational assumptions: Security does not depend on hardness of factoring, discrete log, or lattice problems
- Quantum-proof: Remains secure even against cryptographically relevant quantum computers
- Perfect secrecy: Any K-1 shares reveal zero mutual information about the plaintext (Shannon's information theory)
- No key management: The split IS the security — no separate encryption keys to protect
Threat Resistance
| Attack Vector | Traditional Storage | Xguard (2-of-3) |
|---|---|---|
| Single storage breach | ✗ Full model exposed | ✓ Zero information leaked |
| Insider threat | ✗ Admin exfiltrates all weights | ✓ Single admin has insufficient shares |
| Ransomware | ✗ All weights encrypted by attacker | ✓ 2 untouched nodes reconstruct |
| Cloud provider compromise | ✗ Provider sees all weights | ✓ Provider sees 1-of-3 shares (useless) |
| Legal subpoena | ✗ Full disclosure compelled | ✓ Single jurisdiction yields 1 share |
| Quantum computer | ✗ AES-256 breakable (Grover) | ✓ Information-theoretic security |
Integrity Guarantees
HMAC-SHA256 per-chunk verification ensures tamper detection:
- Tampered shares rejected: Modified share data fails HMAC verification before reconstruction
- Substitution attacks prevented: Attacker cannot swap shares between chunks (chunk IDs are HMAC-protected)
- Rollback attacks impossible: Old shares fail SHA-256 verification against current manifest
- Birthday attack resistance: HMAC-SHA256 provides 128-bit collision resistance
Performance Benchmarks
Xguard overhead is dominated by network I/O for share distribution, not cryptographic operations. Splitting and reconstruction are fast enough to integrate into CI/CD pipelines.
Splitting Performance
| Model Size | Chunks | Config | Split Time | Throughput |
|---|---|---|---|---|
| 125M params (500MB) | 125 | 2-of-3 | 2.8 sec | 179 MB/s |
| 1.5B params (6GB) | 1,500 | 2-of-3 | 34 sec | 176 MB/s |
| 7B params (28GB) | 7,000 | 2-of-3 | 159 sec | 176 MB/s |
| 70B params (280GB) | 70,000 | 3-of-5 | 1,610 sec | 174 MB/s |
Split throughput is consistent across model sizes (~176 MB/s on modern hardware) because chunking parallelizes HMAC and XorIDA operations. A 7B model splits in under 3 minutes.
Reconstruction Performance
| Model Size | Chunks | Config | Reconstruct Time | Throughput |
|---|---|---|---|---|
| 125M params (500MB) | 125 | 2-of-3 | 3.1 sec | 161 MB/s |
| 1.5B params (6GB) | 1,500 | 2-of-3 | 38 sec | 158 MB/s |
| 7B params (28GB) | 7,000 | 2-of-3 | 178 sec | 157 MB/s |
| 70B params (280GB) | 70,000 | 3-of-5 | 1,795 sec | 156 MB/s |
Reconstruction is slightly slower than splitting due to HMAC verification overhead. A 7B model reconstructs in under 3 minutes.
Network Transfer Overhead
For 2-of-3 configuration, total storage is 3× original model size (N shares of equal size). Network transfer during reconstruction:
- Download: 2× model size (K shares)
- Upload: 3× model size (N shares)
- Example: 7GB model → 21GB upload, 14GB download for reconstruction
Honest Limitations
Xguard is not a complete solution for all model security challenges. Understanding the boundaries is critical for correct deployment.
What Xguard Does NOT Protect
1. Weights in Memory During Inference
Once reconstructed for inference, model weights exist in GPU/CPU memory as plaintext. Xguard protects weights at rest, not during execution. Memory dumping attacks can extract loaded weights. Mitigation: Use Trusted Execution Environments (TEEs) like Intel SGX or AMD SEV for in-memory protection.
2. Model Architecture or Hyperparameters
Xguard protects weight values, not the model's architecture definition (layer counts, attention heads, hidden dimensions). The manifest includes architecture: 'transformer' as metadata. An attacker who knows the architecture can attempt knowledge distillation attacks by querying the deployed model.
3. Training Data or Gradient Leakage
Model weights encode information about the training data. Even with weights protected, model inversion attacks can extract training examples by querying the model. Xguard does not prevent membership inference or data extraction attacks against deployed models.
4. Side-Channel Attacks
Timing attacks, power analysis, or electromagnetic emanations during reconstruction are out of scope. If an attacker has physical access to observe reconstruction, constant-time cryptographic primitives should be used.
Operational Considerations
Share Synchronization
When model weights are updated (fine-tuning, retraining), all N shares must be regenerated and redistributed. Partial updates are not supported. A model checkpoint workflow should atomically replace all shares to prevent version skew.
Threshold Choice
Higher threshold K increases security (more nodes must be compromised) but reduces fault tolerance (fewer node failures tolerated). Production deployments should choose K such that:
- N - K ≥ 2: Survives at least 2 node failures
- K > N/2: Prevents majority coalition attacks
- Example: 3-of-5 is safer than 2-of-3 for the same security level
No Built-In Share Distribution
Xguard produces shares as in-memory arrays. The application is responsible for distributing shares to storage nodes. No network transport, authentication, or access control is provided. Use existing infrastructure (S3, GCS, SFTP, etc.) for share storage.
Complete Error Reference
All Xguard operations return Result types with discriminated error codes for precise error handling.
| Code | Category | Description | Mitigation |
|---|---|---|---|
| INVALID_CONFIG | Configuration | storageNodes < 2, threshold < 2, threshold > storageNodes, chunkSize < 1, or weights.length === 0 | Validate config before calling guardModel |
| SPLIT_FAILED | XorIDA | XorIDA splitting operation failed (internal cryptographic error) | Check Web Crypto API availability, retry operation |
| HMAC_FAILED | Integrity | HMAC-SHA256 verification failed during chunk reconstruction — share was tampered with | Reject share, fetch from different storage node |
| RECONSTRUCT_FAILED | XorIDA | XorIDA reconstruction or PKCS#7 unpadding failed | Verify shares are from same manifest, check share indices |
| INSUFFICIENT_SHARES | Configuration | Fewer than threshold shares provided for a chunk | Provide at least K shares for every chunk |
| INTEGRITY_FAILED | Verification | Full model SHA-256 hash does not match manifest.modelHash after reconstruction | Manifest was tampered with or shares are from different models |
const result = await reconstructModel(manifest, shares); if (!result.ok) { switch (result.error.code) { case 'HMAC_FAILED': // Share was tampered with — fetch from backup node const backupShares = await fetchFromBackup(); return reconstructModel(manifest, backupShares); case 'INTEGRITY_FAILED': // Full model hash mismatch — possible manifest tampering throw new Error('Model integrity check failed'); case 'INSUFFICIENT_SHARES': // Need more shares const additionalShares = await fetchAdditionalNode(); return reconstructModel(manifest, [...shares, ...additionalShares]); default: throw new Error(result.error.message); } }
Complete API Surface
Xguard exports 2 functions and 6 TypeScript types. The entire public API fits on one page.
Functions
Types
interface ModelMetadata { readonly name: string; readonly version: string; readonly architecture: string; readonly parameterCount: number; readonly modelSize: number; } interface ModelGuardConfig { readonly storageNodes: number; readonly threshold: number; readonly chunkSize?: number; } interface ModelWeightShare { readonly index: number; readonly total: number; readonly threshold: number; readonly chunkId: string; readonly chunkIndex: number; readonly totalChunks: number; readonly data: string; readonly hmac: string; readonly originalSize: number; } interface ModelManifest { readonly id: string; readonly metadata: ModelMetadata; readonly totalChunks: number; readonly modelHash: string; readonly config: ModelGuardConfig; readonly createdAt: string; } interface ModelGuardResult { readonly manifest: ModelManifest; readonly shares: ModelWeightShare[][]; } type ModelGuardError = | { readonly code: 'INVALID_CONFIG'; readonly message: string } | { readonly code: 'SPLIT_FAILED'; readonly message: string } | { readonly code: 'HMAC_FAILED'; readonly message: string } | { readonly code: 'RECONSTRUCT_FAILED'; readonly message: string } | { readonly code: 'INSUFFICIENT_SHARES'; readonly message: string } | { readonly code: 'INTEGRITY_FAILED'; readonly message: string };
Threat Model
Xguard assumes a powerful adversary who can compromise any K-1 storage nodes but cannot compromise K or more nodes simultaneously.
Assumptions
Trusted
- Web Crypto API implementation: crypto.subtle.digest and crypto.randomUUID are correctly implemented
- HMAC-SHA256 primitives: @private.me/crypto implementation is correct (open-source, audited)
- Training environment: Model weights are not compromised during training or initial split
- Manifest integrity: Manifest is stored separately from shares and protected by access control
Untrusted
- Storage nodes: Any storage node may be compromised, coerced, or cooperating with adversary
- Network: All network traffic may be observed or manipulated
- Cloud providers: Cloud providers may collude or be compelled by legal orders
- Storage administrators: Admins with node access may be malicious or coerced
Attack Scenarios
| Attack | Adversary Capability | Xguard Defense |
|---|---|---|
| Passive observation | Adversary reads K-1 shares | Information-theoretic security — learns nothing |
| Active tampering | Adversary modifies share data | HMAC-SHA256 verification rejects tampered shares |
| Share substitution | Adversary swaps shares between chunks | Chunk IDs are HMAC-protected, final hash mismatch |
| Replay attack | Adversary replays old shares | SHA-256 verification against manifest catches stale shares |
| Manifest tampering | Adversary modifies modelHash in manifest | Reconstruction succeeds but final hash mismatch detected |
| Collusion | K-1 nodes cooperate | Still mathematically impossible to reconstruct |
| Legal compulsion | Court order to single jurisdiction | Geographic distribution — single order yields 1 share |
Out of Scope
Xguard does NOT protect against:
- Compromise of K or more nodes: If adversary controls K nodes, they can reconstruct
- Timing side-channels: Reconstruction timing may leak information about chunk sizes
- Physical attacks: Memory extraction from reconstruction server
- Training data poisoning: Adversary who controls training data can embed backdoors in weights
- Model inversion: Deployed model may leak training data via queries
Deployment Options
SaaS Recommended
Fully managed infrastructure. Call our REST API, we handle scaling, updates, and operations.
- Zero infrastructure setup
- Automatic updates
- 99.9% uptime SLA
- Enterprise SLA available
SDK Integration
Embed directly in your application. Runs in your codebase with full programmatic control.
npm install @private.me/modelguard- TypeScript/JavaScript SDK
- Full source access
- Enterprise support available
On-Premise Upon Request
Enterprise CLI for compliance, air-gap, or data residency requirements.
- Complete data sovereignty
- Air-gap capable deployment
- Custom SLA + dedicated support
- Professional services included
Enterprise On-Premise Deployment
While modelGuard is primarily delivered as SaaS or SDK, we build dedicated on-premise infrastructure for customers with:
- Regulatory mandates — HIPAA, SOX, FedRAMP, CMMC requiring self-hosted processing
- Air-gapped environments — SCIF, classified networks, offline operations
- Data residency requirements — EU GDPR, China data laws, government mandates
- Custom integration needs — Embed in proprietary platforms, specialized workflows
Includes: Enterprise CLI, Docker/Kubernetes orchestration, RBAC, audit logging, and dedicated support.