New to Claude Skills? Learn how to install them →

Csickn33 on GitHub

Configuration Validation

Free

Ensure your application configurations are correct and secure.

Get this skill

Free · Opens the source repo

What Configuration Validation does

Configuration Validation is a specialized skill designed for developers and system administrators focused on maintaining the integrity and security of application configurations. This skill provides tools for analyzing existing configuration files, identifying potential security issues, and implementing robust validation schemas. By leveraging this skill, users can create comprehensive validation rules that ensure configurations are consistent and error-free across different environments.

The skill includes features for configuration analysis, where users can scan their project directories for various configuration file types, such as JSON, YAML, and INI. It checks for security vulnerabilities, like exposed API keys or passwords, helping to mitigate risks associated with configuration errors. With the ability to implement JSON Schema validation, users can ensure that their configurations adhere to predefined standards, thus enhancing reliability and maintainability.

Additionally, the skill supports environment-specific validation, allowing users to apply different rules based on the environment (development, staging, production). This ensures that configurations are not only valid but also tailored to the specific requirements of each environment, such as enforcing stricter security measures in production. Overall, Configuration Validation is an essential tool for anyone involved in configuration management, providing the necessary checks and balances to maintain application stability and security.

When to use it

Use this skill when you need to validate configuration files, implement validation schemas, or ensure consistency across different environments.

When not to use it

This skill is not suitable for tasks unrelated to configuration validation or for domains outside of configuration management.

What you can build with it

Validating Configuration Files

Use this skill to analyze and validate configuration files in your project, ensuring they meet defined standards and security requirements.

Implementing Validation Schemas

Leverage the skill to create and apply JSON Schema validation rules, ensuring your configurations are structured correctly.

Checking Environment-Specific Settings

Utilize the skill to validate configurations based on the environment, applying different rules for development and production settings.

How to install Configuration Validation

View source

1. Install with the skills CLI

npx skills add sickn33/agentic-awesome-skills/deployment-validation-config-validate --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by sickn33

Configuration Validation

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.

Use this skill when

  • Working on configuration validation tasks or workflows
  • Needing guidance, best practices, or checklists for configuration validation

Do not use this skill when

  • The task is unrelated to configuration validation
  • You need a different domain or tool outside this scope

Context

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.

Requirements

$ARGUMENTS

Instructions

1. Configuration Analysis

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

2. Schema Validation

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']
  }
};

3. Environment-Specific Validation

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

4. Configuration Testing

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);
  });
});

5. Runtime Validation

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 });
      }
    });
  }
}

6. Configuration Migration

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

7. Secure Configuration

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;
  }
}

8. Documentation Generation

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

Output Format

  1. Configuration Analysis: Current configuration assessment
  2. Validation Schemas: JSON Schema definitions
  3. Environment Rules: Environment-specific validation
  4. Test Suite: Configuration tests
  5. Migration Scripts: Version migrations
  6. Security Report: Issues and recommendations
  7. Documentation: Auto-generated reference

Focus on preventing configuration errors, ensuring consistency, and maintaining security best practices.

Limitations

  • Use this skill only when the task clearly matches the scope described above.
  • Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
  • Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.

Frequently asked questions about Configuration Validation

Similar skills