or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

environment-loading.mdenvironment-population.mdfile-parsing.mdindex.mdvault-decryption.md
tile.json

vault-decryption.mddocs/

Vault Decryption

Support for encrypted .env.vault files using AES-256-GCM encryption for secure deployments. Enables storing sensitive environment variables in encrypted form while maintaining the same simple dotenv workflow.

Capabilities

Decrypt Function

Decrypts encrypted environment variable ciphertext using AES-256-GCM encryption.

/**
 * Decrypt ciphertext using AES-256-GCM
 * @param encrypted - The encrypted ciphertext string (base64 encoded)
 * @param keyStr - The decryption key string (at least 64 characters)
 * @returns Decrypted plaintext string
 */
function decrypt(encrypted: string, keyStr: string): string;

Usage Examples:

const dotenv = require('dotenv');

// Direct decryption (rarely used directly)
const encrypted = 'A5q7B2C8D9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8V9W0X1Y2Z3A4B5C6D7E8F9G0H1I2J3K4L5M6N7O8P9Q0R1S2T3U4V5W6X7Y8Z9A0B1C2D3E4F5G6H7I8J9K0L1M2N3O4P5Q6R7S8T9U0V1W2X3Y4Z5A6B7C8D9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8V9W0X1Y2Z3A4B5C6D7E8F9G0H1I2J3K4L5M6N7O8P9Q0R1S2T3U4V5W6X7Y8Z9A0B1C2D3E4F5G6H7I8J9K0L1M2N3O4P5Q6R7S8T9U0V1W2X3Y4Z5A6B7C8D9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8V9W0X1Y2Z3A4B5C6D7E8F9G0H1I2J3K4L5M6N7O8P9Q0R1S2T3U4V5W6X7Y8Z9A0B1C2D3E4F5G6H7I8J9K0L1M2N3O4P5Q6R7S8T9U0V1W2X3Y4Z5A6B7C8D9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8V9W0X1Y2Z3A4B5C6D7E8F9G0H1I2J3K4L5M6N7O8P9Q0R1S2T3U4V5W6X7Y8Z9A0B1C2D3E4F5G6H7I8J9K0L1M2';
const key = 'dotenv://:key_1234567890abcdef1234567890abcdef1234567890abcdef12@dotenvx.com/vault/.env.vault?environment=production';

try {
  const decrypted = dotenv.decrypt(encrypted, key);
  console.log('Decrypted content:', decrypted);
  // Output: "DATABASE_URL=postgres://prod-server/db\nAPI_KEY=prod-secret-key"
} catch (error) {
  console.error('Decryption failed:', error.message);
}

Vault Workflow

Automatic Vault Loading

The config() function automatically handles .env.vault files when DOTENV_KEY is present:

const dotenv = require('dotenv');

// Set DOTENV_KEY environment variable
process.env.DOTENV_KEY = 'dotenv://:key_1234567890abcdef@dotenvx.com/vault/.env.vault?environment=production';

// config() automatically detects and decrypts .env.vault
const result = dotenv.config();
console.log('Loaded from vault:', Object.keys(result.parsed));

Environment-Specific Keys

DOTENV_KEY URLs specify which environment to decrypt:

// Development environment
const devKey = 'dotenv://:key_dev123@dotenvx.com/vault/.env.vault?environment=development';

// Production environment  
const prodKey = 'dotenv://:key_prod456@dotenvx.com/vault/.env.vault?environment=production';

// Staging environment
const stagingKey = 'dotenv://:key_stage789@dotenvx.com/vault/.env.vault?environment=staging';

// Load specific environment
dotenv.config({ DOTENV_KEY: prodKey });

Multi-Key Support

Support for comma-separated keys for key rotation:

const dotenv = require('dotenv');

// Multiple keys for rotation support
const multiKey = 'dotenv://:key_old123@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_new456@dotenvx.com/vault/.env.vault?environment=prod';

// Will try each key until successful
dotenv.config({ DOTENV_KEY: multiKey });

Vault File Format

.env.vault Structure

The .env.vault file contains encrypted environment data:

DOTENV_VAULT_DEVELOPMENT="A5q7B2C8D9E0F1G2H3I4J5K6L7M8..."
DOTENV_VAULT_PRODUCTION="X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2..."
DOTENV_VAULT_STAGING="P3Q4R5S6T7U8V9W0X1Y2Z3A4B5C6..."

Key Format

DOTENV_KEY uses URI format with specific components:

dotenv://:key_1234567890abcdef@dotenvx.com/vault/.env.vault?environment=production
│       │ │                   │                 │                    │
│       │ │                   │                 │                    └── Environment name
│       │ │                   │                 └── Vault file path
│       │ │                   └── Host (ignored in decryption)
│       │ └── Decryption key (last 64 characters used)
│       └── Password field (contains the key)
└── Scheme

Error Handling

Common vault-related errors and their handling:

const dotenv = require('dotenv');

try {
  const result = dotenv.config({ DOTENV_KEY: 'invalid-key' });
  if (result.error) {
    handleVaultError(result.error);
  }
} catch (error) {
  handleVaultError(error);
}

function handleVaultError(error) {
  switch (error.code) {
    case 'INVALID_DOTENV_KEY':
      console.error('Invalid DOTENV_KEY format. Must be valid URI format.');
      console.error('Expected: dotenv://:key_xxx@host/vault/.env.vault?environment=env');
      break;
      
    case 'NOT_FOUND_DOTENV_ENVIRONMENT':
      console.error('Environment not found in .env.vault file.');
      console.error('Available environments might be: development, production, staging');
      break;
      
    case 'DECRYPTION_FAILED':
      console.error('Failed to decrypt .env.vault. Check your DOTENV_KEY.');
      break;
      
    case 'MISSING_DATA':
      console.error('Cannot parse .env.vault file - file may be corrupted.');
      break;
      
    default:
      console.error('Vault error:', error.message);
  }
}

Key Validation

Validate DOTENV_KEY format before use:

function validateDotenvKey(key) {
  if (!key || typeof key !== 'string') {
    throw new Error('DOTENV_KEY must be a string');
  }
  
  try {
    const url = new URL(key);
    
    if (url.protocol !== 'dotenv:') {
      throw new Error('DOTENV_KEY must use dotenv:// protocol');
    }
    
    if (!url.password || url.password.length < 64) {
      throw new Error('DOTENV_KEY must contain at least 64-character key');
    }
    
    const environment = url.searchParams.get('environment');
    if (!environment) {
      throw new Error('DOTENV_KEY must specify environment parameter');
    }
    
    return {
      key: url.password,
      environment: environment,
      valid: true
    };
  } catch (error) {
    throw new Error(`Invalid DOTENV_KEY format: ${error.message}`);
  }
}

// Usage
try {
  const keyInfo = validateDotenvKey(process.env.DOTENV_KEY);
  console.log(`Valid key for environment: ${keyInfo.environment}`);
} catch (error) {
  console.error(error.message);
}

Advanced Vault Usage

Custom Vault Processing

Manual vault file processing for advanced workflows:

const dotenv = require('dotenv');
const fs = require('fs');

function processVaultManually(vaultPath, dotenvKey) {
  // Parse vault file
  const vaultContent = fs.readFileSync(vaultPath, 'utf8');
  const vaultData = dotenv.parse(vaultContent);
  
  // Extract key information
  const url = new URL(dotenvKey);
  const key = url.password;
  const environment = url.searchParams.get('environment').toUpperCase();
  
  // Get encrypted data for environment
  const envKey = `DOTENV_VAULT_${environment}`;
  const encrypted = vaultData[envKey];
  
  if (!encrypted) {
    throw new Error(`Environment ${environment} not found in vault`);
  }
  
  // Decrypt and parse
  const decrypted = dotenv.decrypt(encrypted, key);
  return dotenv.parse(decrypted);
}

// Usage
try {
  const config = processVaultManually('.env.vault', process.env.DOTENV_KEY);
  console.log('Manually processed vault:', Object.keys(config));
} catch (error) {
  console.error('Manual vault processing failed:', error.message);
}

Vault Creation Helpers

Utilities for working with vault data (informational - creation requires external tools):

// Note: Actual vault creation requires dotenvx CLI tool
// This is for understanding the data structure

function analyzeVaultFile(vaultPath) {
  const fs = require('fs');
  const dotenv = require('dotenv');
  
  const content = fs.readFileSync(vaultPath, 'utf8');
  const vaultData = dotenv.parse(content);
  
  const environments = Object.keys(vaultData)
    .filter(key => key.startsWith('DOTENV_VAULT_'))
    .map(key => key.replace('DOTENV_VAULT_', '').toLowerCase());
  
  return {
    environments,
    totalSize: content.length,
    encryptedCount: environments.length
  };
}

// Usage
const vaultInfo = analyzeVaultFile('.env.vault');
console.log('Available environments:', vaultInfo.environments);
console.log('Vault file size:', vaultInfo.totalSize, 'bytes');

Security Considerations

Key Management

  • Store DOTENV_KEY securely in your deployment environment
  • Never commit DOTENV_KEY to version control
  • Rotate keys regularly using multi-key support
  • Use different keys for different environments

Vault File Security

  • .env.vault files can be safely committed to version control
  • Encrypted data is secured with AES-256-GCM
  • Each environment uses separate encryption keys
  • Vault files cannot be decrypted without the corresponding DOTENV_KEY