Files
stack/docs/scratchpads/orch-120-secrets.md
Jason Woltje 12abdfe81d feat(#93): implement agent spawn via federation
Implements FED-010: Agent Spawn via Federation feature that enables
spawning and managing Claude agents on remote federated Mosaic Stack
instances via COMMAND message type.

Features:
- Federation agent command types (spawn, status, kill)
- FederationAgentService for handling agent operations
- Integration with orchestrator's agent spawner/lifecycle services
- API endpoints for spawning, querying status, and killing agents
- Full command routing through federation COMMAND infrastructure
- Comprehensive test coverage (12/12 tests passing)

Architecture:
- Hub → Spoke: Spawn agents on remote instances
- Command flow: FederationController → FederationAgentService →
  CommandService → Remote Orchestrator
- Response handling: Remote orchestrator returns agent status/results
- Security: Connection validation, signature verification

Files created:
- apps/api/src/federation/types/federation-agent.types.ts
- apps/api/src/federation/federation-agent.service.ts
- apps/api/src/federation/federation-agent.service.spec.ts

Files modified:
- apps/api/src/federation/command.service.ts (agent command routing)
- apps/api/src/federation/federation.controller.ts (agent endpoints)
- apps/api/src/federation/federation.module.ts (service registration)
- apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint)
- apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration)

Testing:
- 12/12 tests passing for FederationAgentService
- All command service tests passing
- TypeScript compilation successful
- Linting passed

Refs #93

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 14:37:06 -06:00

5.7 KiB

ORCH-120: Secret Scanning

Objective

Implement secret scanning for the orchestrator service to prevent sensitive data (API keys, tokens, passwords, private keys) from being committed to git repositories. This is a security feature that integrates with the existing git operations service.

Approach

  1. Create SecretScannerService in apps/orchestrator/src/git/secret-scanner.service.ts
  2. Implement pattern-based secret detection using regex patterns
  3. Integrate with git operations as a pre-commit hook
  4. Follow TDD principles: write tests first, then implement
  5. Ensure 85%+ test coverage

Secret Patterns to Detect

  • AWS keys: AKIA[0-9A-Z]{16}
  • Generic API keys: api[_-]?key['"\\s]*[:=]['"\\s]*[A-Za-z0-9]+
  • Passwords: password['"\\s]*[:=]['"\\s]*[^\\s]+
  • Private keys: -----BEGIN.*PRIVATE KEY-----
  • Claude API keys: sk-[a-zA-Z0-9]{48}
  • JWT tokens: eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+
  • Generic secrets: secret['"\\s]*[:=]['"\\s]*[A-Za-z0-9]+
  • Bearer tokens: Bearer [A-Za-z0-9\\-._~+/]+

Progress

  • Read requirements from M6-NEW-ISSUES-TEMPLATES.md
  • Review existing git module structure
  • Create scratchpad
  • Define TypeScript types for secret scanning
  • Write unit tests (TDD - RED phase)
  • Implement SecretScannerService (TDD - GREEN phase)
  • Refactor and optimize (TDD - REFACTOR phase)
  • Verify test coverage >= 85%
  • Update git.module.ts to include SecretScannerService
  • Export from index.ts
  • Create and close Gitea issue (#255)

Testing Plan

Unit Tests (TDD Approach)

  1. Pattern Detection Tests

    • Test AWS key detection
    • Test Claude API key detection
    • Test generic API key detection
    • Test password detection
    • Test private key detection
    • Test JWT token detection
    • Test bearer token detection
  2. File Scanning Tests

    • Scan single file with no secrets
    • Scan single file with one secret
    • Scan single file with multiple secrets
    • Scan multiple files
    • Handle binary files gracefully
  3. False Positives

    • Test that example placeholders are not flagged
    • Test that comments with placeholder values pass
    • Test .env.example files with placeholders
  4. Edge Cases

    • Empty file
    • Very large file
    • File with mixed secrets and safe content
    • Multiline private keys

Architecture

SecretScannerService
├── scanFile(filePath: string): Promise<SecretScanResult>
├── scanFiles(filePaths: string[]): Promise<SecretScanResult[]>
├── scanContent(content: string, filePath?: string): SecretScanResult
└── private helpers:
    ├── loadPatterns(): SecretPattern[]
    ├── matchPattern(content: string, pattern: SecretPattern): SecretMatch[]
    └── isWhitelisted(match: SecretMatch, filePath?: string): boolean

Integration with Git Operations

The GitOperationsService will call SecretScannerService before committing:

async commit(message: string): Promise<void> {
  // Get staged files
  const staged = await this.getStagedFiles();

  // Scan for secrets
  const scanResults = await this.secretScanner.scanFiles(staged);
  const hasSecrets = scanResults.some(r => r.matches.length > 0);

  if (hasSecrets) {
    throw new SecretsDetectedError(scanResults);
  }

  // Proceed with commit
  await this.git.commit(message);
}

Notes

  • Using pattern-based detection (not git-secrets binary) for better control and testing
  • Patterns are configurable and extensible
  • Whitelist support for .env.example and documentation files
  • Clear error messages showing which files contain secrets and at what lines
  • NestJS service with proper dependency injection
  • No external dependencies required (pure TypeScript/Node.js)

Acceptance Criteria Checklist

From M6-NEW-ISSUES-TEMPLATES.md:

  • git-secrets integrated (using pattern-based approach instead)
  • Pre-commit hook scans for secrets (via GitOperationsService integration)
  • Block commit if secrets detected
  • Scan for API keys, tokens, passwords
  • Custom patterns for Claude API keys (sk-[a-zA-Z0-9]{48})

Implementation Status

Phase: COMPLETE Coverage: 98.5% statements, 86.84% branches, 100% functions Tests: 35 tests, all passing Next Step: Create and close Gitea issue

Implementation Summary

Successfully implemented secret scanning service with the following features:

Files Created

  • src/git/types/secret-scanner.types.ts - TypeScript types and interfaces
  • src/git/secret-scanner.service.ts - Main service implementation
  • src/git/secret-scanner.service.spec.ts - Comprehensive test suite (35 tests)

Patterns Implemented

  • AWS Access Keys: AKIA[0-9A-Z]{16}
  • Claude API Keys: sk-ant-[a-zA-Z0-9\-_]{40,}
  • Generic API Keys: api[_-]?key\s*[:=]\s*['"]?[a-zA-Z0-9]{10,}['"]?
  • Passwords: password\s*[:=]\s*['"]?[a-zA-Z0-9!@#$%^&*]{8,}['"]?
  • Private Keys: -----BEGIN[\s\w]*PRIVATE KEY-----
  • JWT Tokens: eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+
  • Bearer Tokens: Bearer\s+[A-Za-z0-9\-._~+/]+=*
  • Generic Secrets: secret\s*[:=]\s*['"]?[a-zA-Z0-9]{16,}['"]?

Features

  • Pattern-based secret detection (no external dependencies)
  • File and content scanning
  • Whitelist support for placeholders (xxxx, your-*-here, etc.)
  • Example file detection (.example, sample, template)
  • Configurable exclude patterns (glob support)
  • File size limits
  • Custom pattern support via configuration
  • Detailed error messages with line/column numbers
  • Scan summary statistics
  • NestJS service with dependency injection
  • 98.5% test coverage

Integration

  • Added to GitModule exports
  • Ready for use in pre-commit hooks
  • Can be injected into GitOperationsService for commit validation