Project 36: Enterprise Config - Team-Wide Standards

Project 36: Enterprise Config - Team-Wide Standards

Comprehensive Learning Guide Build policy-based configuration systems that enforce coding standards, security policies, and compliance requirements across Claude Code installations


Table of Contents

  1. Learning Objectives
  2. Deep Theoretical Foundation
  3. Complete Project Specification
  4. Real World Outcome
  5. Solution Architecture
  6. Phased Implementation Guide
  7. Testing Strategy
  8. Common Pitfalls & Debugging
  9. Extensions & Challenges
  10. Resources
  11. Self-Assessment Checklist

Learning Objectives

By completing this project, you will master:

  • Enterprise Configuration Architecture: Understand how to layer policies over user configurations while maintaining usability and allowing appropriate exceptions.

  • Policy-as-Code Patterns: Learn to express organizational policies as machine-readable, versionable, and testable code using patterns from Open Policy Agent (OPA).

  • Configuration Distribution: Implement mechanisms to distribute policies to developer machines via MDM, git, APIs, or custom sync services.

  • Audit Logging: Build comprehensive audit trails that capture Claude Code actions for compliance reporting (SOC 2, HIPAA, etc.).

  • Exception Management: Design systems that allow controlled policy bypasses for legitimate use cases while maintaining security.

  • Developer Experience: Balance security requirements with developer productivity to avoid frustrating users while maintaining guardrails.


Deep Theoretical Foundation

Enterprise Configuration Hierarchy

Enterprise configuration adds a governance layer on top of Claude Code’s existing configuration system:

Enterprise Configuration Precedence:
====================================

ENTERPRISE POLICY (Highest - Cannot Override)
        |
        v
+-----------------------------------------------+
| Organization-Wide Rules                        |
| - Approved MCP servers only                   |
| - No external API access                      |
| - Mandatory audit logging                     |
| - Required skills (code-review)               |
+-----------------------------------------------+
        |
        v
PROJECT CONFIG (Team/Repository Level)
        |
        v
+-----------------------------------------------+
| Project-Specific Settings                      |
| - CLAUDE.md instructions                      |
| - Project hooks and skills                    |
| - (Constrained by enterprise policy)          |
+-----------------------------------------------+
        |
        v
USER CONFIG (Individual Developer)
        |
        v
+-----------------------------------------------+
| Personal Preferences                           |
| - Output style preferences                    |
| - Personal hooks                              |
| - (Constrained by enterprise + project)       |
+-----------------------------------------------+
        |
        v
DEFAULTS (Built-in Fallbacks)


Configuration Merge Strategy:
============================

For each setting:
1. Check if enterprise policy LOCKS the value -> Use policy value
2. Check if enterprise policy RESTRICTS options -> Validate against policy
3. Check if project config sets value -> Use project value
4. Check if user config sets value -> Use user value
5. Use default value

Example:
--------
Enterprise Policy: mcpServers RESTRICTED to ["github", "jira", "internal-docs"]
Project Config: mcpServers = ["github", "internal-docs"]
User Config: mcpServers = ["github", "slack"]  // slack not approved!

Result: mcpServers = ["github", "internal-docs"]
        (User's "slack" rejected - not in enterprise allowlist)
        (User notified of policy violation)

Reference: “Enterprise Integration Patterns” by Hohpe & Woolf, Chapter 7 discusses configuration distribution patterns.


Policy-as-Code Concepts

Expressing policies as code enables version control, testing, and automated enforcement:

Policy Components:
=================

1. POLICY DEFINITION
   - What is being controlled?
   - What are the allowed values/actions?
   - What happens on violation?

2. POLICY EVALUATION
   - When is the policy checked?
   - What context is available?
   - How is the decision made?

3. POLICY ENFORCEMENT
   - Block action? Allow with warning?
   - Audit log only?
   - Require approval?


Policy Types:
=============

ALLOWLIST (Whitelist)
---------------------
Only explicitly permitted items are allowed.

policy:
  name: approved-mcp-servers
  type: allowlist
  target: mcpServers
  values: [github, jira, internal-docs]

Evaluation: mcpServer IN allowlist? -> ALLOW : DENY


DENYLIST (Blacklist)
--------------------
Everything allowed except explicitly denied items.

policy:
  name: blocked-tools
  type: denylist
  target: tools
  values: [Bash, Write]  # Block dangerous tools

Evaluation: tool IN denylist? -> DENY : ALLOW


PATTERN MATCH
-------------
Content matching regular expressions.

policy:
  name: no-secrets-in-config
  type: pattern-deny
  target: claudeMd
  pattern: "(sk-|api[-_]?key|password|secret)"

Evaluation: content MATCHES pattern? -> DENY : ALLOW


REQUIRE
-------
Certain items must be present.

policy:
  name: require-code-review
  type: require
  target: skills
  values: [code-review]

Evaluation: required SUBSET OF current? -> ALLOW : WARN


LIMIT
-----
Numeric constraints.

policy:
  name: max-tokens-per-session
  type: limit
  target: sessionTokens
  max: 100000

Evaluation: value <= max? -> ALLOW : DENY

Reference: Open Policy Agent (OPA) documentation at openpolicyagent.org


Audit Logging for Compliance

Enterprise environments require detailed audit trails for compliance frameworks:

Audit Log Architecture:
======================

+-------------------+     +-------------------+     +-------------------+
|  Claude Code      |     |  Local Log        |     |  Central Audit    |
|  Instance         |     |  Buffer           |     |  Service          |
|-------------------|     |-------------------|     |-------------------|
| Events:           |---->| Batch collection  |---->| Storage:          |
| - Tool executions |     | Encryption        |     | - S3/GCS          |
| - File changes    |     | Retry queue       |     | - SIEM            |
| - MCP calls       |     |                   |     | - Splunk          |
+-------------------+     +-------------------+     +-------------------+


Audit Event Schema:
==================

{
  "version": "1.0",
  "timestamp": "2024-12-22T14:30:00.000Z",
  "eventId": "evt_a1b2c3d4e5f6",

  // Identity
  "user": {
    "id": "user_123",
    "email": "developer@company.com",
    "department": "engineering"
  },

  // Machine
  "machine": {
    "id": "machine_abc123",
    "hostname": "developer-laptop",
    "os": "macOS 14.0"
  },

  // Session
  "session": {
    "id": "sess_xyz789",
    "startTime": "2024-12-22T14:00:00.000Z",
    "projectPath": "/Users/dev/project"
  },

  // Action
  "action": {
    "type": "tool_execution",
    "tool": "Write",
    "params": {
      "path": "/src/config.py",
      "contentHash": "sha256:abc123..."  // Don't log actual content
    },
    "result": "success",
    "duration": 234
  },

  // Policy
  "policyCheck": {
    "policies": ["file-access", "approved-paths"],
    "result": "passed",
    "violations": []
  },

  // Context
  "context": {
    "prompt": "[REDACTED]",  // May contain sensitive info
    "tokenCount": 1500
  }
}


Compliance Mappings:
===================

SOC 2 Requirements:
-------------------
- CC6.1: Logical access controls -> Policy enforcement logs
- CC7.2: System change monitoring -> Tool execution logs
- CC8.1: Change management -> File modification tracking

HIPAA Requirements:
-------------------
- Access controls -> User identity in all logs
- Audit controls -> Comprehensive action logging
- Integrity controls -> Hash verification

GDPR Considerations:
-------------------
- Minimize PII in logs
- Support data subject requests
- Define retention periods

Reference: “Security Engineering” by Ross Anderson, Chapter 6 covers audit and monitoring systems.


Exception Management

Not all policy violations should be blocked. A good system allows controlled exceptions:

Exception Hierarchy:
===================

PERMANENT EXCEPTIONS
--------------------
Granted to specific teams/users indefinitely.

exceptions:
  - team: security-team
    exempt_from: [approved-mcp-servers]
    reason: Security testing requires arbitrary access
    approved_by: CISO
    expires: null  # Permanent


TEMPORARY EXCEPTIONS
--------------------
Time-limited bypasses for specific needs.

exceptions:
  - user: alice@company.com
    exempt_from: [file-access-restrictions]
    reason: Emergency production fix
    approved_by: manager@company.com
    expires: 2024-12-23T00:00:00Z  # 24-hour window


PROJECT EXCEPTIONS
------------------
Exceptions scoped to specific repositories.

exceptions:
  - project: legacy-system
    exempt_from: [typescript-required]
    reason: Legacy JavaScript codebase
    approved_by: tech-lead@company.com


Exception Workflow:
==================

Developer                     Admin Portal                   Policy System
---------                     -----------                   -------------

Encounters
violation
    |
    v
Request      ------>      Review request
exception                      |
                              v
                        Approve/Deny
                              |
    <------             If approved:
Notified                Update policy
                        with exception
                              |
                              v
Retry action  ------>    Re-evaluate
                        (exception applies)
                              |
    <------                   v
Action                  Action allowed
succeeds                + audit logged

Complete Project Specification

Functional Requirements

Core Features (Must Have):

Feature Description Priority
Policy definition YAML/JSON policy format P0
Policy enforcement Block/allow based on policies P0
Configuration distribution Deliver policies to machines P0
Audit logging Log all actions with policy results P0
Exception management Allow controlled policy bypasses P0
Policy testing Test policies before deployment P1
Admin dashboard View violations and manage exceptions P1
Compliance reports Generate SOC 2/HIPAA reports P2
Policy versioning Track and rollback policy changes P2

Policy Definition Format:

# enterprise-policy.yaml
version: "1.0"
organization: "Acme Corporation"
effective_date: "2024-12-01"
last_updated: "2024-12-20"

# Policy definitions
policies:
  # Restrict MCP servers to approved list
  - name: approved-mcp-servers
    description: Only allow approved MCP servers
    type: allowlist
    target: mcpServers
    values:
      - github-mcp
      - jira-mcp
      - internal-docs-mcp
    severity: error
    message: "MCP server '{{value}}' is not on the approved list"

  # Prevent secrets in CLAUDE.md
  - name: no-secrets-in-claude-md
    description: Prevent API keys and secrets in configuration
    type: pattern-deny
    target: claudeMd
    pattern: "(sk-[a-zA-Z0-9]{32,}|api[-_]?key\\s*[=:]|password\\s*[=:])"
    severity: error
    message: "Potential secret detected in CLAUDE.md"

  # Require code review skill
  - name: require-code-review
    description: All projects must have code review capability
    type: require
    target: skills
    values:
      - code-review
    severity: warning
    message: "Consider adding the code-review skill"

  # Limit token usage
  - name: max-session-tokens
    description: Limit tokens per session for cost control
    type: limit
    target: sessionTokens
    max: 100000
    severity: warning
    message: "Approaching token limit ({{current}}/{{max}})"

# Audit configuration
audit:
  enabled: true
  destination: https://audit.acme.com/claude-logs
  batch_size: 100
  flush_interval: 60  # seconds
  include_events:
    - tool_execution
    - file_modification
    - mcp_call
    - policy_violation
    - session_start
    - session_end
  exclude_patterns:
    - path: "*.log"
    - path: "node_modules/*"

# Exception definitions
exceptions:
  - team: security-team
    exempt_from:
      - approved-mcp-servers
    reason: Security testing requires arbitrary MCP access
    approved_by: ciso@acme.com

  - user: alice@acme.com
    exempt_from:
      - max-session-tokens
    reason: Large codebase migration project
    expires: "2024-12-31"
    approved_by: manager@acme.com

Real World Outcome

You’ll have an enterprise policy system:

Policy Enforcement in Action:

$ claude

Enterprise Policy Active: Acme Corporation
Policies: 4 active, 1 exception applied (security-team)

You: Can you install this MCP server from npm: random-utils-mcp?

Claude: I'd like to help, but I can't install that MCP server.

+----------------------------------------------------------------+
| POLICY VIOLATION                                                |
+----------------------------------------------------------------+
| Policy: approved-mcp-servers                                    |
| Severity: ERROR                                                 |
|                                                                 |
| The MCP server "random-utils-mcp" is not on the approved list. |
|                                                                 |
| Approved servers:                                               |
| - github-mcp                                                    |
| - jira-mcp                                                      |
| - internal-docs-mcp                                             |
|                                                                 |
| To request an exception:                                        |
| 1. Visit https://admin.acme.com/claude/exceptions              |
| 2. Submit request with business justification                   |
| 3. Wait for security team approval                              |
+----------------------------------------------------------------+

You: Can you write to /etc/hosts?

Claude: I cannot write to that location.

+----------------------------------------------------------------+
| POLICY VIOLATION                                                |
+----------------------------------------------------------------+
| Policy: approved-paths                                          |
| Severity: ERROR                                                 |
|                                                                 |
| Writing to system paths is not permitted.                       |
| Allowed paths: ~/*, /tmp/claude-*                              |
+----------------------------------------------------------------+

You: Let's review the authentication code instead.

Claude: I'll review the authentication code for you.

[Reviews code normally]

+----------------------------------------------------------------+
| ACTION LOGGED                                                   |
+----------------------------------------------------------------+
| Event: tool_execution (Read)                                    |
| Target: src/auth/login.ts                                       |
| Policy check: PASSED                                            |
| Audit ID: evt_abc123                                            |
+----------------------------------------------------------------+

Admin Dashboard View:

+------------------------------------------------------------------+
|              CLAUDE CODE ENTERPRISE DASHBOARD                     |
+------------------------------------------------------------------+
|                                                                   |
| OVERVIEW (Last 24 Hours)                                          |
| =========================                                         |
| Active Users: 127                                                 |
| Total Sessions: 342                                               |
| Policy Violations: 23                                             |
| Exceptions Used: 8                                                |
|                                                                   |
| VIOLATION BREAKDOWN                                               |
| ====================                                              |
| approved-mcp-servers    |########            | 12 (52%)          |
| no-secrets-in-config    |#####               | 6 (26%)           |
| max-session-tokens      |###                 | 4 (17%)           |
| require-code-review     |#                   | 1 (4%)            |
|                                                                   |
| RECENT VIOLATIONS                                                 |
| =================                                                 |
| 14:32 | bob@acme.com    | approved-mcp-servers | random-mcp      |
| 14:28 | alice@acme.com  | no-secrets-in-config | API key found   |
| 14:15 | carol@acme.com  | approved-mcp-servers | custom-mcp      |
|                                                                   |
| PENDING EXCEPTION REQUESTS (3)                                    |
| ==============================                                    |
| [View] | bob@acme.com | random-mcp | Business justification...   |
| [View] | dev-team     | new-tool   | Required for project X...   |
|                                                                   |
+------------------------------------------------------------------+

Solution Architecture

System Architecture Diagram

+------------------------------------------------------------------+
|                    ENTERPRISE CONFIG SYSTEM                       |
+------------------------------------------------------------------+
|                                                                   |
|  +--------------------+                                           |
|  | POLICY SERVER      |                                           |
|  |--------------------|                                           |
|  | - Policy storage   |                                           |
|  | - Version control  |                                           |
|  | - Distribution API |                                           |
|  +--------+-----------+                                           |
|           |                                                       |
|           | Policy sync                                           |
|           v                                                       |
|  +--------------------+     +-------------------+                  |
|  | LOCAL AGENT        |     | CLAUDE CODE       |                  |
|  |--------------------|     |-------------------|                  |
|  | - Policy cache     |<--->| - Hook system     |                  |
|  | - Offline support  |     | - Event emitter   |                  |
|  | - Update checker   |     | - Action executor |                  |
|  +--------+-----------+     +--------+----------+                  |
|           |                          |                            |
|           v                          v                            |
|  +--------------------+     +-------------------+                  |
|  | POLICY ENGINE      |     | AUDIT COLLECTOR   |                  |
|  |--------------------|     |-------------------|                  |
|  | - Evaluation logic |     | - Event buffering |                  |
|  | - Exception check  |     | - Encryption      |                  |
|  | - Decision cache   |     | - Batch upload    |                  |
|  +--------+-----------+     +--------+----------+                  |
|           |                          |                            |
|           v                          v                            |
|  +--------------------+     +-------------------+                  |
|  | ENFORCEMENT HOOKS  |     | AUDIT SERVICE     |                  |
|  |--------------------|     |-------------------|                  |
|  | - PreToolUse       |     | - Log storage     |                  |
|  | - PostToolUse      |     | - Query API       |                  |
|  | - Config validate  |     | - Reports         |                  |
|  +--------------------+     +-------------------+                  |
|                                                                   |
+------------------------------------------------------------------+

Policy Enforcement Flow

Action Request Flow:
===================

User Request                 Policy Check                   Execution
============                 ============                   =========

"Write to file"
      |
      v
+-------------+
| PreToolUse  |
| Hook        |
+------+------+
       |
       v
+-------------+     +-------------+
| Load Active |---->| Policy      |
| Policies    |     | Definitions |
+------+------+     +-------------+
       |
       v
+-------------+     +-------------+
| Check       |---->| Exception   |
| Exceptions  |     | Database    |
+------+------+     +-------------+
       |
       v
+-------------+
| Evaluate    |
| Policies    |
+------+------+
       |
       +------------+-----------+
       |            |           |
       v            v           v
   ALLOWED      WARNING      BLOCKED
       |            |           |
       v            v           v
   Execute      Execute      Return
   action       + warn       error
       |            |           |
       +------------+-----------+
                    |
                    v
            +-------------+
            | Audit Log   |
            | Event       |
            +-------------+
                    |
                    v
            +-------------+
            | Upload to   |
            | Central     |
            +-------------+

Module Breakdown

src/
+-- index.ts                 # Main entry point
|
+-- policy/
|   +-- loader.ts            # Load policies from sources
|   +-- parser.ts            # Parse YAML/JSON policies
|   +-- validator.ts         # Validate policy syntax
|   +-- types.ts             # Policy type definitions
|
+-- engine/
|   +-- evaluator.ts         # Policy evaluation logic
|   +-- matcher.ts           # Pattern matching
|   +-- decision.ts          # Decision making
|   +-- cache.ts             # Decision caching
|
+-- exceptions/
|   +-- manager.ts           # Exception CRUD
|   +-- checker.ts           # Check if exception applies
|   +-- types.ts             # Exception types
|
+-- enforcement/
|   +-- hooks/
|   |   +-- pre-tool.ts      # PreToolUse policy hook
|   |   +-- post-tool.ts     # PostToolUse audit hook
|   |   +-- config-validate.ts # Config validation hook
|   +-- blocker.ts           # Action blocking logic
|   +-- warner.ts            # Warning generation
|
+-- audit/
|   +-- collector.ts         # Event collection
|   +-- buffer.ts            # Batch buffering
|   +-- uploader.ts          # Send to audit service
|   +-- schema.ts            # Event schema
|
+-- sync/
|   +-- client.ts            # Policy server client
|   +-- cache.ts             # Local policy cache
|   +-- updater.ts           # Check for updates
|
+-- admin/
|   +-- server.ts            # Admin API server
|   +-- dashboard.ts         # Dashboard routes
|   +-- reports.ts           # Report generation
|
+-- types/
    +-- policy.ts            # Policy types
    +-- event.ts             # Audit event types
    +-- config.ts            # Configuration types

Phased Implementation Guide

Phase 1: Policy Engine Core (Day 1-3)

Goal: Build policy parser and evaluator.

Milestone: Policies load from YAML and evaluate against test inputs.

Tasks:

  1. Project Setup
    mkdir enterprise-config && cd enterprise-config
    npm init -y
    npm install yaml commander chalk winston
    npm install -D typescript @types/node vitest
    npx tsc --init
    
  2. Define Policy Types (src/types/policy.ts)
    export type PolicyType =
      | 'allowlist'
      | 'denylist'
      | 'pattern-deny'
      | 'require'
      | 'limit';
    
    export type PolicySeverity = 'error' | 'warning' | 'info';
    
    export interface Policy {
      name: string;
      description: string;
      type: PolicyType;
      target: string;
      values?: string[];
      pattern?: string;
      max?: number;
      severity: PolicySeverity;
      message: string;
    }
    
    export interface PolicyResult {
      policy: string;
      passed: boolean;
      severity: PolicySeverity;
      message?: string;
      value?: unknown;
    }
    
  3. Create Policy Parser (src/policy/parser.ts)
    import { parse } from 'yaml';
    import { readFileSync } from 'fs';
    import { Policy } from '../types/policy';
    
    export interface EnterprisePolicy {
      version: string;
      organization: string;
      policies: Policy[];
      audit: AuditConfig;
      exceptions: Exception[];
    }
    
    export function parsePolicy(path: string): EnterprisePolicy {
      const content = readFileSync(path, 'utf-8');
      const parsed = parse(content);
      validatePolicy(parsed);
      return parsed as EnterprisePolicy;
    }
    
    function validatePolicy(policy: unknown): void {
      // Validate required fields
      // Validate policy types
      // Validate patterns compile
    }
    
  4. Create Policy Evaluator (src/engine/evaluator.ts)
    import { Policy, PolicyResult } from '../types/policy';
    
    export function evaluatePolicy(
      policy: Policy,
      context: EvaluationContext
    ): PolicyResult {
      switch (policy.type) {
        case 'allowlist':
          return evaluateAllowlist(policy, context);
        case 'denylist':
          return evaluateDenylist(policy, context);
        case 'pattern-deny':
          return evaluatePatternDeny(policy, context);
        case 'require':
          return evaluateRequire(policy, context);
        case 'limit':
          return evaluateLimit(policy, context);
        default:
          throw new Error(`Unknown policy type: ${policy.type}`);
      }
    }
    
    function evaluateAllowlist(policy: Policy, context: EvaluationContext): PolicyResult {
      const value = context.getValue(policy.target);
      const allowed = policy.values || [];
    
      if (Array.isArray(value)) {
        const violations = value.filter(v => !allowed.includes(v));
        return {
          policy: policy.name,
          passed: violations.length === 0,
          severity: policy.severity,
          message: violations.length > 0
            ? policy.message.replace('{{value}}', violations.join(', '))
            : undefined,
          value: violations
        };
      }
    
      const passed = allowed.includes(value as string);
      return {
        policy: policy.name,
        passed,
        severity: policy.severity,
        message: passed ? undefined : policy.message.replace('{{value}}', String(value)),
        value
      };
    }
    
  5. Test Evaluator
    npx tsx src/test-evaluator.ts
    

Success Criteria: Policies correctly evaluate against test inputs.


Phase 2: Enforcement Hooks (Day 4-5)

Goal: Integrate policy engine with Claude Code hooks.

Milestone: PreToolUse hook blocks policy violations.

Tasks:

  1. Create Enforcement Hook (src/enforcement/hooks/pre-tool.ts) ```typescript import { evaluatePolicy } from ‘../../engine/evaluator’; import { loadPolicies } from ‘../../policy/loader’; import { checkExceptions } from ‘../../exceptions/checker’;

    export interface HookEvent { type: ‘PreToolUse’; tool: string; params: Record<string, unknown>; session: SessionContext; }

    export interface HookResult { decision: ‘continue’ | ‘block’; reason?: string; }

    export async function preToolUseHook(event: HookEvent): Promise { const policies = await loadPolicies(); const context = buildContext(event);

    for (const policy of policies) { // Check if user has exception if (await checkExceptions(event.session.user, policy.name)) { continue; }

    const result = evaluatePolicy(policy, context);
    
    if (!result.passed && result.severity === 'error') {
      return {
        decision: 'block',
        reason: formatViolation(result)
      };
    }   }
    

    return { decision: ‘continue’ }; }

    function formatViolation(result: PolicyResult): string { return ` Policy Violation: ${result.policy} Severity: ${result.severity.toUpperCase()}

${result.message}

To request an exception, visit: https://admin.company.com/exceptions `.trim(); }


2. **Create Exception Checker** (`src/exceptions/checker.ts`)
   ```typescript
   export interface Exception {
     user?: string;
     team?: string;
     project?: string;
     exempt_from: string[];
     reason: string;
     expires?: string;
     approved_by: string;
   }

   export async function checkExceptions(
     user: UserContext,
     policyName: string
   ): Promise<boolean> {
     const exceptions = await loadExceptions();

     for (const exception of exceptions) {
       // Check if exception applies to this user
       if (exception.user && exception.user !== user.email) continue;
       if (exception.team && !user.teams.includes(exception.team)) continue;

       // Check if exception covers this policy
       if (!exception.exempt_from.includes(policyName)) continue;

       // Check if exception is expired
       if (exception.expires && new Date(exception.expires) < new Date()) continue;

       return true;
     }

     return false;
   }
  1. Register Hook with Claude Code
    // package.json
    {
      "claude": {
        "hooks": ["./dist/enforcement/hooks/pre-tool.js"]
      }
    }
    
  2. Test Hook Integration
    • Create test policy blocking specific tool
    • Verify hook blocks the action
    • Verify exception bypasses block

Success Criteria: Policy violations blocked by hook.


Phase 3: Audit Logging (Day 6-7)

Goal: Capture and upload audit events.

Milestone: All actions logged with policy check results.

Tasks:

  1. Create Audit Collector (src/audit/collector.ts)
    import { v4 as uuid } from 'uuid';
    
    export interface AuditEvent {
      eventId: string;
      timestamp: string;
      user: UserInfo;
      machine: MachineInfo;
      session: SessionInfo;
      action: ActionInfo;
      policyCheck: PolicyCheckInfo;
    }
    
    class AuditCollector {
      private buffer: AuditEvent[] = [];
      private flushInterval: NodeJS.Timer;
    
      constructor(private config: AuditConfig) {
        this.flushInterval = setInterval(
          () => this.flush(),
          config.flush_interval * 1000
        );
      }
    
      collect(event: Partial<AuditEvent>): void {
        const fullEvent: AuditEvent = {
          eventId: uuid(),
          timestamp: new Date().toISOString(),
          ...this.getContextInfo(),
          ...event
        };
    
        this.buffer.push(fullEvent);
    
        if (this.buffer.length >= this.config.batch_size) {
          this.flush();
        }
      }
    
      private async flush(): Promise<void> {
        if (this.buffer.length === 0) return;
    
        const batch = [...this.buffer];
        this.buffer = [];
    
        try {
          await this.upload(batch);
        } catch (error) {
          // Re-add to buffer for retry
          this.buffer.unshift(...batch);
          console.error('Audit upload failed:', error);
        }
      }
    
      private async upload(events: AuditEvent[]): Promise<void> {
        const encrypted = this.encrypt(events);
        await fetch(this.config.destination, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(encrypted)
        });
      }
    }
    
  2. Create PostToolUse Hook (src/enforcement/hooks/post-tool.ts)
    import { auditCollector } from '../../audit/collector';
    
    export async function postToolUseHook(event: HookEvent): Promise<void> {
      auditCollector.collect({
        action: {
          type: 'tool_execution',
          tool: event.tool,
          params: redactSensitive(event.params),
          result: event.result.status,
          duration: event.result.duration
        },
        policyCheck: {
          policies: event.policiesChecked,
          result: event.policyResult,
          violations: event.violations
        }
      });
    }
    
    function redactSensitive(params: Record<string, unknown>): Record<string, unknown> {
      // Redact file contents, keep paths
      // Hash sensitive values
      // Remove PII
    }
    
  3. Implement Audit Service (optional)
    • Simple HTTP server to receive logs
    • Store in PostgreSQL or S3
    • Basic query API

Success Criteria: Actions logged and queryable.


Phase 4: Admin Dashboard (Day 8-10)

Goal: Build web interface for policy management.

Milestone: Dashboard shows violations and manages exceptions.

Tasks:

  1. Create Admin API (src/admin/server.ts)
    import express from 'express';
    
    const app = express();
    
    // Get dashboard stats
    app.get('/api/stats', async (req, res) => {
      const stats = await getStats();
      res.json(stats);
    });
    
    // List violations
    app.get('/api/violations', async (req, res) => {
      const violations = await getViolations(req.query);
      res.json(violations);
    });
    
    // List exception requests
    app.get('/api/exceptions/requests', async (req, res) => {
      const requests = await getExceptionRequests();
      res.json(requests);
    });
    
    // Approve exception
    app.post('/api/exceptions/:id/approve', async (req, res) => {
      await approveException(req.params.id, req.body.approvedBy);
      res.json({ success: true });
    });
    
    // Generate compliance report
    app.get('/api/reports/:type', async (req, res) => {
      const report = await generateReport(req.params.type);
      res.json(report);
    });
    
  2. Create Dashboard UI
    • Use React or simple HTML/JS
    • Show violation counts and trends
    • List recent violations
    • Manage exception requests
  3. Create Report Generator (src/admin/reports.ts)
    export async function generateSOC2Report(startDate: Date, endDate: Date) {
      const events = await queryAuditLogs(startDate, endDate);
    
      return {
        period: { startDate, endDate },
        accessControls: {
          totalLogins: events.filter(e => e.action.type === 'session_start').length,
          uniqueUsers: new Set(events.map(e => e.user.id)).size,
          policyViolations: events.filter(e => !e.policyCheck.result).length
        },
        changeMonitoring: {
          filesModified: events.filter(e => e.action.tool === 'Write').length,
          toolExecutions: events.filter(e => e.action.type === 'tool_execution').length
        },
        // ... more SOC 2 mappings
      };
    }
    

Success Criteria: Dashboard shows real-time policy status.


Phase 5: Distribution and Polish (Day 11-14)

Goal: Distribute policies to machines and polish UX.

Milestone: Production-ready enterprise config system.

Tasks:

  1. Create Policy Sync Client (src/sync/client.ts)
    export class PolicySyncClient {
      private cacheDir: string;
    
      constructor(private serverUrl: string) {
        this.cacheDir = path.join(os.homedir(), '.claude-enterprise');
      }
    
      async sync(): Promise<void> {
        try {
          const policies = await this.fetchPolicies();
          await this.saveToCache(policies);
        } catch (error) {
          console.warn('Policy sync failed, using cached policies');
        }
      }
    
      async getPolicies(): Promise<EnterprisePolicy> {
        // Try cache first for offline support
        const cached = await this.loadFromCache();
    
        // Background sync
        this.sync().catch(() => {});
    
        return cached;
      }
    }
    
  2. Create MDM Integration Guide
    • macOS: Profile for config deployment
    • Windows: Group Policy template
    • Linux: systemd service
  3. Developer Experience Polish
    • Clear violation messages
    • Exception request workflow
    • Documentation for common scenarios
  4. Testing
    • Unit tests for all policies
    • Integration tests for hooks
    • Load testing for audit system

Success Criteria: System ready for team deployment.


Testing Strategy

Unit Tests: Policy Evaluation

// tests/engine/evaluator.test.ts
import { describe, it, expect } from 'vitest';
import { evaluatePolicy } from '../../src/engine/evaluator';

describe('policy evaluation', () => {
  describe('allowlist', () => {
    const policy = {
      name: 'approved-mcp',
      type: 'allowlist' as const,
      target: 'mcpServers',
      values: ['github', 'jira'],
      severity: 'error' as const,
      message: 'MCP {{value}} not approved'
    };

    it('allows approved values', () => {
      const context = { getValue: () => ['github'] };
      const result = evaluatePolicy(policy, context);
      expect(result.passed).toBe(true);
    });

    it('blocks unapproved values', () => {
      const context = { getValue: () => ['slack'] };
      const result = evaluatePolicy(policy, context);
      expect(result.passed).toBe(false);
      expect(result.message).toContain('slack');
    });

    it('identifies multiple violations', () => {
      const context = { getValue: () => ['github', 'slack', 'notion'] };
      const result = evaluatePolicy(policy, context);
      expect(result.passed).toBe(false);
      expect(result.value).toEqual(['slack', 'notion']);
    });
  });

  describe('pattern-deny', () => {
    const policy = {
      name: 'no-secrets',
      type: 'pattern-deny' as const,
      target: 'claudeMd',
      pattern: 'sk-[a-zA-Z0-9]{20,}',
      severity: 'error' as const,
      message: 'Secret detected in config'
    };

    it('passes when no secrets', () => {
      const context = { getValue: () => 'Normal configuration content' };
      const result = evaluatePolicy(policy, context);
      expect(result.passed).toBe(true);
    });

    it('blocks when secret found', () => {
      const context = { getValue: () => 'API key: sk-abcdefghij1234567890' };
      const result = evaluatePolicy(policy, context);
      expect(result.passed).toBe(false);
    });
  });
});

Integration Tests: Hooks

// tests/enforcement/hooks.test.ts
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { preToolUseHook } from '../../src/enforcement/hooks/pre-tool';

describe('preToolUseHook', () => {
  beforeEach(() => {
    vi.resetModules();
  });

  it('blocks policy violation', async () => {
    vi.mock('../../src/policy/loader', () => ({
      loadPolicies: () => [{
        name: 'block-bash',
        type: 'denylist',
        target: 'tool',
        values: ['Bash'],
        severity: 'error',
        message: 'Bash tool blocked'
      }]
    }));

    const event = {
      type: 'PreToolUse',
      tool: 'Bash',
      params: { command: 'rm -rf /' },
      session: { user: { email: 'user@company.com' } }
    };

    const result = await preToolUseHook(event);

    expect(result.decision).toBe('block');
    expect(result.reason).toContain('block-bash');
  });

  it('allows with valid exception', async () => {
    vi.mock('../../src/exceptions/checker', () => ({
      checkExceptions: () => Promise.resolve(true)
    }));

    const event = {
      type: 'PreToolUse',
      tool: 'Bash',
      params: { command: 'ls' },
      session: { user: { email: 'admin@company.com' } }
    };

    const result = await preToolUseHook(event);

    expect(result.decision).toBe('continue');
  });
});

Common Pitfalls & Debugging

Pitfall 1: Too Restrictive Policies

Symptom: Developers constantly hitting policy violations.

Bad:

policies:
  - name: no-file-writes
    type: denylist
    target: tool
    values: [Write]
    severity: error

Good:

policies:
  - name: restricted-paths
    type: pattern-deny
    target: writePath
    pattern: "^/(etc|var|usr|bin|sbin)"
    severity: error
    message: "System paths are protected"

Pitfall 2: Policy Server Single Point of Failure

Symptom: Claude Code unusable when policy server is down.

Bad:

// Blocks if server unreachable
const policies = await fetchPolicies();

Good:

// Graceful fallback
async function getPolicies() {
  try {
    const fresh = await fetchPolicies();
    await saveToCache(fresh);
    return fresh;
  } catch (error) {
    console.warn('Using cached policies');
    return loadFromCache();
  }
}

Pitfall 3: Insufficient Audit Context

Symptom: Can’t investigate incidents due to missing data.

Bad:

auditLog({
  action: 'file_write',
  user: userId
});

Good:

auditLog({
  eventId: uuid(),
  timestamp: new Date().toISOString(),
  user: {
    id: userId,
    email: userEmail,
    team: userTeam
  },
  machine: {
    id: machineId,
    hostname: os.hostname()
  },
  session: {
    id: sessionId,
    project: projectPath
  },
  action: {
    type: 'tool_execution',
    tool: 'Write',
    target: filePath,
    contentHash: hash(content),
    result: 'success'
  },
  policyCheck: {
    policies: checkedPolicies,
    result: 'passed'
  }
});

Pitfall 4: No Exception Expiration

Symptom: Temporary exceptions become permanent.

Bad:

exceptions:
  - user: alice@company.com
    exempt_from: [all-policies]
    reason: Emergency access
    # No expiration!

Good:

exceptions:
  - user: alice@company.com
    exempt_from: [file-access-restrictions]
    reason: Emergency production fix - INCIDENT-123
    expires: "2024-12-23T00:00:00Z"
    approved_by: manager@company.com
    reviewed_at: "2024-12-22T14:30:00Z"

The Interview Questions They’ll Ask

Prepare to answer these:

  1. “How would you roll out a policy change to 1000 developers?”
    • Staged rollout (10% -> 50% -> 100%)
    • Warning-only period before enforcement
    • Clear communication and documentation
    • Exception request process ready
    • Rollback plan if issues
  2. “What’s your strategy for handling emergency policy bypasses?”
    • On-call admin approval workflow
    • Time-limited emergency exceptions
    • Automatic expiration with review
    • Full audit trail
    • Post-incident review process
  3. “How do you ensure audit logs can’t be tampered with?”
    • Cryptographic signing of events
    • Immutable storage (write-once)
    • Separate audit infrastructure
    • Independent verification
    • Chain of custody
  4. “How do you test policies before deploying to production?”
    • Policy unit tests
    • Staging environment
    • Dry-run mode
    • Shadow evaluation (log-only)
    • Canary deployment
  5. “What’s the performance impact of policy checking?”
    • Local policy caching
    • Decision caching
    • Async audit logging
    • Batch processing
    • Lazy evaluation

Hints in Layers

Hint 1: Start with Hooks Use PreToolUse hooks to implement policy checking before actions. This is the enforcement point.

Hint 2: Policy Evaluation Build a policy engine that evaluates rules against proposed actions. Keep it fast and testable.

Hint 3: Central Distribution Host policies in a central location (git repo, S3, API) that clients fetch and cache locally.

Hint 4: Graceful Degradation If the policy server is unreachable, fail open with logging, not fail closed. But log everything.


Books That Will Help

Topic Book Chapter
Enterprise patterns “Enterprise Integration Patterns” by Hohpe & Woolf Ch. 7: Messaging
Policy design “Security Engineering” by Ross Anderson Ch. 6: Access Control
Compliance “The DevOps Handbook” by Kim et al. Ch. 22-23: Security & Compliance
Distributed config “Designing Data-Intensive Applications” by Kleppmann Ch. 9: Consistency
Audit logging “Logging and Log Management” by Chuvakin Full book

Extensions & Challenges

Extension 1: Policy as Rego (OPA)

Use Open Policy Agent’s Rego language for complex policies:

package claude.enterprise

default allow = false

allow {
    input.tool == "Read"
    allowed_path(input.params.path)
}

allowed_path(path) {
    startswith(path, "/home/")
}

allowed_path(path) {
    startswith(path, "/tmp/")
}

Extension 2: Real-Time Dashboard

Use WebSocket for live updates:

io.on('connection', (socket) => {
  auditStream.on('event', (event) => {
    socket.emit('audit_event', event);
  });
});

Extension 3: ML-Based Anomaly Detection

Flag unusual patterns:

async function detectAnomaly(event: AuditEvent): Promise<boolean> {
  const userBaseline = await getUserBaseline(event.user.id);
  const score = calculateAnomalyScore(event, userBaseline);
  return score > threshold;
}

Self-Assessment Checklist

Conceptual Understanding

  • Can you explain enterprise configuration precedence?
  • Can you describe different policy types and when to use each?
  • Can you explain audit logging requirements for SOC 2?
  • Can you list exception management best practices?
  • Can you explain graceful degradation patterns?

Implementation Skills

  • Can you parse and validate YAML policies?
  • Can you implement policy evaluation for different types?
  • Can you create enforcement hooks for Claude Code?
  • Can you design an audit event schema?
  • Can you build a policy distribution system?

Code Quality

  • Is your policy engine testable?
  • Are exceptions properly time-limited?
  • Is audit logging reliable?
  • Does the system fail gracefully?
  • Can policies be updated without restarts?

The Core Question You’ve Answered

“How do you enable Claude Code across an organization while maintaining security and compliance?”

Enterprises need guardrails. This project shows how to provide them without destroying the developer experience.

By building this system, you have mastered:

  1. Policy-as-Code: Expressing organizational rules as testable, versionable code
  2. Enterprise Distribution: Delivering configuration across many machines
  3. Audit & Compliance: Building trails that satisfy auditors
  4. Exception Management: Allowing flexibility while maintaining control

You can now deploy Claude Code safely across your entire organization.


Project Guide Version 1.0 - December 2025