ClaudeForge environment configuration and secrets management with Vault, AWS Secrets Manager, and validation.
/plugin marketplace add claudeforge/marketplace/plugin install env-config-manager@claudeforge-marketplaceClaudeForge intelligent environment configuration and secrets management system that securely handles environment variables, manages secrets across multiple environments, and ensures configuration validation with enterprise-grade security practices.
Transform configuration management from scattered environment files to centralized, secure, and validated configuration systems that prevent security vulnerabilities, simplify deployment, and maintain consistency across all environments.
/env-config-manager [action] [options]
Target: $ARGUMENTS (if specified, otherwise analyze current scope)
Initialize Environment:
/env-config-manager init --template=node --environments=dev,staging,prod
Creates environment configuration structure with:
Validate Configuration:
/env-config-manager validate --env=production --strict=true
Validates environment configuration including:
Generate Types:
/env-config-manager generate-types --output=./types/env.d.ts
Generates TypeScript type definitions with:
HashiCorp Vault Integration:
/env-config-manager vault --action=sync --path=secret/myapp --env=production
Manages secrets with Vault including:
AWS Secrets Manager:
/env-config-manager aws-secrets --region=us-east-1 --sync=true
Integrates with AWS Secrets Manager:
Azure Key Vault:
/env-config-manager azure-keyvault --vault=myapp-vault --managed-identity=true
Manages Azure Key Vault secrets with:
Multi-Environment Strategy:
/env-config-manager multi-env --strategy=hierarchical --base=.env.base
Implements environment hierarchy with:
Configuration Schema:
/env-config-manager schema --format=json-schema --output=./config.schema.json
Creates configuration schemas with:
Secret Encryption:
/env-config-manager encrypt --method=age --public-key=./key.pub
Encrypts configuration files with:
Secret Detection:
/env-config-manager detect-secrets --scan=./src --prevent-commit=true
Scans for accidentally committed secrets:
Access Control:
/env-config-manager access-control --role=developer --env=production
Manages configuration access with:
Secret Rotation:
/env-config-manager rotate --secrets=DB_PASSWORD,API_KEY --schedule=30d
Automates secret rotation including:
// config/env.js
const dotenv = require('dotenv');
const path = require('path');
const Joi = require('joi');
// Load environment-specific configuration
const envFile = `.env.${process.env.NODE_ENV || 'development'}`;
dotenv.config({ path: path.resolve(__dirname, '../', envFile) });
dotenv.config({ path: path.resolve(__dirname, '../', '.env.local') });
dotenv.config({ path: path.resolve(__dirname, '../', '.env') });
// Configuration schema
const envSchema = Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'staging', 'production', 'test')
.default('development'),
PORT: Joi.number()
.integer()
.min(1024)
.max(65535)
.default(3000)
.description('Server port number'),
DATABASE_URL: Joi.string()
.uri({ scheme: ['postgres', 'postgresql'] })
.required()
.description('PostgreSQL connection string'),
REDIS_URL: Joi.string()
.uri({ scheme: ['redis', 'rediss'] })
.required()
.description('Redis connection string'),
JWT_SECRET: Joi.string()
.min(32)
.required()
.description('JWT signing secret (min 32 characters)'),
JWT_EXPIRES_IN: Joi.string()
.pattern(/^\d+[dhms]$/)
.default('7d')
.description('JWT expiration time'),
AWS_REGION: Joi.string()
.when('NODE_ENV', {
is: 'production',
then: Joi.required(),
otherwise: Joi.optional()
})
.description('AWS region for services'),
AWS_ACCESS_KEY_ID: Joi.string()
.when('NODE_ENV', {
is: 'production',
then: Joi.required(),
otherwise: Joi.optional()
}),
AWS_SECRET_ACCESS_KEY: Joi.string()
.when('NODE_ENV', {
is: 'production',
then: Joi.required(),
otherwise: Joi.optional()
}),
STRIPE_API_KEY: Joi.string()
.pattern(/^sk_(test|live)_[a-zA-Z0-9]+$/)
.required()
.description('Stripe API key'),
SENDGRID_API_KEY: Joi.string()
.pattern(/^SG\.[a-zA-Z0-9_-]+$/)
.required()
.description('SendGrid API key'),
API_RATE_LIMIT: Joi.number()
.integer()
.min(10)
.max(10000)
.default(100)
.description('API rate limit per minute'),
LOG_LEVEL: Joi.string()
.valid('error', 'warn', 'info', 'http', 'debug')
.default('info')
.description('Logging level'),
CORS_ORIGIN: Joi.alternatives()
.try(
Joi.string().uri(),
Joi.string().valid('*'),
Joi.array().items(Joi.string().uri())
)
.default('*')
.description('CORS allowed origins')
}).unknown(false);
// Validate environment variables
const { error, value: config } = envSchema.validate(process.env, {
abortEarly: false,
stripUnknown: true
});
if (error) {
const errors = error.details.map(detail => detail.message).join('\n');
throw new Error(`Environment validation failed:\n${errors}`);
}
// Export validated configuration
module.exports = {
env: config.NODE_ENV,
port: config.PORT,
database: {
url: config.DATABASE_URL
},
redis: {
url: config.REDIS_URL
},
jwt: {
secret: config.JWT_SECRET,
expiresIn: config.JWT_EXPIRES_IN
},
aws: {
region: config.AWS_REGION,
accessKeyId: config.AWS_ACCESS_KEY_ID,
secretAccessKey: config.AWS_SECRET_ACCESS_KEY
},
stripe: {
apiKey: config.STRIPE_API_KEY
},
sendgrid: {
apiKey: config.SENDGRID_API_KEY
},
api: {
rateLimit: config.API_RATE_LIMIT
},
logging: {
level: config.LOG_LEVEL
},
cors: {
origin: config.CORS_ORIGIN
}
};
// types/env.d.ts
declare global {
namespace NodeJS {
interface ProcessEnv {
/** Application environment */
NODE_ENV: 'development' | 'staging' | 'production' | 'test';
/** Server port number (1024-65535) */
PORT: string;
/** PostgreSQL connection string */
DATABASE_URL: string;
/** Redis connection string */
REDIS_URL: string;
/** JWT signing secret (minimum 32 characters) */
JWT_SECRET: string;
/** JWT expiration time (e.g., "7d", "24h") */
JWT_EXPIRES_IN?: string;
/** AWS region for services (required in production) */
AWS_REGION?: string;
/** AWS access key ID (required in production) */
AWS_ACCESS_KEY_ID?: string;
/** AWS secret access key (required in production) */
AWS_SECRET_ACCESS_KEY?: string;
/** Stripe API key (sk_test_* or sk_live_*) */
STRIPE_API_KEY: string;
/** SendGrid API key (SG.*) */
SENDGRID_API_KEY: string;
/** API rate limit per minute (10-10000) */
API_RATE_LIMIT?: string;
/** Logging level */
LOG_LEVEL?: 'error' | 'warn' | 'info' | 'http' | 'debug';
/** CORS allowed origins */
CORS_ORIGIN?: string;
}
}
}
export {};
package config
import (
"context"
"fmt"
"log"
"os"
"time"
vault "github.com/hashicorp/vault/api"
)
type VaultConfig struct {
client *vault.Client
mountPath string
secretPath string
}
func NewVaultConfig() (*VaultConfig, error) {
config := vault.DefaultConfig()
config.Address = os.Getenv("VAULT_ADDR")
client, err := vault.NewClient(config)
if err != nil {
return nil, fmt.Errorf("failed to create vault client: %w", err)
}
// Authenticate using token
token := os.Getenv("VAULT_TOKEN")
if token != "" {
client.SetToken(token)
} else {
// Authenticate using AppRole
if err := authenticateAppRole(client); err != nil {
return nil, fmt.Errorf("vault authentication failed: %w", err)
}
}
return &VaultConfig{
client: client,
mountPath: "secret",
secretPath: "myapp",
}, nil
}
func authenticateAppRole(client *vault.Client) error {
roleID := os.Getenv("VAULT_ROLE_ID")
secretID := os.Getenv("VAULT_SECRET_ID")
data := map[string]interface{}{
"role_id": roleID,
"secret_id": secretID,
}
resp, err := client.Logical().Write("auth/approle/login", data)
if err != nil {
return err
}
client.SetToken(resp.Auth.ClientToken)
// Start token renewal goroutine
go renewToken(client, resp.Auth.LeaseDuration)
return nil
}
func renewToken(client *vault.Client, leaseDuration int) {
ticker := time.NewTicker(time.Duration(leaseDuration/2) * time.Second)
defer ticker.Stop()
for range ticker.C {
secret, err := client.Auth().Token().RenewSelf(leaseDuration)
if err != nil {
log.Printf("Failed to renew token: %v", err)
continue
}
log.Printf("Token renewed, new TTL: %d seconds", secret.Auth.LeaseDuration)
}
}
func (vc *VaultConfig) GetSecret(key string) (string, error) {
path := fmt.Sprintf("%s/data/%s", vc.mountPath, vc.secretPath)
secret, err := vc.client.Logical().Read(path)
if err != nil {
return "", fmt.Errorf("failed to read secret: %w", err)
}
if secret == nil || secret.Data == nil {
return "", fmt.Errorf("secret not found")
}
// KV v2 stores data under "data" key
data, ok := secret.Data["data"].(map[string]interface{})
if !ok {
return "", fmt.Errorf("invalid secret format")
}
value, ok := data[key].(string)
if !ok {
return "", fmt.Errorf("secret key not found: %s", key)
}
return value, nil
}
func (vc *VaultConfig) SetSecret(key, value string) error {
path := fmt.Sprintf("%s/data/%s", vc.mountPath, vc.secretPath)
// First, read existing secrets to preserve them
existing, err := vc.client.Logical().Read(path)
if err != nil {
return fmt.Errorf("failed to read existing secrets: %w", err)
}
data := make(map[string]interface{})
if existing != nil && existing.Data != nil {
if existingData, ok := existing.Data["data"].(map[string]interface{}); ok {
data = existingData
}
}
// Update with new value
data[key] = value
// Write back to vault
payload := map[string]interface{}{
"data": data,
}
_, err = vc.client.Logical().Write(path, payload)
if err != nil {
return fmt.Errorf("failed to write secret: %w", err)
}
return nil
}
func (vc *VaultConfig) RotateSecret(ctx context.Context, key string, generator func() (string, error)) error {
// Generate new secret value
newValue, err := generator()
if err != nil {
return fmt.Errorf("failed to generate new secret: %w", err)
}
// Store new secret
if err := vc.SetSecret(key, newValue); err != nil {
return fmt.Errorf("failed to store new secret: %w", err)
}
log.Printf("Secret %s rotated successfully", key)
return nil
}
// Example usage
func LoadConfig() (*AppConfig, error) {
vaultConfig, err := NewVaultConfig()
if err != nil {
return nil, err
}
dbPassword, err := vaultConfig.GetSecret("DB_PASSWORD")
if err != nil {
return nil, err
}
apiKey, err := vaultConfig.GetSecret("API_KEY")
if err != nil {
return nil, err
}
return &AppConfig{
DatabasePassword: dbPassword,
APIKey: apiKey,
}, nil
}
ClaudeForge Environment Config Manager - Enterprise-grade configuration and secrets management with comprehensive validation, multi-platform integration, and security-first architecture for modern applications.