Security & Privacy
Understanding the privacy-first architecture and security guarantees of ProjectZero Prompt Mining.
Privacy-First Architecture
Core Privacy Promise
Full prompts NEVER leave your infrastructure. Only cryptographic hashes (keccak256) are sent to PZERO Gateway and stored on-chain. The original prompt text stays completely private on your servers.
This architecture ensures that you maintain complete data sovereignty while still enabling blockchain-verified proof of prompt ownership and user rewards.
Data Privacy Breakdown
Stays on your infrastructure
- ✓ Full prompt text
- ✓ User conversation history
- ✓ LLM responses
- ✓ Context and metadata
- ✓ Application data
Transmitted via HTTPS API
- ✓ Prompt hash (32 bytes)
- ✓ Author wallet address
- ✓ Reward amount
- ✓ Your API key
- NO full prompt text
Public blockchain data
- ✓ Prompt hash (irreversible)
- ✓ Author address
- ✓ Timestamp
- ✓ Reward amount
- NO recoverable content
How It Works
- ✓ Full prompt text stored
- ✓ Hash calculated locally
- ✓ Privacy maintained
- ✓ Only hash transmitted
- ✓ Hash is irreversible
- ✓ Content unknowable
// On your server (PRIVATE)
const originalPrompt = "What is quantum computing?"
// Hash locally
const promptHash = keccak256(originalPrompt)
// => 0x1a2b3c4d5e6f...
// ONLY the hash is sent to PZERO Gateway
await pzeroGateway.authorize({
promptHash, // ← Only this 32-byte hash
author,
activityPoints
})
// Original prompt NEVER transmitted
// Hash cannot be reversed to get original textHash-Only Architecture
The system uses Keccak256 (same as Ethereum) for one-way cryptographic hashing.
Why Hashing is Secure
- One-way function: Cannot reverse a hash to get the original prompt
- Collision-resistant: Virtually impossible to find two prompts with the same hash
- Deterministic: Same prompt always produces the same hash (enables verification)
- Fixed length: All hashes are exactly 32 bytes, regardless of prompt length
import { keccak256, toUtf8Bytes } from 'ethers'
// Different prompts = Different hashes
const hash1 = keccak256(toUtf8Bytes("What is AI?"))
// => 0xabc123...
const hash2 = keccak256(toUtf8Bytes("What is AI!")) // Note the exclamation
// => 0xdef456... (completely different)
// Same prompt = Same hash (always)
const hash3 = keccak256(toUtf8Bytes("What is AI?"))
// => 0xabc123... (identical to hash1)Technical Note: Even if someone intercepts the hash (0x1a2b3c...), they cannot determine what the original prompt was. Brute-forcing is computationally infeasible for non-trivial prompts.
API Key Security
Your ProjectZero API key authenticates your service with the PZERO Gateway.
Best Practices
- ✓ Store in environment variables
- ✓ Never commit to git
- ✓ Use different keys for dev/prod
- ✓ Rotate keys periodically
- ✓ Server-side only (never expose to frontend)
Never Do This
- Do not hardcode secrets in source code
- Do not expose keys inside client-side JavaScript
- Do not share keys between services
- Do not commit .env files to git
- Do not log API keys in console/files
Secure Environment Setup
# GOOD: Environment variables
PZERO_API_KEY=pzero_live_sk_abcdef123456
# GOOD: .gitignore includes .env
# echo ".env" >> .gitignore// ❌ NEVER DO THIS
const apiKey = "pzero_live_sk_abcdef123456" // Hardcoded!
// ❌ NEVER DO THIS
const response = await fetch('/api/prompts', {
headers: {
'x-api-key': 'pzero_live_sk_abcdef123456' // Exposed in frontend!
}
})// ✓ CORRECT: Server-side only
const apiKey = process.env.PZERO_API_KEY
// ✓ CORRECT: Never sent to client
const authorization = await pzeroClient.authorize({
promptHash,
author,
activityPoints
}, {
headers: { 'x-api-key': apiKey }
})Wallet Management
If using backend-signed or meta-transaction modes, your backend wallet private key must be secured.
Critical Security
Your backend wallet private key controls funds and permissions. If compromised, attackers can drain gas funds or mint unauthorized prompts.
- • Store in environment variables, never in code
- • Use hardware security modules (HSM) in production
- • Consider using AWS KMS, Azure Key Vault, or similar
- • Implement withdrawal limits and monitoring
Wallet Security Strategies
1. Dedicated Gas Wallet
Create a separate wallet ONLY for gas sponsorship. Keep minimal funds (e.g., $100-500 worth of ETH).
// Dedicated wallet with limited funds
PRIVATE_KEY=0x... # ← Only has gas money, no other permissions2. Key Management Service
Use AWS KMS, Azure Key Vault, or Google Cloud KMS for production.
import { KmsEthersSigner } from '@aws-sdk/kms-ethers-signer'
// Sign with AWS KMS (key never exposed)
const signer = new KmsEthersSigner({
keyId: process.env.AWS_KMS_KEY_ID,
region: 'us-east-1'
})3. Multi-Sig Wallet
For enterprise deployments, use a multi-signature wallet (e.g., Gnosis Safe) requiring multiple approvals for withdrawals.
Transport Security
All communication uses HTTPS/TLS encryption.
PZERO Gateway
- ✓ TLS 1.3 encryption
- ✓ Certificate pinning
- ✓ HTTPS only (HTTP auto-redirects)
Blockchain RPC
- ✓ HTTPS RPC endpoints
- ✓ Signed transactions
- ✓ Nonce management
Integration Security Best Practices
Follow these security best practices when integrating Prompt Mining into your LLM service.
1. Server-Side Only Integration
Always hash prompts and call the PZERO Gateway from your backend. Never expose API keys or prompt hashing logic to frontend code.
// ✓ CORRECT: Backend API route (Next.js example)
export async function POST(request: Request) {
const { promptText, userAddress } = await request.json()
// Hash on server
const hash = keccak256(toUtf8Bytes(promptText))
// Call PZERO Gateway from server
const auth = await pzeroGateway.authorize({
promptHash: hash,
author: userAddress,
activityPoints: 100
}, {
headers: { 'x-api-key': process.env.PZERO_API_KEY }
})
return Response.json({ hash, signature: auth.signature })
}2. Input Validation
Validate and sanitize all inputs before hashing. Prevent injection attacks and ensure consistent hashing.
// Validate before hashing
function validatePrompt(prompt: string): boolean {
// Check length (reasonable limits)
if (!prompt || prompt.length < 1 || prompt.length > 10000) {
return false
}
// Sanitize: trim whitespace
prompt = prompt.trim()
// Check for suspicious patterns
if (containsScriptTags(prompt)) {
return false
}
return true
}3. Rate Limiting
Implement rate limiting on your backend to prevent abuse and quota exhaustion.
// Rate limiting example (Redis-based)
const rateLimiter = new RateLimiter({
maxRequests: 100,
windowMs: 60 * 1000 // 1 minute
})
app.post('/api/mint-prompt', async (req, res) => {
const userId = req.user.id
if (!await rateLimiter.check(userId)) {
return res.status(429).json({
error: 'Rate limit exceeded'
})
}
// Proceed with minting
})4. Error Handling
Handle errors gracefully without exposing sensitive information. Log errors securely for debugging.
try {
const result = await mintPrompt(hash, author, points)
} catch (error) {
// ✓ Log securely (don't log API keys!)
logger.error('Mint failed', {
hash,
error: error.message,
// DO NOT log: API keys, private keys, full prompts
})
// ✓ Return user-friendly message
return {
error: 'Failed to mint prompt. Please try again.'
}
// Never return raw error with stack trace to client
}5. Monitoring & Alerting
Monitor your integration for suspicious activity, quota usage, and failed transactions.
- • Track daily mint volume (detect anomalies)
- • Monitor API error rates
- • Alert on quota nearing limit (e.g., 80% of monthly quota)
- • Track gas wallet balance (auto-refill when low)
- • Log failed signature verifications (security alert)
6. Secure Configuration
Use environment variables and secrets management for all sensitive configuration.
# PZERO Configuration
PZERO_API_KEY=pzero_test_sk_...
PZERO_API_URL=https://pm-gateway.projectzero.io
# Blockchain Configuration (use different values per environment)
PRIVATE_KEY=0x... # From secure vault
RPC_URL=https://nexera-testnet.rpc.url
# Contract Addresses
PROMPT_MINER_ADDRESS=0x...
ACTIVITY_POINTS_ADDRESS=0x...
# Security
NODE_ENV=production
LOG_LEVEL=info # Use 'debug' only in developmentSecurity Checklist Before Going Live
- ☐ API keys stored in environment variables (not hardcoded)
- ☐ Private keys secured in KMS or hardware wallet
- ☐ Rate limiting enabled on backend endpoints
- ☐ Input validation for all user-submitted data
- ☐ Monitoring and alerting configured
- ☐ Separate API keys for dev/staging/production
- ☐ HTTPS enabled for all endpoints
- ☐ Error messages don't leak sensitive info
- ☐ Gas wallet has auto-refill mechanism
- ☐ Tested failover scenarios (Gateway downtime, RPC errors)
Audit & Compliance
ProjectZero smart contracts have been audited by leading security firms.
Security Audits
- Smart Contract Audit: Third-party security audit completed (Q4 2024)
- Open Source: All contracts are open-source and verifiable on Nexera Explorer
- Bug Bounty: Responsible disclosure program for security researchers
For audit reports and security disclosures, contact security@projectzero.io