/

Multi-Environment Setup

Environment isolation

ByteHide Secrets allows you to store different values for the same secret key across multiple environments. This ensures proper isolation between development, staging, and production configurations.

Understanding Environments

Environments allow you to manage separate sets of secrets for different stages of your application lifecycle:

  • Development: Used during local development
  • Staging: For testing before production deployment
  • Production: For your live application
  • Custom environments: Create any custom environment you need

The key benefit is that your code can use the same secret key across all environments, but retrieve different values depending on the context.

Creating Environments

Environments are created in the ByteHide cloud panel:

  1. Navigate to your project in the ByteHide Dashboard
  2. Go to the Settings tab
  3. In the Environments section, click Add
  4. Enter a name for your environment (e.g., "staging")
  5. Optionally connect a repository to this environment
  6. Click Save

Environment Management

Setting Environment-Specific Secrets

Once you've created environments, you can set environment-specific values for each secret key:

  1. Go to the Keys tab in your project
  2. Click Create secret to add a new secret
  3. Enter a key name (e.g., "DATABASE_URL")
  4. Add values for each environment:
    • Development: mongodb://localhost:27017/myapp
    • Staging: mongodb://staging-db:27017/myapp
    • Production: mongodb://prod-db:27017/myapp
  5. Click Save

Multi-Environment Secret

Accessing Environment-Specific Secrets

Set Environment at Initialization

The most common approach is to set the environment when initializing the SDK:

// Set environment via environment variable
// BYTEHIDE_SECRETS_ENVIRONMENT=production
// (No explicit initialization needed if environment variables are set)

// Or directly for testing/development
SecretsManager.unsecureInitialize("your-token", "production");

// Now all secret requests will use "production" environment
const dbUrl = await SecretsManager.get("DATABASE_URL"); // Gets production value

Environment Configuration in Different Scenarios

Local Development

# .env file or environment variables
BYTEHIDE_SECRETS_TOKEN=your-token
BYTEHIDE_SECRETS_ENVIRONMENT=development

Server Deployment

Configure environment variables in your hosting platform:

  • Azure App Service: Application Settings
  • AWS Lambda: Environment Variables
  • Docker: Environment flags
  • Kubernetes: ConfigMaps or Secrets

Node.js Express Example

// app.js
import express from 'express';
import { SecretsManager } from '@bytehide/secrets';

const app = express();
const port = process.env.PORT || 3000;

// Environment is determined by BYTEHIDE_SECRETS_ENVIRONMENT var
async function startServer() {
  try {
    // Get database connection for current environment
    const dbUrl = await SecretsManager.get("DATABASE_URL");
    
    // Connect to database
    await connectToDb(dbUrl);
    
    app.listen(port, () => {
      console.log(`Server running on port ${port} in ${process.env.BYTEHIDE_SECRETS_ENVIRONMENT} environment`);
    });
  } catch (error) {
    console.error("Failed to start server:", error);
    process.exit(1);
  }
}

startServer();

Front-End Applications

For front-end applications, environment variables are injected at build time:

Webpack Environment Setup

// webpack.config.js
const webpack = require('webpack');
const env = process.env.NODE_ENV || 'development';

module.exports = {
  // ...
  plugins: [
    new webpack.DefinePlugin({
      'window.env': JSON.stringify({
        BYTEHIDE_SECRETS_ENVIRONMENT: env,
        BYTEHIDE_SECRETS_TOKEN: process.env.BYTEHIDE_SECRETS_TOKEN
      })
    })
  ]
};

Vite Environment Setup

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  define: {
    'window.env': {
      BYTEHIDE_SECRETS_ENVIRONMENT: process.env.NODE_ENV || 'development',
      BYTEHIDE_SECRETS_TOKEN: process.env.BYTEHIDE_SECRETS_TOKEN
    }
  }
});

CI/CD Pipeline

In your CI/CD workflows, set the appropriate environment:

# GitHub Actions example
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      # ...
      - name: Set ByteHide Environment
        run: |
          # For staging branch
          if [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then
            echo "BYTEHIDE_SECRETS_ENVIRONMENT=staging" >> $GITHUB_ENV
          # For main branch
          elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
            echo "BYTEHIDE_SECRETS_ENVIRONMENT=production" >> $GITHUB_ENV
          else
            echo "BYTEHIDE_SECRETS_ENVIRONMENT=development" >> $GITHUB_ENV
          fi

Best Practices

Environment Naming Convention

Use consistent environment names across your organization:

  • development (or dev)
  • testing (or test)
  • staging (or stg)
  • production (or prod)

Value Consistency

Maintain the same key structure across environments with different values:

API_KEY:
  - development: "sk_test_123"
  - staging: "sk_test_456"
  - production: "sk_live_789"

Environment Validation

Validate that the environment exists:

async function validateEnvironment(environment) {
  try {
    // Try to get any secret with this environment
    // This will throw an error if the environment doesn't exist
    await SecretsManager.get("API_KEY");
    return true;
  } catch (error) {
    if (error.message.includes("environment not found")) {
      throw new Error(`ByteHide environment '${environment}' does not exist`);
    }
    // Other error
    throw error;
  }
}

Environment-Specific Logic

Sometimes you need to execute different code based on the environment:

import { SecretsManager } from '@bytehide/secrets';

function getApiBaseUrl() {
  switch (process.env.BYTEHIDE_SECRETS_ENVIRONMENT) {
    case 'production':
      return 'https://api.example.com';
    case 'staging':
      return 'https://staging-api.example.com';
    default:
      return 'http://localhost:3000';
  }
}

async function getFullConfig() {
  const apiKey = await SecretsManager.get("API_KEY");
  return {
    apiKey,
    baseUrl: getApiBaseUrl(),
    timeout: process.env.BYTEHIDE_SECRETS_ENVIRONMENT === 'production' ? 5000 : 30000
  };
}

Next Steps

Previous
Access Secrets