You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensive validation schemas, implement configurat
Add this skill
npx mdskills install sickn33/deployment-validation-config-validateProvides comprehensive validation code and patterns but lacks clear agent triggers and workflows
1---2name: deployment-validation-config-validate3description: "You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensive validation schemas, implement configurat"4---56# Configuration Validation78You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensive validation schemas, implement configuration testing strategies, and ensure configurations are secure, consistent, and error-free across all environments.910## Use this skill when1112- Working on configuration validation tasks or workflows13- Needing guidance, best practices, or checklists for configuration validation1415## Do not use this skill when1617- The task is unrelated to configuration validation18- You need a different domain or tool outside this scope1920## Context21The user needs to validate configuration files, implement configuration schemas, ensure consistency across environments, and prevent configuration-related errors. Focus on creating robust validation rules, type safety, security checks, and automated validation processes.2223## Requirements24$ARGUMENTS2526## Instructions2728### 1. Configuration Analysis2930Analyze existing configuration structure and identify validation needs:3132```python33import os34import yaml35import json36from pathlib import Path37from typing import Dict, List, Any3839class ConfigurationAnalyzer:40 def analyze_project(self, project_path: str) -> Dict[str, Any]:41 analysis = {42 'config_files': self._find_config_files(project_path),43 'security_issues': self._check_security_issues(project_path),44 'consistency_issues': self._check_consistency(project_path),45 'recommendations': []46 }47 return analysis4849 def _find_config_files(self, project_path: str) -> List[Dict]:50 config_patterns = [51 '**/*.json', '**/*.yaml', '**/*.yml', '**/*.toml',52 '**/*.ini', '**/*.env*', '**/config.js'53 ]5455 config_files = []56 for pattern in config_patterns:57 for file_path in Path(project_path).glob(pattern):58 if not self._should_ignore(file_path):59 config_files.append({60 'path': str(file_path),61 'type': self._detect_config_type(file_path),62 'environment': self._detect_environment(file_path)63 })64 return config_files6566 def _check_security_issues(self, project_path: str) -> List[Dict]:67 issues = []68 secret_patterns = [69 r'(api[_-]?key|apikey)',70 r'(secret|password|passwd)',71 r'(token|auth)',72 r'(aws[_-]?access)'73 ]7475 for config_file in self._find_config_files(project_path):76 content = Path(config_file['path']).read_text()77 for pattern in secret_patterns:78 if re.search(pattern, content, re.IGNORECASE):79 if self._looks_like_real_secret(content, pattern):80 issues.append({81 'file': config_file['path'],82 'type': 'potential_secret',83 'severity': 'high'84 })85 return issues86```8788### 2. Schema Validation8990Implement configuration schema validation with JSON Schema:9192```typescript93import Ajv from 'ajv';94import ajvFormats from 'ajv-formats';95import { JSONSchema7 } from 'json-schema';9697interface ValidationResult {98 valid: boolean;99 errors?: Array<{100 path: string;101 message: string;102 keyword: string;103 }>;104}105106export class ConfigValidator {107 private ajv: Ajv;108109 constructor() {110 this.ajv = new Ajv({111 allErrors: true,112 strict: false,113 coerceTypes: true114 });115 ajvFormats(this.ajv);116 this.addCustomFormats();117 }118119 private addCustomFormats() {120 this.ajv.addFormat('url-https', {121 type: 'string',122 validate: (data: string) => {123 try {124 return new URL(data).protocol === 'https:';125 } catch { return false; }126 }127 });128129 this.ajv.addFormat('port', {130 type: 'number',131 validate: (data: number) => data >= 1 && data <= 65535132 });133134 this.ajv.addFormat('duration', {135 type: 'string',136 validate: /^\d+[smhd]$/137 });138 }139140 validate(configData: any, schemaName: string): ValidationResult {141 const validate = this.ajv.getSchema(schemaName);142 if (!validate) throw new Error(`Schema '${schemaName}' not found`);143144 const valid = validate(configData);145146 if (!valid && validate.errors) {147 return {148 valid: false,149 errors: validate.errors.map(error => ({150 path: error.instancePath || '/',151 message: error.message || 'Validation error',152 keyword: error.keyword153 }))154 };155 }156 return { valid: true };157 }158}159160// Example schema161export const schemas = {162 database: {163 type: 'object',164 properties: {165 host: { type: 'string', format: 'hostname' },166 port: { type: 'integer', format: 'port' },167 database: { type: 'string', minLength: 1 },168 user: { type: 'string', minLength: 1 },169 password: { type: 'string', minLength: 8 },170 ssl: {171 type: 'object',172 properties: {173 enabled: { type: 'boolean' }174 },175 required: ['enabled']176 }177 },178 required: ['host', 'port', 'database', 'user', 'password']179 }180};181```182183### 3. Environment-Specific Validation184185```python186from typing import Dict, List, Any187188class EnvironmentValidator:189 def __init__(self):190 self.environments = ['development', 'staging', 'production']191 self.environment_rules = {192 'development': {193 'allow_debug': True,194 'require_https': False,195 'min_password_length': 8196 },197 'production': {198 'allow_debug': False,199 'require_https': True,200 'min_password_length': 16,201 'require_encryption': True202 }203 }204205 def validate_config(self, config: Dict, environment: str) -> List[Dict]:206 if environment not in self.environment_rules:207 raise ValueError(f"Unknown environment: {environment}")208209 rules = self.environment_rules[environment]210 violations = []211212 if not rules['allow_debug'] and config.get('debug', False):213 violations.append({214 'rule': 'no_debug_in_production',215 'message': 'Debug mode not allowed in production',216 'severity': 'critical'217 })218219 if rules['require_https']:220 urls = self._extract_urls(config)221 for url_path, url in urls:222 if url.startswith('http://') and 'localhost' not in url:223 violations.append({224 'rule': 'require_https',225 'message': f'HTTPS required for {url_path}',226 'severity': 'high'227 })228229 return violations230```231232### 4. Configuration Testing233234```typescript235import { describe, it, expect } from '@jest/globals';236import { ConfigValidator } from './config-validator';237238describe('Configuration Validation', () => {239 let validator: ConfigValidator;240241 beforeEach(() => {242 validator = new ConfigValidator();243 });244245 it('should validate database config', () => {246 const config = {247 host: 'localhost',248 port: 5432,249 database: 'myapp',250 user: 'dbuser',251 password: 'securepass123'252 };253254 const result = validator.validate(config, 'database');255 expect(result.valid).toBe(true);256 });257258 it('should reject invalid port', () => {259 const config = {260 host: 'localhost',261 port: 70000,262 database: 'myapp',263 user: 'dbuser',264 password: 'securepass123'265 };266267 const result = validator.validate(config, 'database');268 expect(result.valid).toBe(false);269 });270});271```272273### 5. Runtime Validation274275```typescript276import { EventEmitter } from 'events';277import * as chokidar from 'chokidar';278279export class RuntimeConfigValidator extends EventEmitter {280 private validator: ConfigValidator;281 private currentConfig: any;282283 async initialize(configPath: string): Promise<void> {284 this.currentConfig = await this.loadAndValidate(configPath);285 this.watchConfig(configPath);286 }287288 private async loadAndValidate(configPath: string): Promise<any> {289 const config = await this.loadConfig(configPath);290291 const validationResult = this.validator.validate(292 config,293 this.detectEnvironment()294 );295296 if (!validationResult.valid) {297 this.emit('validation:error', {298 path: configPath,299 errors: validationResult.errors300 });301302 if (!this.isDevelopment()) {303 throw new Error('Configuration validation failed');304 }305 }306307 return config;308 }309310 private watchConfig(configPath: string): void {311 const watcher = chokidar.watch(configPath, {312 persistent: true,313 ignoreInitial: true314 });315316 watcher.on('change', async () => {317 try {318 const newConfig = await this.loadAndValidate(configPath);319320 if (JSON.stringify(newConfig) !== JSON.stringify(this.currentConfig)) {321 this.emit('config:changed', {322 oldConfig: this.currentConfig,323 newConfig324 });325 this.currentConfig = newConfig;326 }327 } catch (error) {328 this.emit('config:error', { error });329 }330 });331 }332}333```334335### 6. Configuration Migration336337```python338from typing import Dict339from abc import ABC, abstractmethod340import semver341342class ConfigMigration(ABC):343 @property344 @abstractmethod345 def version(self) -> str:346 pass347348 @abstractmethod349 def up(self, config: Dict) -> Dict:350 pass351352 @abstractmethod353 def down(self, config: Dict) -> Dict:354 pass355356class ConfigMigrator:357 def __init__(self):358 self.migrations: List[ConfigMigration] = []359360 def migrate(self, config: Dict, target_version: str) -> Dict:361 current_version = config.get('_version', '0.0.0')362363 if semver.compare(current_version, target_version) == 0:364 return config365366 result = config.copy()367 for migration in self.migrations:368 if (semver.compare(migration.version, current_version) > 0 and369 semver.compare(migration.version, target_version) <= 0):370 result = migration.up(result)371 result['_version'] = migration.version372373 return result374```375376### 7. Secure Configuration377378```typescript379import * as crypto from 'crypto';380381interface EncryptedValue {382 encrypted: true;383 value: string;384 algorithm: string;385 iv: string;386 authTag?: string;387}388389export class SecureConfigManager {390 private encryptionKey: Buffer;391392 constructor(masterKey: string) {393 this.encryptionKey = crypto.pbkdf2Sync(masterKey, 'config-salt', 100000, 32, 'sha256');394 }395396 encrypt(value: any): EncryptedValue {397 const algorithm = 'aes-256-gcm';398 const iv = crypto.randomBytes(16);399 const cipher = crypto.createCipheriv(algorithm, this.encryptionKey, iv);400401 let encrypted = cipher.update(JSON.stringify(value), 'utf8', 'hex');402 encrypted += cipher.final('hex');403404 return {405 encrypted: true,406 value: encrypted,407 algorithm,408 iv: iv.toString('hex'),409 authTag: cipher.getAuthTag().toString('hex')410 };411 }412413 decrypt(encryptedValue: EncryptedValue): any {414 const decipher = crypto.createDecipheriv(415 encryptedValue.algorithm,416 this.encryptionKey,417 Buffer.from(encryptedValue.iv, 'hex')418 );419420 if (encryptedValue.authTag) {421 decipher.setAuthTag(Buffer.from(encryptedValue.authTag, 'hex'));422 }423424 let decrypted = decipher.update(encryptedValue.value, 'hex', 'utf8');425 decrypted += decipher.final('utf8');426427 return JSON.parse(decrypted);428 }429430 async processConfig(config: any): Promise<any> {431 const processed = {};432433 for (const [key, value] of Object.entries(config)) {434 if (this.isEncryptedValue(value)) {435 processed[key] = this.decrypt(value as EncryptedValue);436 } else if (typeof value === 'object' && value !== null) {437 processed[key] = await this.processConfig(value);438 } else {439 processed[key] = value;440 }441 }442443 return processed;444 }445}446```447448### 8. Documentation Generation449450```python451from typing import Dict, List452import yaml453454class ConfigDocGenerator:455 def generate_docs(self, schema: Dict, examples: Dict) -> str:456 docs = ["# Configuration Reference\n"]457458 docs.append("## Configuration Options\n")459 sections = self._generate_sections(schema.get('properties', {}), examples)460 docs.extend(sections)461462 return '\n'.join(docs)463464 def _generate_sections(self, properties: Dict, examples: Dict, level: int = 3) -> List[str]:465 sections = []466467 for prop_name, prop_schema in properties.items():468 sections.append(f"{'#' * level} {prop_name}\n")469470 if 'description' in prop_schema:471 sections.append(f"{prop_schema['description']}\n")472473 sections.append(f"**Type:** `{prop_schema.get('type', 'any')}`\n")474475 if 'default' in prop_schema:476 sections.append(f"**Default:** `{prop_schema['default']}`\n")477478 if prop_name in examples:479 sections.append("**Example:**\n```yaml")480 sections.append(yaml.dump({prop_name: examples[prop_name]}))481 sections.append("```\n")482483 return sections484```485486## Output Format4874881. **Configuration Analysis**: Current configuration assessment4892. **Validation Schemas**: JSON Schema definitions4903. **Environment Rules**: Environment-specific validation4914. **Test Suite**: Configuration tests4925. **Migration Scripts**: Version migrations4936. **Security Report**: Issues and recommendations4947. **Documentation**: Auto-generated reference495496Focus on preventing configuration errors, ensuring consistency, and maintaining security best practices.497
Full transparency — inspect the skill content before installing.