Back to skills
Defense In Depth
Multi-layer validation strategy that makes bugs structurally impossible rather than merely fixed. After finding and fixing a bug's root cause, implement validation at every layer data passes through.
26 stars
0 votes
0 copies
0 views
Added 12/19/2025
toolstypescriptrustnodedebuggingrefactoringapidatabase
Works with
api
Install via CLI
$
openskills install duthaho/claudekitFiles
SKILL.md
# Defense-in-Depth
## Description
Multi-layer validation strategy that makes bugs structurally impossible rather than merely fixed. After finding and fixing a bug's root cause, implement validation at every layer data passes through.
## When to Use
- After fixing any data-related bug
- Protecting critical data paths
- Preventing bug recurrence
- Building robust systems
- When single validation points have failed
---
## Core Concept
**"Validate at EVERY layer data passes through. Make the bug structurally impossible."**
Single validation points can be bypassed:
- Alternative code paths skip validation
- Refactoring accidentally removes checks
- Tests mock away the validation
Multiple layers create redundancy:
- Different layers catch different cases
- If one check fails, another catches it
- Bug becomes impossible, not just unlikely
---
## The Four-Layer Approach
### Layer 1: Entry Point Validation
Reject invalid input at API/system boundaries:
```typescript
// API endpoint - first line of defense
app.post('/orders', (req, res) => {
// Type check
if (typeof req.body.userId !== 'string') {
return res.status(400).json({ error: 'userId must be a string' });
}
// Existence check
if (!req.body.userId) {
return res.status(400).json({ error: 'userId is required' });
}
// Format validation
if (!isValidUUID(req.body.userId)) {
return res.status(400).json({ error: 'userId must be a valid UUID' });
}
// Proceed with valid data
orderService.createOrder(req.body);
});
```
### Layer 2: Business Logic Validation
Ensure data semantically makes sense for the operation:
```typescript
// Service layer - business rules
class OrderService {
async createOrder(data: OrderData) {
// Business validation
const user = await this.userRepo.findById(data.userId);
if (!user) {
throw new BusinessError('User does not exist');
}
if (!user.canPlaceOrders) {
throw new BusinessError('User is not allowed to place orders');
}
if (data.items.length === 0) {
throw new BusinessError('Order must have at least one item');
}
// Proceed with valid business state
return this.orderRepo.create(data);
}
}
```
### Layer 3: Environment Guards
Add context-specific safeguards:
```typescript
// Repository layer - environment guards
class OrderRepository {
async create(order: Order) {
// Test environment guard
if (process.env.NODE_ENV === 'test' && !process.env.ALLOW_DB_WRITES) {
throw new Error('Database writes disabled in test environment');
}
// Production safety guard
if (order.total > 100000 && !order.managerApproval) {
throw new Error('Large orders require manager approval');
}
// Dangerous operation guard
if (order.userId === SYSTEM_USER_ID) {
throw new Error('Cannot create orders for system user');
}
return this.db.insert('orders', order);
}
}
```
### Layer 4: Debug Instrumentation
Capture execution context for forensic analysis:
```typescript
// Logging layer - forensic evidence
class OrderRepository {
async create(order: Order) {
// Log entry for debugging
this.logger.debug('Creating order', {
orderId: order.id,
userId: order.userId,
itemCount: order.items.length,
total: order.total,
timestamp: new Date().toISOString(),
requestId: context.requestId
});
try {
const result = await this.db.insert('orders', order);
this.logger.info('Order created successfully', {
orderId: result.id,
duration: Date.now() - start
});
return result;
} catch (error) {
this.logger.error('Order creation failed', {
orderId: order.id,
error: error.message,
stack: error.stack,
order: JSON.stringify(order)
});
throw error;
}
}
}
```
---
## Why Multiple Layers?
### Single Point Failure
```typescript
// Only one check - easily bypassed
function createOrder(data) {
if (!data.userId) throw new Error('userId required'); // Single check
// ...
}
// Direct repository call bypasses validation
orderRepository.create({ items: [] }); // No userId check!
```
### Multi-Layer Protection
```typescript
// Multiple checks - defense in depth
// Layer 1: API validates
// Layer 2: Service validates
// Layer 3: Repository validates
// Even if one is bypassed, others catch it
orderRepository.create({ items: [] });
// Repository throws: "userId is required"
```
---
## Implementation Strategy
When debugging, use this approach:
### 1. Trace the Data Flow
```markdown
User Input → API → Service → Repository → Database
```
### 2. Identify Checkpoints
```markdown
Where does this data pass through?
- API endpoint (Layer 1)
- Service method (Layer 2)
- Repository method (Layer 3)
- Database constraints (Layer 4)
```
### 3. Add Validation at Each
```markdown
For each checkpoint:
- What could be wrong at this point?
- What validation makes sense here?
- What error message helps debug?
```
### 4. Test Layer Independence
```markdown
Remove each layer one at a time:
- Does the bug still get caught?
- Which layer catches it?
- Is there a gap in coverage?
```
---
## Validation by Layer Type
| Layer | What to Validate | Example |
|-------|------------------|---------|
| Entry Point | Type, format, presence | `userId` is string, not empty |
| Business Logic | Semantic correctness | User exists, can place orders |
| Environment | Context-specific rules | Test mode restrictions |
| Data Access | Integrity constraints | Foreign keys, not null |
---
## Anti-Patterns
### Single Checkpoint Fallacy
```typescript
// BAD: One validation point
if (isValid(data)) {
// Assume valid everywhere else
}
```
### Validation in Tests Only
```typescript
// BAD: Tests validate, production doesn't
beforeEach(() => {
validateTestData(data); // This doesn't help production
});
```
### Trust After First Check
```typescript
// BAD: Validated once, trusted forever
const validatedData = validate(input);
// ... many lines later ...
process(validatedData); // Is it still valid?
```
---
## Checklist
After fixing any bug:
- [ ] Root cause identified
- [ ] Fix applied at source
- [ ] Layer 1 validation added (entry point)
- [ ] Layer 2 validation added (business logic)
- [ ] Layer 3 guards added (environment)
- [ ] Layer 4 logging added (instrumentation)
- [ ] Tested: removing any single layer still catches bug
- [ ] Bug is structurally impossible, not just fixed
---
Attribution
Comments (0)
No comments yet. Be the first to comment!
