feat(domain): add policy-driven supply chain security subsystem#527
Open
feat(domain): add policy-driven supply chain security subsystem#527
Conversation
1eb0ac9 to
b314a3f
Compare
Contributor
Covers policy engine architecture, TypeSpec domain models, hybrid policy storage, runtime guardrails, CLI enforcement, CI integration, dependency risk evaluation, GitHub governance audit, web UI surfaces, and release integrity enforcement across 13 key decisions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… chain security 34 tasks across 7 phases: domain models, policy engine, CLI enforcement, runtime guardrails, GitHub governance audit, web UI surfaces, and CI integration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define SecurityMode, SecurityActionCategory, SecurityActionDisposition, SecuritySeverity, DependencyRiskType, and ReleaseIntegrityCheckType enums in tsp/common/enums/security.tsp. Define SecurityPolicy, SecurityEvent, DependencyFinding, ReleaseIntegrityResult, EffectivePolicySnapshot and supporting models in tsp/domain/entities/security.tsp. Add SecurityConfig to Settings model with mode, lastEvaluationAt, and policySource fields. Run tsp:compile to generate output.ts with all new types.
Migration 053 adds security_mode (TEXT NOT NULL DEFAULT 'Advisory'), security_last_evaluation_at (TEXT), and security_policy_source (TEXT) columns to the settings table. Migration 054 creates the security_events table with id, repository_path, feature_id, severity, category, disposition, actor, message, remediation_summary, and created_at columns plus indexes on (repository_path, created_at) and (feature_id). Both migrations are idempotent and additive-only with no-op down().
Add SecurityConfig support to the settings persistence layer: - Map security.mode/lastEvaluationAt/policySource to flat DB columns - Default security.mode to Advisory in settings defaults factory - Update SQLite repository INSERT/UPDATE for new security columns - Add comprehensive mapper tests (toDatabase, fromDatabase, round-trip) - Add defaults factory tests for SecurityConfig Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce the central ISecurityPolicyService port interface and its infrastructure implementation. Includes security policy file reader (shep.security.yaml via js-yaml), schema validator with fail-fast semantics, and deterministic policy evaluator that merges global settings defaults with repository policy using strict-wins precedence. Also adds ISecurityEventRepository port interface for event persistence. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement SecurityEventRow mapper with toDatabase/fromDatabase functions and SQLiteSecurityEventRepository with save, findByRepository, findByFeature, deleteOlderThan (90-day retention), and count operations. All queries use parameterized SQL. Includes mapper unit tests and repository integration tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Register ISecurityPolicyService, ISecurityEventRepository, SecurityPolicyFileReader, and SecurityPolicyValidator in the DI container. All security services follow existing factory registration patterns for consistent resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add four use cases for the security subsystem: - EnforceSecurityUseCase: orchestrates full enforcement flow - EvaluateSecurityPolicyUseCase: wraps policy evaluation - GetSecurityStateUseCase: returns security state for UI - RecordSecurityEventUseCase: persists events with retention Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add createSecurityCommand() with enforce subcommand that evaluates repository security posture via EnforceSecurityUseCase. Supports --output json for CI consumption and --repo for custom paths. Exit code 0 for pass, 1 for enforce-mode failure. Register all phase 3 services and use cases in the DI container. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SecurityConstraints type and securityConstraints field to AgentExecutionOptions. Create SecurityViolationError class for policy violations. Add reusable validateSecurityConstraints() function and integrate into Claude Code executor with Enforce mode fail-closed and Advisory mode warning behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add securityMode and securityActionDispositions channels to FeatureAgentAnnotation. Extend WorkerArgs with security fields and parseWorkerArgs with --security-mode and --security-dispositions CLI arg parsing. Thread security state into graph invoke calls. Fix mock state objects in existing tests to include new channels. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass securityMode from settings to all 6 process spawn call sites (create, start, resume, approve, reject, unblock) so the worker process receives the configured security policy mode as a CLI arg. Update IFeatureAgentProcessService interface and FeatureAgentProcessService implementation to accept and forward securityMode and securityActionDispositions spawn options. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add security-pre-check module with classifyNodeAction() to map graph node names to SecurityActionCategory, and checkSecurityDisposition() to evaluate the effective policy before agent execution. Integrate into executeNode() in node-helpers.ts: denied actions throw SecurityViolationError in Enforce mode, approval-required actions trigger interrupt(), and Advisory mode logs warnings without blocking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
extend igithubrepositoryservice with auditrepositorygovernance method and governancefinding type for branch protection and codeowners checks. implement gh-cli-backed governance auditor that handles auth errors gracefully as unknown findings. integrate governance audit into enforcesecurityusecase as audit-only (per fr-15) so governance findings are reported and persisted but never cause enforce-mode failures. add governance section to cli output and i18n translations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add web UI components for supply-chain security observability: - Security server actions (getSecurityState, enforceSececurity, updateSecurityMode) - SecurityBadge component with mode-aware shield icon on feature nodes - SecurityPanel collapsible drawer section with severity summary and event list - SupplyChainSecuritySettingsSection with mode selector and findings display - Integrate security section into settings page navigation and layout - Thread securityMode through build-graph-nodes to feature node data - Add security i18n keys to all locale web.json and cli.json files - Fix .js import extension in security-violation.error.ts for Turbopack - Add getSettings mock to start-feature and prd-approval integration tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add security-enforce parallel job to ci.yml that runs shep security enforce --output json. Gate both release and dev-release jobs on the security-enforce job passing. Add scaffoldSecurityPolicy method to ISpecInitializerService and SpecInitializerService that generates a baseline shep.security.yaml with Advisory mode, default action dispositions, and dependency/release rules with YAML comments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server actions were importing security use case classes directly which caused Next.js turbopack to attempt bundling the entire node dependency tree. Switch to type-only imports with string DI token resolution, matching the pattern used by all other server actions. Add corresponding string token registrations in the DI container. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Evidence covers all 7 phases of the 083-supply-chain-security feature: - 120 security-specific unit tests passing (13 test files) - 16 runtime guardrail tests passing - 43 release integrity and governance tests passing - 608 integration tests passing - CLI enforce command with human and JSON output - App settings page with security section rendering - Storybook stories for SecurityPanel and SecurityBadge components - Full test suite: 6181 tests passing across 452 test files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add missing security server action mock for Storybook to prevent dynamic import failure in supply-chain-security-settings-section stories. Import i18n singleton in preview.tsx to ensure translations are available before stories render. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recaptured all evidence files after fixing Storybook mock and i18n initialization issues. Screenshots now show real component renders instead of error pages. Test evidence uses targeted configs for clean, focused output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recaptured all 15 evidence files with improved quality: - App screenshots now show real settings page with Security tab, security mode selector, and Control Center with feature cards - Storybook screenshots now include full page with sidebar context instead of tiny clipped component-only captures - Test outputs freshly captured from passing test runs - CLI outputs show actual security enforce command results Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Why: buildGraphNodes accepted a securityMode option and feature-node rendered SecurityBadge when data.securityMode was set, but get-graph-data never forwarded security.mode from settings — so no badge ever appeared on the live canvas despite the wiring existing end-to-end. Adds 4 regression tests in build-graph-nodes.test.ts and a LESSONS.md entry so the call site cannot silently drift again. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rebase onto main pulled in main's new IGitHubRepositoryService methods (getAuthenticatedUser, checkPushAccess, forkRepository). The governance audit commit's mock in enforce-security.use-case.test.ts was missing these additions and broke typecheck. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4ee3ded to
8338d20
Compare
Contributor
Adds a master feature flag that makes the entire supply chain security feature inert when off. Defaults to true to preserve current behavior. Gates every surface the feature touches: - Web canvas: get-graph-data skips passing securityMode so no badge renders - Web Settings page: Security nav tab and section are hidden - Agent ExecuteNode: resolveEffectiveSecurityMode forces Disabled so the pre-check becomes a no-op regardless of state.securityMode - CLI: shep security enforce exits 0 with a flag-disabled note, honoring both settings and the SHEP_SUPPLY_CHAIN_SECURITY env var - CI: security-enforce job reads SHEP_SUPPLY_CHAIN_SECURITY from repo vars so the flag can be flipped from one place Why: the feature previously had no rollback path. The only way to disable it was to set SecurityMode=Disabled in settings, which left the UI surfaces, migrations, and enforcement wiring all in place. If any component misbehaves in production there was no one-line escape hatch. Now flipping featureFlags.supplyChainSecurity=false (or the env var in CI) renders the feature fully inert. Adds regression tests for every gate: - Mapper round-trip for the new column (migration 056) - CLI command gate via both settings and env var (5 new tests) - resolveEffectiveSecurityMode helper (4 new tests) - FeatureFlagsSettingsSection renders the new toggle - Settings defaults include supplyChainSecurity=true Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
🔒 Security Issues Detected
🤖 Generated by CI Security Scan | View Details |
The commit 1c6b476 on feat/messaging-remote-control contains a test fixture with a fake API key that gitleaks flags. A follow-up commit 3173676 on the same branch already tried to fix it, and its fingerprint is in .gitleaksignore — but the original commit is still reachable in the git object graph, so gitleaks detect scanning the repo picks it up. Adds the earlier fingerprint to the allowlist so it matches the already- whitelisted replacement. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
…urity # Conflicts: # .github/workflows/ci.yml # .gitleaksignore # LESSONS.md # packages/core/src/domain/generated/output.ts # packages/core/src/infrastructure/di/container.ts # src/presentation/web/app/(dashboard)/get-graph-data.ts # src/presentation/web/app/build-graph-nodes.ts # src/presentation/web/components/features/settings/settings-page-client.tsx # tsp/domain/entities/index.tsp Co-Authored-By: Shep Bot <shep-agent@users.noreply.github.com>
Co-Authored-By: Shep Bot <shep-agent@users.noreply.github.com>
Co-Authored-By: Shep Bot <shep-agent@users.noreply.github.com>
Contributor
🔒 Security Issues Detected
🤖 Generated by CI Security Scan | View Details |
…s gitleaks Co-Authored-By: Shep Bot <shep-agent@users.noreply.github.com>
Contributor
🔒 Security Issues Detected
🤖 Generated by CI Security Scan | View Details |
…n stories Co-Authored-By: Shep Bot <shep-agent@users.noreply.github.com>
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a phased, policy-driven supply chain security subsystem that constrains agent execution, validates dependency and release-integrity risk, and exposes security state across CLI, CI, and the Control Center.
shep.security.yaml) + SQLite settings persistence, strict-wins merge precedence, deterministic evaluation across CLI/CI/runtimeexecuteNode()— classifies actions into categories (dependency install, CI/release modification, publish), applies deny/approval_required/warn/allow dispositions per policyshep security enforcecommand with human-readable and structured JSON/YAML output, non-zero exit on enforce-mode failuresghCLI (audit-only, no mutations)Key Design Decisions
ghaudit onlyArchitecture
The implementation spans all four Clean Architecture layers:
Evidence
CLI
shep security enforceshowing Advisory mode, 8 findings, exit code 0Web UI
Storybook
Tests
Test plan
Built with Shep 🐑 Shep Bot