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

Private Data

Stays on your infrastructure

  • ✓ Full prompt text
  • ✓ User conversation history
  • ✓ LLM responses
  • ✓ Context and metadata
  • ✓ Application data
PZERO Gateway Sees

Transmitted via HTTPS API

  • ✓ Prompt hash (32 bytes)
  • ✓ Author wallet address
  • ✓ Reward amount
  • ✓ Your API key
  • NO full prompt text
On-Chain Storage

Public blockchain data

  • ✓ Prompt hash (irreversible)
  • ✓ Author address
  • ✓ Timestamp
  • ✓ Reward amount
  • NO recoverable content

How It Works

On Your Server
  • ✓ Full prompt text stored
  • ✓ Hash calculated locally
  • ✓ Privacy maintained
On-Chain & Gateway
  • ✓ Only hash transmitted
  • ✓ Hash is irreversible
  • ✓ Content unknowable
privacy-architecture.ts
// 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 text

Hash-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
typescript
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

.env
# GOOD: Environment variables
PZERO_API_KEY=pzero_live_sk_abcdef123456

# GOOD: .gitignore includes .env
# echo ".env" >> .gitignore
BAD-EXAMPLE.ts
// ❌ 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!
  }
})
GOOD-EXAMPLE.ts
// ✓ 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).

typescript
// Dedicated wallet with limited funds
PRIVATE_KEY=0x...  # ← Only has gas money, no other permissions

2. Key Management Service

Use AWS KMS, Azure Key Vault, or Google Cloud KMS for production.

typescript
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.

PZERO Gateway Authorization Flow

Understanding how PZERO Gateway signs authorization helps you verify security.

Authorization Flow

  1. Your service sends: Prompt hash, author address, reward amount
  2. PZERO Gateway checks:
    • API key is valid
    • Quota not exceeded for your tier
    • Request rate within limits
  3. PZERO signs: Creates cryptographic signature with PZERO's private key
  4. Blockchain verifies: Smart contract checks PZERO signature before minting
typescript
// What PZERO signs (simplified)
const message = keccak256(abi.encodePacked(
  promptHash,      // Your prompt hash
  author,          // User address
  activityPoints,  // Reward amount
  nonce,           // Prevents replay attacks
  expiresAt        // Signature expiry (typically 15 min)
))

const signature = sign(message, PZERO_PRIVATE_KEY)

// Smart contract verifies this signature
function mint(...) {
  require(
    recoverSigner(message, signature) == PZERO_SIGNER_ADDRESS,
    "Invalid PZERO signature"
  )
  // ... mint prompt
}

Security Benefit: Even if your API key is compromised, attackers cannot mint prompts without PZERO's signature. PZERO enforces quota limits and validates all requests.

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.

typescript
// ✓ 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.

typescript
// 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.

typescript
// 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.

typescript
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.

.env.example
# 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 development

Security 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