skills/safety/defense-in-depth/SKILL.md
Use when implementing validation or safety checks. Multi-layer validation approach prevents bugs through redundant safeguards. Makes bugs structurally impossible.
npx skillsauth add liauw-media/codeassist defense-in-depthInstall 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.
Make bugs structurally impossible through multiple independent layers of validation.
Single-layer protection is insufficient. Defense in depth adds multiple independent validation layers so that if one fails, others catch the problem. Different code paths require different validations.
Purpose: Reject bad input at API boundaries
Where: Controllers, API endpoints, function entry points
What to validate:
Example:
// Laravel Controller
public function createUser(Request $request)
{
// Layer 1: Entry point validation
$validated = $request->validate([
'email' => 'required|email|max:255',
'password' => 'required|min:8',
'age' => 'required|integer|min:18',
]);
// Continue with business logic...
}
Purpose: Enforce operational requirements
Where: Service classes, domain logic
What to validate:
Example:
// UserService
public function createUser(array $data): User
{
// Layer 2: Business logic validation
if ($this->userRepository->emailExists($data['email'])) {
throw new ValidationException('Email already registered');
}
if ($data['age'] < 18) {
throw new ValidationException('Must be 18 or older');
}
// Create user...
}
Purpose: Context-specific safety checks
Where: Before operations, database queries, external calls
What to check:
Example:
public function processPayment(Payment $payment): void
{
// Layer 3: Environment guards
if (app()->environment('production') && !config('payment.gateway_enabled')) {
throw new RuntimeException('Payment gateway not configured for production');
}
if ($payment->amount > config('payment.max_amount')) {
throw new RuntimeException('Payment exceeds maximum allowed amount');
}
// Process payment...
}
Purpose: Forensic logging for debugging
Where: Throughout critical paths
What to log:
Example:
public function transferFunds(Account $from, Account $to, float $amount): void
{
// Layer 4: Debug instrumentation
Log::info('Transfer initiated', [
'from_account' => $from->id,
'to_account' => $to->id,
'amount' => $amount,
'from_balance_before' => $from->balance,
'to_balance_before' => $to->balance,
]);
// Perform transfer...
Log::info('Transfer completed', [
'from_balance_after' => $from->balance,
'to_balance_after' => $to->balance,
]);
}
// Layer 1: Entry Point Validation (Controller)
public function register(RegisterRequest $request)
{
// FormRequest handles basic validation:
// - email format
// - password strength
// - required fields
$validated = $request->validated();
$user = $this->userService->register($validated);
return response()->json(['user' => $user], 201);
}
// Layer 2: Business Logic Validation (Service)
public function register(array $data): User
{
// Business rule: Email must be unique
if ($this->userRepository->emailExists($data['email'])) {
throw new DuplicateEmailException('Email already registered');
}
// Business rule: Domain not blacklisted
$domain = substr($data['email'], strpos($data['email'], '@') + 1);
if ($this->isBlacklistedDomain($domain)) {
throw new ValidationException('Email domain not allowed');
}
// Business rule: Age requirement
if (isset($data['birthdate'])) {
$age = Carbon::parse($data['birthdate'])->age;
if ($age < 18) {
throw new ValidationException('Must be 18 or older to register');
}
}
return $this->createUser($data);
}
// Layer 3: Environment Guards (Repository/Model)
protected function createUser(array $data): User
{
// Environment guard: Database connection
if (!DB::connection()->getPdo()) {
throw new DatabaseException('Database connection not available');
}
// Environment guard: Email service available
if (!app('email')->isAvailable()) {
throw new ServiceException('Email service unavailable');
}
// Layer 4: Debug instrumentation
Log::info('Creating user', [
'email' => $data['email'],
'timestamp' => now(),
]);
$user = User::create([
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
Log::info('User created', [
'user_id' => $user->id,
'email' => $user->email,
]);
return $user;
}
// Only entry point validation
public function createUser(Request $request)
{
$validated = $request->validate(['email' => 'required|email']);
// ❌ Problem: Email could be duplicate
// ❌ Problem: Domain could be blacklisted
// ❌ Problem: Database could be down
// ❌ Problem: No logging for debugging
User::create($validated);
}
// Layer 1: Entry validation
$validated = $request->validate(['email' => 'required|email']);
// Layer 2: Business validation
if ($this->emailExists($validated['email'])) {
throw new ValidationException('Duplicate email');
}
// Layer 3: Environment guard
if (!DB::connection()->getPdo()) {
throw new DatabaseException('Database unavailable');
}
// Layer 4: Instrumentation
Log::info('Creating user', ['email' => $validated['email']]);
// ✅ Now protected against multiple failure modes
User::create($validated);
// Layer 1: Format
'email' => 'required|email'
// Layer 2: Business rules
- Unique in database
- Domain not blacklisted
- Not a disposable email service
// Layer 3: Environment
- Email service available
- SMTP configured
// Layer 4: Logging
- Log email (sanitized)
- Log validation results
// Layer 1: Input validation
'amount' => 'required|numeric|min:0.01'
'currency' => 'required|in:USD,EUR,GBP'
// Layer 2: Business rules
- Amount within limits
- Account has sufficient funds
- Payment method valid
// Layer 3: Environment
- Payment gateway available
- SSL certificate valid
- Fraud detection service up
// Layer 4: Logging
- Log all payment attempts
- Log amounts and currencies
- Log success/failure
// Layer 1: Input validation
'file' => 'required|file|max:10240|mimes:jpg,png,pdf'
// Layer 2: Business rules
- User has upload quota remaining
- File name not duplicate
- Content passes virus scan
// Layer 3: Environment
- Disk space available
- Directory writable
- Virus scanner available
// Layer 4: Logging
- Log file details
- Log storage location
- Log processing results
Example from Production:
Before Defense in Depth:
// Only basic validation
public function updateProfile(Request $request, User $user)
{
$data = $request->validate(['bio' => 'string|max:500']);
$user->update($data);
}
// Bug: User could set bio to another user's email, causing privacy leak
// Bug: Bio could contain SQL injection (if used raw elsewhere)
// Bug: No logging meant debugging was impossible
After Defense in Depth:
public function updateProfile(Request $request, User $user)
{
// Layer 1: Input validation
$data = $request->validate([
'bio' => 'string|max:500',
]);
// Layer 2: Business validation
if ($this->containsSensitiveData($data['bio'])) {
throw new ValidationException('Bio contains restricted content');
}
// Layer 3: Environment guard
if (!$user->can('update', $user)) {
throw new UnauthorizedException();
}
// Layer 4: Instrumentation
Log::info('Profile update', [
'user_id' => $user->id,
'old_bio' => $user->bio,
'new_bio' => $data['bio'],
]);
$user->update($data);
Log::info('Profile updated successfully', ['user_id' => $user->id]);
}
// ✅ Protected against multiple attack vectors
// ✅ Logging helps debug issues
Use with:
test-driven-development - Write tests for each layercode-review - Verify all layers presentsystematic-debugging - Logs help identify which layer failedComplements:
database-backup - Another safety layerverification-before-completion - Validate defenses workFor any data processing or critical operation:
// ❌ Only validates at entry
public function createOrder(Request $request)
{
$validated = $request->validate(['product_id' => 'required']);
Order::create($validated);
}
// Missing: Business rules, environment checks, logging
// ❌ Same validation in every layer (violates DRY)
// Layer 1
$request->validate(['email' => 'email']);
// Layer 2
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { ... }
// ✅ Different validations per layer
// Layer 1: Format
// Layer 2: Business rules (uniqueness, blacklist)
// ❌ No instrumentation
public function criticalOperation()
{
// Complex logic
// No logs
}
// ✅ Add logging
Log::info('Critical operation started');
// Complex logic
Log::info('Critical operation completed');
This skill is based on:
Social Proof: Major companies (Google, Amazon, Microsoft) use layered validation.
When implementing validation:
Bottom Line: One layer of validation is not enough. Different layers catch different problems. Implement all four layers to make bugs structurally impossible.
development
Use when decomposing complex work. Dispatch fresh subagent per task, review between tasks. Flow: Load plan → Dispatch task → Review output → Apply feedback → Mark complete → Next task. No skipping reviews, no parallel dispatch.
development
# Server Documentation System Set up a documentation system that tracks changes and maintains server/project documentation with Claude Code hooks. ## When to Use - Setting up a new server or development environment - Need to track configuration changes over time - Want automatic documentation of work sessions - Maintaining changelog for infrastructure ## Directory Structure ``` ~/docs/ # User home directory (cross-platform) ├── changelog.md # Global over
development
Delegate tasks to remote Claude Code agent containers for parallel execution, long-running analysis, or resource-intensive operations.
development
Use when working on multiple features simultaneously. Creates isolated workspaces without branch switching, enabling parallel development.