• Skip to main content
  • Skip to navigation
  • Skip to search
    Petunia™
    FeaturesPricingIntegrationsAboutContact
    Log inStart free trialSign up
    Loading
    Petunia™

    Reimagining customer communication for the modern business.

    Product

    • Features
    • Pricing
    • Integrations
    • Roadmap
    • What's New

    Resources

    • Help Center
    • Documentation
    • Guides
    • API Reference
    • Community
    • Support

    Company

    • About Us
    • Careers
    • Blog
    • Press
    • Contact

    © 2026 Gray Group International LLC. All rights reserved.·
    Made by gardenpatch 🌱

    Privacy PolicyTerms of ServiceCookie Policy

    Petunia™ is a trademark of Gray Group International LLC. The Petunia name, brand, product design, and content are proprietary. Unauthorized use, imitation, or copying is prohibited.

    Documentation

    ACCOUNT_TOKEN_ENCRYPTION

    docs/features/ACCOUNT_TOKEN_ENCRYPTION.md
    Docs homeGuidesSupport
    Quick links
    Start here
    How the docs are organized.
    Environment setup
    Configure env + run locally.
    Unified Inbox
    Inbox concepts & behavior.
    Voice AI setup
    Providers, Twilio, testing.
    Pricing model
    Source-of-truth pricing.
    Operations runbook
    How to operate safely.

    Account OAuth Token Encryption

    This document describes the implementation of encryption for OAuth tokens stored in the Account table.

    Overview

    The Account table stores OAuth provider credentials (access tokens and refresh tokens) for third-party authentication providers like Google and Facebook. These tokens must be encrypted at rest for security and compliance.

    Implementation

    1. Encryption Utilities

    Location: /lib/utils/oauth-token-encryption.ts

    This module provides wrapper functions for encrypting and decrypting OAuth tokens using the existing AES-256-GCM encryption infrastructure from /lib/utils/encryption.ts.

    Key Functions:

    • encryptAccessToken(token, userId?) - Encrypts an OAuth access token
    • decryptAccessToken(encrypted, userId?) - Decrypts an OAuth access token
    • encryptRefreshToken(token, userId?) - Encrypts an OAuth refresh token
    • decryptRefreshToken(encrypted, userId?) - Decrypts an OAuth refresh token
    • isTokenEncrypted(token) - Checks if a token is already encrypted
    • safeEncryptToken(token, userId?) - Idempotent encryption (safe to call multiple times)

    Features:

    • AES-256-GCM Encryption: Industry-standard authenticated encryption
    • Backward Compatibility: Gracefully handles plaintext legacy tokens during migration
    • Idempotent: Safe to run encryption multiple times on the same data
    • Error Handling: Comprehensive logging and error reporting

    2. Prisma Middleware

    Location: /lib/database/account-encryption-middleware.ts

    This middleware automatically encrypts tokens on write operations and decrypts them on read operations, making the encryption transparent to application code.

    Supported Operations:

    • create - Encrypts tokens when creating new Account records
    • update - Encrypts tokens when updating Account records
    • upsert - Encrypts tokens for both create and update paths
    • createMany / updateMany - Encrypts tokens in batch operations
    • findUnique / findFirst / findMany - Decrypts tokens on read

    Registration: The middleware is automatically registered in /lib/database.ts:

    import { registerAccountEncryption } from './database/account-encryption-middleware';
    
    if (typeof window === 'undefined') {
      registerAccountEncryption(basePrisma);
    }
    

    3. Migration Script

    Location: /scripts/migrations/encrypt-oauth-tokens.ts

    This script encrypts existing plaintext tokens in the database.

    Usage:

    # Dry run (no changes)
    npx tsx scripts/migrations/encrypt-oauth-tokens.ts
    
    # Execute migration
    npx tsx scripts/migrations/encrypt-oauth-tokens.ts --execute
    

    Features:

    • Dry-run Mode: Preview changes before executing
    • Idempotent: Safe to run multiple times (skips already-encrypted tokens)
    • Comprehensive Reporting: Shows detailed statistics of the migration
    • Error Handling: Continues processing even if individual records fail

    Security Features

    Encryption Format

    Tokens are encrypted using AES-256-GCM with the following format:

    iv:authTag:encryptedContent
    

    All components are base64-encoded and separated by colons.

    Key Derivation

    Encryption uses PBKDF2 key derivation with:

    • Algorithm: SHA-256
    • Iterations: 100,000 (high security)
    • Key Length: 256 bits
    • Salt: Configurable via CREDENTIALS_ENCRYPTION_SALT environment variable

    Environment Variables

    Required:

    • CREDENTIALS_ENCRYPTION_KEY - Master encryption key (must be at least 32 characters)

    Optional:

    • CREDENTIALS_ENCRYPTION_SALT - Custom salt for key derivation (defaults to 'petunia-encryption-salt')

    Key Validation

    The encryption system validates keys to prevent weak or test values:

    • Minimum length: 32 characters
    • Rejects common weak patterns (e.g., "password", "test", "demo")
    • Rejects repeated characters
    • Validates in production mode (warnings in development)

    Migration Process

    Prerequisites

    1. Ensure CREDENTIALS_ENCRYPTION_KEY is set in your environment:

      # Generate a secure key (example)
      openssl rand -base64 32
      
    2. Set the key in your environment:

      export CREDENTIALS_ENCRYPTION_KEY="your-secure-key-here"
      

    Migration Steps

    1. Dry Run - Test the migration without making changes:

      npx tsx scripts/migrations/encrypt-oauth-tokens.ts
      
    2. Review Output - Check the migration report:

      📊 Migration Summary
      ═══════════════════════════════════════════════════════════════════
      Total Account records: 150
      Already encrypted: 0
      Newly encrypted: 150
      Failed: 0
      Skipped: 0
      
    3. Execute - Run the actual migration:

      npx tsx scripts/migrations/encrypt-oauth-tokens.ts --execute
      
    4. Verify - Check the results and ensure all tokens are encrypted

    Rollback

    If you need to rollback:

    1. The migration script does not modify the database structure, only data
    2. You can restore from a database backup taken before the migration
    3. The decryption functions handle both encrypted and plaintext tokens during the transition

    Backward Compatibility

    The implementation includes backward compatibility features:

    1. Plaintext Token Support: Decryption functions detect plaintext tokens and return them as-is
    2. Gradual Migration: Old plaintext tokens continue to work while migration is in progress
    3. Idempotent Encryption: Re-running encryption on already-encrypted data has no effect

    Testing

    Unit Tests

    Location: /tests/lib/utils/oauth-token-encryption.test.ts

    Run tests:

    npm test -- tests/lib/utils/oauth-token-encryption.test.ts
    

    Test Coverage:

    • Encryption/decryption of access tokens
    • Encryption/decryption of refresh tokens
    • Backward compatibility with plaintext tokens
    • Round-trip encryption/decryption
    • Error handling (empty tokens, invalid formats)
    • Idempotent encryption (safeEncryptToken)

    Integration Tests

    The middleware is automatically tested through any tests that interact with the Account model via Prisma.

    Monitoring

    The encryption utilities include comprehensive logging:

    • Info: Migration progress, encryption operations
    • Debug: Individual token encryption/decryption events
    • Warn: Legacy plaintext tokens encountered
    • Error: Encryption/decryption failures

    All logs are sent through the application's logging infrastructure and can be monitored in production.

    Performance Considerations

    PBKDF2 Key Caching

    The encryption utilities implement key caching to avoid repeated PBKDF2 derivations:

    • Cache TTL: 5 minutes
    • Cache Size: Limited to 10 entries (LRU)
    • Impact: Reduces encryption overhead from ~50ms to <5ms per operation

    Database Performance

    • Middleware Overhead: Minimal (<1ms per token)
    • Migration Performance: Processes tokens in sequence to avoid overwhelming the database
    • Index Usage: Uses existing Account table indexes (no additional indexes required)

    Compliance

    This implementation supports:

    • GDPR: Encryption of personal data at rest
    • PCI DSS: Secure storage of authentication credentials
    • SOC 2: Encryption controls for sensitive data

    Future Enhancements

    Potential improvements:

    1. Key Rotation: Implement automated key rotation support
    2. Tenant Isolation: Use HKDF-derived per-tenant keys (currently uses shared key)
    3. Hardware Security Modules (HSM): Support for HSM-backed encryption keys
    4. Audit Logging: Enhanced audit trail for token access

    Troubleshooting

    Common Issues

    Issue: CREDENTIALS_ENCRYPTION_KEY not set in production environment

    • Solution: Set the environment variable in your production deployment

    Issue: Tokens appear as gibberish in database queries

    • Expected: Tokens are encrypted. Use the application code to decrypt them.

    Issue: Migration fails with "Failed to encrypt token"

    • Check: Verify the encryption key is set correctly
    • Check: Ensure database connection is stable
    • Action: Re-run the migration (it's idempotent)

    Issue: Performance degradation after enabling encryption

    • Check: Verify key caching is working (check debug logs)
    • Action: Monitor encryption metrics in production

    Related Documentation

    • Encryption Utilities - Core encryption infrastructure
    • Database Middleware - Prisma middleware implementation
    • Migration Scripts - Other data migration scripts

    Questions?

    For questions or issues, please:

    1. Check this documentation
    2. Review the code comments in the implementation files
    3. Contact the security team for compliance-related questions
    On this page
    OverviewImplementation1. Encryption Utilities2. Prisma Middleware3. Migration ScriptSecurity FeaturesEncryption FormatKey DerivationEnvironment VariablesKey ValidationMigration ProcessPrerequisitesMigration StepsRollbackBackward CompatibilityTestingUnit TestsIntegration TestsMonitoringPerformance ConsiderationsPBKDF2 Key CachingDatabase PerformanceComplianceFuture EnhancementsTroubleshootingCommon IssuesRelated DocumentationQuestions?