library/skills/deployment-validation-config-validate/SKILL.md
You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensive validation schemas, implement configurat
npx skillsauth add superesty/unified-ag-kit deployment-validation-config-validateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You 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.
The 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.
$ARGUMENTS
Analyze existing configuration structure and identify validation needs:
import os
import yaml
import json
from pathlib import Path
from typing import Dict, List, Any
class ConfigurationAnalyzer:
def analyze_project(self, project_path: str) -> Dict[str, Any]:
analysis = {
'config_files': self._find_config_files(project_path),
'security_issues': self._check_security_issues(project_path),
'consistency_issues': self._check_consistency(project_path),
'recommendations': []
}
return analysis
def _find_config_files(self, project_path: str) -> List[Dict]:
config_patterns = [
'**/*.json', '**/*.yaml', '**/*.yml', '**/*.toml',
'**/*.ini', '**/*.env*', '**/config.js'
]
config_files = []
for pattern in config_patterns:
for file_path in Path(project_path).glob(pattern):
if not self._should_ignore(file_path):
config_files.append({
'path': str(file_path),
'type': self._detect_config_type(file_path),
'environment': self._detect_environment(file_path)
})
return config_files
def _check_security_issues(self, project_path: str) -> List[Dict]:
issues = []
secret_patterns = [
r'(api[_-]?key|apikey)',
r'(secret|password|passwd)',
r'(token|auth)',
r'(aws[_-]?access)'
]
for config_file in self._find_config_files(project_path):
content = Path(config_file['path']).read_text()
for pattern in secret_patterns:
if re.search(pattern, content, re.IGNORECASE):
if self._looks_like_real_secret(content, pattern):
issues.append({
'file': config_file['path'],
'type': 'potential_secret',
'severity': 'high'
})
return issues
Implement configuration schema validation with JSON Schema:
import Ajv from 'ajv';
import ajvFormats from 'ajv-formats';
import { JSONSchema7 } from 'json-schema';
interface ValidationResult {
valid: boolean;
errors?: Array<{
path: string;
message: string;
keyword: string;
}>;
}
export class ConfigValidator {
private ajv: Ajv;
constructor() {
this.ajv = new Ajv({
allErrors: true,
strict: false,
coerceTypes: true
});
ajvFormats(this.ajv);
this.addCustomFormats();
}
private addCustomFormats() {
this.ajv.addFormat('url-https', {
type: 'string',
validate: (data: string) => {
try {
return new URL(data).protocol === 'https:';
} catch { return false; }
}
});
this.ajv.addFormat('port', {
type: 'number',
validate: (data: number) => data >= 1 && data <= 65535
});
this.ajv.addFormat('duration', {
type: 'string',
validate: /^\d+[smhd]$/
});
}
validate(configData: any, schemaName: string): ValidationResult {
const validate = this.ajv.getSchema(schemaName);
if (!validate) throw new Error(`Schema '${schemaName}' not found`);
const valid = validate(configData);
if (!valid && validate.errors) {
return {
valid: false,
errors: validate.errors.map(error => ({
path: error.instancePath || '/',
message: error.message || 'Validation error',
keyword: error.keyword
}))
};
}
return { valid: true };
}
}
// Example schema
export const schemas = {
database: {
type: 'object',
properties: {
host: { type: 'string', format: 'hostname' },
port: { type: 'integer', format: 'port' },
database: { type: 'string', minLength: 1 },
user: { type: 'string', minLength: 1 },
password: { type: 'string', minLength: 8 },
ssl: {
type: 'object',
properties: {
enabled: { type: 'boolean' }
},
required: ['enabled']
}
},
required: ['host', 'port', 'database', 'user', 'password']
}
};
from typing import Dict, List, Any
class EnvironmentValidator:
def __init__(self):
self.environments = ['development', 'staging', 'production']
self.environment_rules = {
'development': {
'allow_debug': True,
'require_https': False,
'min_password_length': 8
},
'production': {
'allow_debug': False,
'require_https': True,
'min_password_length': 16,
'require_encryption': True
}
}
def validate_config(self, config: Dict, environment: str) -> List[Dict]:
if environment not in self.environment_rules:
raise ValueError(f"Unknown environment: {environment}")
rules = self.environment_rules[environment]
violations = []
if not rules['allow_debug'] and config.get('debug', False):
violations.append({
'rule': 'no_debug_in_production',
'message': 'Debug mode not allowed in production',
'severity': 'critical'
})
if rules['require_https']:
urls = self._extract_urls(config)
for url_path, url in urls:
if url.startswith('http://') and 'localhost' not in url:
violations.append({
'rule': 'require_https',
'message': f'HTTPS required for {url_path}',
'severity': 'high'
})
return violations
import { describe, it, expect } from '@jest/globals';
import { ConfigValidator } from './config-validator';
describe('Configuration Validation', () => {
let validator: ConfigValidator;
beforeEach(() => {
validator = new ConfigValidator();
});
it('should validate database config', () => {
const config = {
host: 'localhost',
port: 5432,
database: 'myapp',
user: 'dbuser',
password: 'securepass123'
};
const result = validator.validate(config, 'database');
expect(result.valid).toBe(true);
});
it('should reject invalid port', () => {
const config = {
host: 'localhost',
port: 70000,
database: 'myapp',
user: 'dbuser',
password: 'securepass123'
};
const result = validator.validate(config, 'database');
expect(result.valid).toBe(false);
});
});
import { EventEmitter } from 'events';
import * as chokidar from 'chokidar';
export class RuntimeConfigValidator extends EventEmitter {
private validator: ConfigValidator;
private currentConfig: any;
async initialize(configPath: string): Promise<void> {
this.currentConfig = await this.loadAndValidate(configPath);
this.watchConfig(configPath);
}
private async loadAndValidate(configPath: string): Promise<any> {
const config = await this.loadConfig(configPath);
const validationResult = this.validator.validate(
config,
this.detectEnvironment()
);
if (!validationResult.valid) {
this.emit('validation:error', {
path: configPath,
errors: validationResult.errors
});
if (!this.isDevelopment()) {
throw new Error('Configuration validation failed');
}
}
return config;
}
private watchConfig(configPath: string): void {
const watcher = chokidar.watch(configPath, {
persistent: true,
ignoreInitial: true
});
watcher.on('change', async () => {
try {
const newConfig = await this.loadAndValidate(configPath);
if (JSON.stringify(newConfig) !== JSON.stringify(this.currentConfig)) {
this.emit('config:changed', {
oldConfig: this.currentConfig,
newConfig
});
this.currentConfig = newConfig;
}
} catch (error) {
this.emit('config:error', { error });
}
});
}
}
from typing import Dict
from abc import ABC, abstractmethod
import semver
class ConfigMigration(ABC):
@property
@abstractmethod
def version(self) -> str:
pass
@abstractmethod
def up(self, config: Dict) -> Dict:
pass
@abstractmethod
def down(self, config: Dict) -> Dict:
pass
class ConfigMigrator:
def __init__(self):
self.migrations: List[ConfigMigration] = []
def migrate(self, config: Dict, target_version: str) -> Dict:
current_version = config.get('_version', '0.0.0')
if semver.compare(current_version, target_version) == 0:
return config
result = config.copy()
for migration in self.migrations:
if (semver.compare(migration.version, current_version) > 0 and
semver.compare(migration.version, target_version) <= 0):
result = migration.up(result)
result['_version'] = migration.version
return result
import * as crypto from 'crypto';
interface EncryptedValue {
encrypted: true;
value: string;
algorithm: string;
iv: string;
authTag?: string;
}
export class SecureConfigManager {
private encryptionKey: Buffer;
constructor(masterKey: string) {
this.encryptionKey = crypto.pbkdf2Sync(masterKey, 'config-salt', 100000, 32, 'sha256');
}
encrypt(value: any): EncryptedValue {
const algorithm = 'aes-256-gcm';
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, this.encryptionKey, iv);
let encrypted = cipher.update(JSON.stringify(value), 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
encrypted: true,
value: encrypted,
algorithm,
iv: iv.toString('hex'),
authTag: cipher.getAuthTag().toString('hex')
};
}
decrypt(encryptedValue: EncryptedValue): any {
const decipher = crypto.createDecipheriv(
encryptedValue.algorithm,
this.encryptionKey,
Buffer.from(encryptedValue.iv, 'hex')
);
if (encryptedValue.authTag) {
decipher.setAuthTag(Buffer.from(encryptedValue.authTag, 'hex'));
}
let decrypted = decipher.update(encryptedValue.value, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
async processConfig(config: any): Promise<any> {
const processed = {};
for (const [key, value] of Object.entries(config)) {
if (this.isEncryptedValue(value)) {
processed[key] = this.decrypt(value as EncryptedValue);
} else if (typeof value === 'object' && value !== null) {
processed[key] = await this.processConfig(value);
} else {
processed[key] = value;
}
}
return processed;
}
}
from typing import Dict, List
import yaml
class ConfigDocGenerator:
def generate_docs(self, schema: Dict, examples: Dict) -> str:
docs = ["# Configuration Reference\n"]
docs.append("## Configuration Options\n")
sections = self._generate_sections(schema.get('properties', {}), examples)
docs.extend(sections)
return '\n'.join(docs)
def _generate_sections(self, properties: Dict, examples: Dict, level: int = 3) -> List[str]:
sections = []
for prop_name, prop_schema in properties.items():
sections.append(f"{'#' * level} {prop_name}\n")
if 'description' in prop_schema:
sections.append(f"{prop_schema['description']}\n")
sections.append(f"**Type:** `{prop_schema.get('type', 'any')}`\n")
if 'default' in prop_schema:
sections.append(f"**Default:** `{prop_schema['default']}`\n")
if prop_name in examples:
sections.append("**Example:**\n```yaml")
sections.append(yaml.dump({prop_name: examples[prop_name]}))
sections.append("```\n")
return sections
Focus on preventing configuration errors, ensuring consistency, and maintaining security best practices.
development
Expert in LangGraph - the production-grade framework for building stateful, multi-actor AI applications. Covers graph construction, state management, cycles and branches, persistence with checkpointers, human-in-the-loop patterns, and the ReAct agent pattern. Used in production at LinkedIn, Uber, and 400+ companies. This is LangChain's recommended approach for building agents. Use when: langgraph, langchain agent, stateful agent, agent graph, react agent.
development
Expert in Langfuse - the open-source LLM observability platform. Covers tracing, prompt management, evaluation, datasets, and integration with LangChain, LlamaIndex, and OpenAI. Essential for debugging, monitoring, and improving LLM applications in production. Use when: langfuse, llm observability, llm tracing, prompt management, llm evaluation.
tools
Design LLM applications using the LangChain framework with agents, memory, and tool integration patterns. Use when building LangChain applications, implementing AI agents, or creating complex LLM workflows.
development
Expert Kubernetes architect specializing in cloud-native infrastructure, advanced GitOps workflows (ArgoCD/Flux), and enterprise container orchestration. Masters EKS/AKS/GKE, service mesh (Istio/Linkerd), progressive delivery, multi-tenancy, and platform engineering. Handles security, observability, cost optimization, and developer experience. Use PROACTIVELY for K8s architecture, GitOps implementation, or cloud-native platform design.