Skip to content

Latest commit

 

History

History
858 lines (671 loc) · 43.7 KB

File metadata and controls

858 lines (671 loc) · 43.7 KB

Hack23 Logo

⚙️ European Parliament MCP Server — Workflows

CI/CD Pipeline & Automation Documentation
12 GitHub Actions Workflows — TypeScript/Node.js — DevSecOps Pipeline

Test and Report CodeQL Scorecard Release

Owner Version Effective Date Review Cycle

📋 Document Owner: DevOps Team | 📄 Version: 0.7.0 | 📅 Last Updated: 2026-05-05 (UTC)
🔄 Review Cycle: Quarterly | ⏰ Next Review: 2026-08-05
🏷️ Classification: Public (Open Source MCP Server)
🔷 Project Version: 1.2.21
🔷 TypeScript Baseline: 6.0.3 ✅ ISMS Compliance: ISO 27001 (A.8.31, A.14.2, A.12.1), NIST CSF 2.0 (PR.DS-6, DE.CM-8), CIS Controls v8.1 (2.2, 4.1, 16.6)


📋 Table of Contents

  1. Architecture Documentation Map
  2. Pipeline Overview
  3. Pipeline Stages Summary
  4. Workflow Overview
  5. Workflow Relationships
  6. Detailed Pipeline Stages
  7. Caching & Resilience
  8. Security Controls
  9. Quality Gates
  10. ISMS Compliance
  11. Related Documentation

🗺️ Architecture Documentation Map

Document Current Future Description
Architecture ARCHITECTURE.md FUTURE_ARCHITECTURE.md C4 model, containers, components
Mind Map MINDMAP.md FUTURE_MINDMAP.md System concepts and relationships
SWOT Analysis SWOT.md FUTURE_SWOT.md Strategic positioning
Data Model DATA_MODEL.md FUTURE_DATA_MODEL.md Entity relationships and schemas
Flowchart FLOWCHART.md FUTURE_FLOWCHART.md Business process flows
State Diagram STATEDIAGRAM.md FUTURE_STATEDIAGRAM.md System state transitions
Workflows WORKFLOWS.md (this document) FUTURE_WORKFLOWS.md CI/CD pipeline documentation
Security Architecture SECURITY_ARCHITECTURE.md FUTURE_SECURITY_ARCHITECTURE.md Security controls and design
Threat Model THREAT_MODEL.md STRIDE-based threat analysis
CRA Assessment CRA-ASSESSMENT.md EU Cyber Resilience Act review
Architecture Diagrams ARCHITECTURE_DIAGRAMS.md Supplementary C4 diagrams

🎯 Pipeline Overview

The European Parliament MCP Server (v0.6.2) maintains 11 automated GitHub Actions workflows organized across 8 pipeline stages, providing comprehensive DevSecOps coverage for a TypeScript/Node.js MCP server. All workflows align with Hack23 ISMS policies and follow supply-chain security best practices.

graph LR
    A["📝 Code Change"] --> B["🔍 Validate"]
    B --> C["🧪 Build & Test"]
    C --> D["🔒 Security Scan"]
    D --> E["🔄 Integration"]
    E --> F{"🏷️ Tagged<br>Release?"}
    F -->|Yes| G["📦 Release & Publish"]
    G --> H["🛡️ Supply Chain"]
    H --> I["📊 Monitor"]
    F -->|No| J["✅ PR Ready"]

    style A fill:#4a90e2,stroke:#2e6ab0,color:#fff
    style B fill:#f5a623,stroke:#d48b1a,color:#fff
    style C fill:#7b68ee,stroke:#5b48ce,color:#fff
    style D fill:#e74c3c,stroke:#c0392b,color:#fff
    style E fill:#2ecc71,stroke:#27ae60,color:#fff
    style F fill:#ffd43b,stroke:#f0c419,color:#333
    style G fill:#9b59b6,stroke:#8e44ad,color:#fff
    style H fill:#e67e22,stroke:#d35400,color:#fff
    style I fill:#1abc9c,stroke:#16a085,color:#fff
    style J fill:#51cf66,stroke:#40c057,color:#fff
Loading

Key Principles

  • 🔒 Security First — All workflows use step-security/harden-runner, pinned action SHAs, and least-privilege permissions
  • 📦 Supply Chain Integrity — SLSA Level 3 provenance, SPDX JSON SBOMs with GitHub Attestations
  • 🧪 Quality Enforcement — 80%+ code coverage, zero lint errors, type-safe builds, license compliance
  • 📊 Transparency — All evidence available in the Documentation Portal

📊 Pipeline Stages Summary

Stage Pipeline Phase Workflows Trigger Duration Purpose
1 Code Validation dependency-review.yml, labeler.yml, knip.yml PR ~1 min Dependency scanning, PR labeling, unused-code detection
2 Build & Test test-and-report.yml Push, PR ~3 min TypeScript build, lint, unit tests, coverage
3 Security Analysis codeql.yml Push, PR, Weekly ~5 min SAST scanning (CodeQL)
4 Integration Testing integration-tests.yml, osint-qa.yml Push, PR, Daily (integration-tests.yml only; osint-qa.yml is Push (paths), PR (paths)) ~5–20 min E2E tests, live API validation, OSINT QA harness (contract + per-file coverage + Stryker mutation)
5 Release & Publish release.yml Tag (v*) ~8 min npm publish, GitHub Release, docs, SBOM generation
6 Supply Chain slsa-provenance.yml Release, Push ~4 min SLSA provenance, attestations
7 Continuous Monitoring scorecard.yml, refresh-stats.yml Push, Weekly ~5 min OpenSSF Scorecard, EP statistics refresh
8 Repository Mgmt setup-labels.yml, copilot-setup-steps.yml Manual ~1 min Label sync, Copilot agent setup

📋 Workflow Overview

# Workflow File Trigger Node.js Permissions ISMS Evidence
1 Test and Report test-and-report.yml Push, PR 26.x + TS 6.0.3 read-all, scoped per job Secure Dev Policy
2 CodeQL Analysis codeql.yml Push, PR, Weekly security-events: write ISO 27001 A.14.2.8
3 Build, Attest and Release release.yml Tag (v*), Manual 26.x + TS 6.0.3 id-token: write, attestations: write SLSA Level 3, includes SBOM
4 Integration & E2E Tests integration-tests.yml Push, PR, Daily, Manual 26.x + TS 6.0.3 read-all Quality Assurance
5 SLSA Provenance slsa-provenance.yml Tag (v*), Release, Manual node-version: 26 id-token: write, attestations: write SLSA Level 3
6 Scorecard scorecard.yml Push, Weekly security-events: write, id-token: write Open Source Policy
7 Dependency Review dependency-review.yml PR contents: read NIST CSF DE.CM-8
8 PR Labeler labeler.yml PR pull-requests: write Process Automation
9 Setup Labels setup-labels.yml Manual issues: write Configuration Mgmt
10 Copilot Setup copilot-setup-steps.yml Push, PR, Manual 26.x + TS 6.0.3 Scoped per caller Dev Tooling
11 EP Statistics Refresh refresh-stats.yml Weekly (cron), Manual 26.x + TS 6.0.3 contents: write Agentic data intelligence
12 Knip — Unused Code knip.yml Push, PR, Manual node-version: 26 contents: read ISO 27001 A.8.28 (Secure Coding)
13 OSINT QA Harness osint-qa.yml Push (paths), PR (paths), Manual node-version: 26 read-all (workflow), scoped to contents: read per job ISO 27001 A.8.29 (Security testing in dev & acceptance), A.8.34 (Audit protection); CIS v8.1 Control 16; Hack23 ISMS Secure Development Policy §4.4 (Testing), §4.5 (QA)

🔄 Workflow Relationships

flowchart TB
    subgraph "🔀 Developer Activity"
        DEV["👨‍💻 Code Push / PR"]
    end

    subgraph "Stage 1: Code Validation"
        DEV --> LABEL["🏷️ PR Labeler<br><code>labeler.yml</code>"]
        DEV --> DEPREVIEW["🔍 Dependency Review<br><code>dependency-review.yml</code>"]
        DEV --> KNIP_WF["🧹 Knip<br><code>knip.yml</code>"]
    end

    subgraph "Stage 2: Build & Test"
        DEV --> TEST["🧪 Test & Report<br><code>test-and-report.yml</code>"]
        TEST --> PREPARE["⚙️ Prepare<br>Node.js 26, npm install"]
        PREPARE --> BUILD_VAL["📦 Build Validation"]
        PREPARE --> UNIT["🧪 Unit Tests"]
        BUILD_VAL --> TYPE["tsc --noEmit"]
        BUILD_VAL --> LINT["ESLint 10.x"]
        BUILD_VAL --> KNIP["Knip"]
        BUILD_VAL --> SBOM_CHECK["SBOM Quality ≥7.0"]
        UNIT --> COV{"Coverage ≥80%?"}
        COV -->|Yes| PASS["✅ Pass"]
        COV -->|No| WARN["⚠️ Warning"]
    end

    subgraph "Stage 3: Security Analysis"
        DEV --> CODEQL["🔒 CodeQL<br><code>codeql.yml</code>"]
        CODEQL --> SARIF["📄 SARIF Upload"]
    end

    subgraph "Stage 4: Integration Testing"
        DEV --> INTEGRATION["🔄 Integration Tests<br><code>integration-tests.yml</code>"]
        INTEGRATION --> E2E["E2E Tests"]
        INTEGRATION --> PERF["Performance Tests"]
        INTEGRATION --> SECSCAN["Security Scan<br>npm audit"]
    end

    subgraph "Stage 5: Release (tags only)"
        TAG["🏷️ Push v* Tag"] --> RELEASE["📦 Release<br><code>release.yml</code>"]
        RELEASE --> NPM["npm publish<br>--provenance"]
        RELEASE --> GH_RELEASE["GitHub Release<br>+ Changelog"]
        RELEASE --> DOCS["📚 TypeDoc"]
        RELEASE --> SBOM_RELEASE["📋 SBOM (SPDX JSON)"]
    end

    subgraph "Stage 6: Supply Chain"
        RELEASE --> SLSA["🛡️ SLSA Provenance<br><code>slsa-provenance.yml</code>"]
        SLSA --> SLSA_VERIFY["✅ Verify Provenance"]
        SLSA --> SLSA_ATTEST["🔏 SLSA Attestation"]
    end

    subgraph "Stage 7: Continuous Monitoring"
        WEEKLY["⏰ Scheduled"] --> SCORECARD["🏆 OpenSSF Scorecard<br><code>scorecard.yml</code>"]
        WEEKLY --> REFRESH_STATS["📊 EP Statistics Refresh<br><code>refresh-stats.yml</code>"]
        WEEKLY --> CODEQL
        WEEKLY --> INTEGRATION
    end

    style DEV fill:#4a90e2,stroke:#2e6ab0,color:#fff
    style TEST fill:#7b68ee,stroke:#5b48ce,color:#fff
    style CODEQL fill:#e74c3c,stroke:#c0392b,color:#fff
    style INTEGRATION fill:#2ecc71,stroke:#27ae60,color:#fff
    style RELEASE fill:#9b59b6,stroke:#8e44ad,color:#fff
    style SLSA fill:#e67e22,stroke:#d35400,color:#fff
    style SCORECARD fill:#1abc9c,stroke:#16a085,color:#fff
    style REFRESH_STATS fill:#1abc9c,stroke:#16a085,color:#fff
    style PASS fill:#51cf66,stroke:#40c057,color:#fff
Loading

🏗️ Detailed Pipeline Stages

Stage 1: Code Validation

1.1 Dependency Review

Property Value
Workflow File .github/workflows/dependency-review.yml
Trigger Pull requests
Duration ~1 min
Quality Gate Block PRs with known vulnerabilities
Runner Hardening step-security/harden-runner (egress audit)

Key Steps:

  1. Harden runner environment
  2. Checkout repository
  3. Run GitHub Dependency Review Action
  4. Post PR comment with vulnerability summary

Security Checks:

  • Known vulnerability detection (CVE database, GitHub Advisory Database)
  • License compliance — allowed: MIT, Apache-2.0, BSD-*, ISC
  • Dependency graph analysis for transitive vulnerabilities
  • Security advisory alerts for new disclosures

1.2 Pull Request Labeler

Property Value
Workflow File .github/workflows/labeler.yml
Trigger pull_request_target (opened, synchronize, reopened, edited)
Duration ~30 sec
Quality Gate Informational (auto-classification)

Label Categories:

Category Labels File Patterns
MCP mcp-tools, mcp-resources, mcp-prompts, mcp-protocol src/tools/**, src/resources/**
EP Data ep-api, ep-data, meps, plenary, committees, documents src/api/**, src/ep-*/**
Quality testing, documentation, security, dependencies tests/**, docs/**, *.md
Components component-tools, component-resources, component-client src/tools/**, src/resources/**

1.3 Knip — Unused Code Detection

Property Value
Workflow File .github/workflows/knip.yml
Trigger Push to main, Pull requests to main, Manual dispatch
Duration ~1 min
Node.js Version node-version: 26
Quality Gate 0 unused exports, dependencies, or files (blocking)
Runner Hardening step-security/harden-runner (egress audit)
Concurrency cancel-in-progress per ref to save CI minutes

Key Steps:

  1. Harden runner environment
  2. Checkout repository
  3. Setup Node.js 26 + cache ~/.npm
  4. npm ci
  5. npm run knip (uses knip.json covering src/**/*.ts, tests/**/*.ts, scripts/**/*.ts)
  6. Post job summary with triage guidance on failure

Triage Guidance (surfaced in failure summary):

  1. Integrate — code is intended but not yet wired up; complete integration.
  2. Whitelist — code is used by tooling Knip cannot detect (agentic workflows, dynamic imports); update knip.json.
  3. Delete — code is genuinely dead; remove it.

Coverage Scope:

  • src/**/*.ts — production source
  • tests/**/*.ts — unit, integration, E2E, performance tests
  • scripts/**/*.ts — build, release, and statistics-generation scripts

Note: npm run knip also runs as a step inside test-and-report.yml's build-validation job. The dedicated knip.yml workflow runs in parallel for faster developer feedback and clearer signal in PR checks.


Stage 2: Build & Test

2.1 Test and Report

Property Value
Workflow File .github/workflows/test-and-report.yml
Trigger Push to main, Pull requests to main
Duration ~3 min
Node.js Version node-version: 26
Quality Gates 9 gates (see table below)

Jobs:

prepare → build-validation → unit-tests → report

Job Details:

Job Steps Artifacts
prepare Setup Node.js 26, npm ci, cache dependencies Cached node_modules
build-validation tsc --noEmit (TypeScript 6.0.3), ESLint, Knip, npm run build, license check, SBOM quality Build artifacts, SBOM report
unit-tests npm run test:coverage, coverage threshold check, Codecov upload Coverage reports (lcov, JSON)
report Combine artifacts, generate test summary, PR comment Combined test report

Quality Gates:

Check Command Threshold On Failure
TypeScript compilation tsc --noEmit 0 errors ❌ Block merge
Linting npx eslint . 0 errors ❌ Block merge
Unused code npx knip 0 unused exports ❌ Block merge
Build npm run build Successful compilation ❌ Block merge
Package validation npm pack --dry-run Valid package structure ❌ Block merge
License compliance license-checker MIT, Apache-2.0, BSD, ISC only ❌ Block merge
SBOM quality SBOMQS ≥7.0/10 ❌ Block merge
Unit tests npm run test:coverage All tests pass ❌ Block merge
Code coverage Vitest coverage ≥80% lines ⚠️ Warning

Stage 3: Security Analysis

3.1 CodeQL Analysis

Property Value
Workflow File .github/workflows/codeql.yml
Trigger Push to main, PR to main, Weekly (Monday 00:00 UTC)
Duration ~5 min
Quality Gate No high/critical findings
Permissions contents: read, actions: read, security-events: write

Configuration:

Setting Value
Language JavaScript/TypeScript
Query suites security-extended, security-and-quality
Paths analyzed src/ (excludes node_modules, dist, tests)
Output SARIF uploaded to GitHub Security tab

CWE Coverage:

CWE ID Vulnerability Class Relevance to MCP Server
CWE-20 Input Validation Zod schema validation for all tool inputs
CWE-79 Cross-Site Scripting Response sanitization for HTML content
CWE-78 Command Injection No shell execution in codebase
CWE-94 Code Injection No dynamic code evaluation
CWE-200 Information Exposure GDPR-compliant audit logging
CWE-312 Cleartext Storage No sensitive data persistence
CWE-287 Authentication Issues Read-only public API access

Stage 4: Integration Testing

4.1 Integration and E2E Tests

Property Value
Workflow File .github/workflows/integration-tests.yml
Trigger Push to main, PR to main, Daily (02:00 UTC), Manual
Duration ~5 min
Node.js Version node-version: 26
Quality Gate All integration and E2E tests pass

Environment Variables:

Variable Default Purpose
EP_API_URL https://data.europarl.europa.eu/api/v2 European Parliament API endpoint
EP_INTEGRATION_TESTS true Enable live API tests
EP_REQUEST_TIMEOUT_MS 30000 Request timeout (30 sec)
NODE_ENV test Runtime environment

Jobs:

Job Purpose Key Commands
integration-tests Full test pipeline tsc --noEmit, npm run lint, npm run build, npm run test:unit, npm run test:integration, npm run test:e2e, npm run test:performance
security-scan Dependency audit npm audit --audit-level=moderate, license compliance check
test-summary Aggregate results Download artifacts, generate summary report

Test Modes:

Mode Description API Calls
Unit Integration Mock-based contract tests None (mocked)
Live API Real EP API calls (EP_INTEGRATION_TESTS=true) Yes — rate-limited
E2E Full MCP protocol round-trip tests Yes — real transport
Performance Response time benchmarks Yes — timed requests

Rate Limit Awareness:

  • EP API limit: 100 requests per 15 minutes
  • Scheduled daily runs minimize API impact
  • Fixture capture mode for offline replay

Stage 5: Release & Publish

5.1 Build, Attest and Release

Property Value
Workflow File .github/workflows/release.yml
Trigger Push tags (v*), Manual dispatch
Duration ~8 min
Node.js Version node-version: 26
Secrets NPM_TOKEN
Quality Gate Full test suite passes, attestations generated

Jobs:

prepare → build → release

Job Details:

Job Permissions Key Steps
prepare contents: write Version extraction, tsc --noEmit, full test suite, TypeDoc generation, coverage reports, commit docs to repo
build contents: read, id-token: write, attestations: write npm run build, npm pack, zip creation, SPDX JSON SBOM generation, GitHub Attestations API
release contents: write, id-token: write Download artifacts, draft release notes, create GitHub Release, npm publish --provenance

Release Process:

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub Actions
    participant NPM as npm Registry
    participant API as GitHub API

    Dev->>GH: Push v* tag
    GH->>GH: Prepare (type-check, test, docs)
    GH->>GH: Build (tsc, npm pack, zip)
    GH->>API: Generate build attestation
    GH->>GH: Generate SPDX JSON SBOM
    GH->>API: Create GitHub Release + changelog
    GH->>NPM: npm publish --provenance
    NPM-->>GH: Published with SLSA provenance
    GH->>API: Upload release artifacts (zip, SBOM)
Loading

Artifact Signing:

Artifact Method Verification
npm package --provenance flag (Sigstore) npm audit signatures
Build artifacts GitHub Attestations API gh attestation verify
SBOM SPDX JSON with attestation gh attestation verify
Release GitHub Release with checksums SHA256 hash comparison

Stage 6: Supply Chain Security

6.1 SBOM Generation (Integrated into CI and Release Workflows)

Note: SBOM generation is integrated into the test-and-report.yml and release.yml workflows. There is no standalone sbom-generation.yml workflow file, and slsa-provenance.yml does not produce an SBOM. Every push/PR produces a SPDX-JSON SBOM via test-and-report.yml (with an SBOMQS quality gate), and every tagged release produces an attested SPDX-JSON SBOM attached to the GitHub Release via release.yml.

SBOM Creation in CI and Release Pipelines:

Property Value
Workflow Files .github/workflows/test-and-report.yml (PR/push quality gate), .github/workflows/release.yml (release artifact + attestation)
Trigger Push, PR (test-and-report.yml); Tag push (v*), Manual dispatch (release.yml)
Duration Included in the ~3 min build-validation job and the ~8 min release workflow
Quality Gate SBOMQS quality score ≥7.0/10 (enforced in test-and-report.yml)
Format SPDX 2.3 JSON (via anchore/sbom-action with format: spdx-json) + GitHub Attestations on release
Permissions contents: write, id-token: write, attestations: write (release only)

SBOM Process:

test-and-report.yml generates a SPDX-JSON SBOM via anchore/sbom-action on every push and PR, then scores it with SBOMQS and fails the build if the average score falls below 7.0/10. release.yml generates the same SPDX-JSON SBOM at release time, produces a GitHub SBOM attestation (actions/attest-sbom), attaches the .spdx.json and .spdx.json.intoto.jsonl attestation bundle to the GitHub Release, and uploads them as release assets that are verifiable via gh attestation verify.

6.2 SLSA Provenance

Property Value
Workflow File .github/workflows/slsa-provenance.yml
Trigger Push tags (v*), Release (published), Manual
Duration ~4 min
Quality Gate SLSA Level 3 provenance verified
Permissions contents: write, id-token: write, attestations: write, actions: read

Jobs:

build → provenance → verify → publish-npm (release only)

SLSA Level 3 Requirements:

SLSA Requirement Implementation Evidence
Build as code GitHub Actions workflow definition .github/workflows/slsa-provenance.yml
Hermetic build No network access during build step Harden-runner egress audit
Isolated build GitHub-hosted Ubuntu 26.04 runners Ephemeral VMs per run
Parameterless No user-controlled build parameters Workflow inputs validated
Provenance Signed SLSA v1.0 provenance document slsa-github-generator output
Verification Checksums + attestation verification gh attestation verify

Stage 7: Continuous Monitoring

7.1 OpenSSF Scorecard

Property Value
Workflow File .github/workflows/scorecard.yml
Trigger Push to main, Weekly (Tuesday 07:20 UTC), branch_protection_rule
Duration ~3 min
Quality Gate Target score ≥8.0/10
Permissions security-events: write, id-token: write, contents: read, actions: read

Scorecard Checks Evaluated:

Check Description Target
Branch-Protection Enforce reviews, status checks ✅ Enabled
CI-Tests CI runs on PRs ✅ Active
Code-Review PRs require review ✅ Required
Dangerous-Workflow No pull_request_target misuse ✅ Clean
Dependency-Update-Tool Dependabot or Renovate ✅ Dependabot
Maintained Recent commits and activity ✅ Active
Pinned-Dependencies SHA256-pinned actions ✅ All pinned
SAST Static analysis enabled ✅ CodeQL
Security-Policy SECURITY.md present ✅ Published
Signed-Releases Provenance on releases ✅ SLSA L3
Token-Permissions Minimal token permissions ✅ Scoped
Vulnerabilities No known CVEs ✅ Monitored

7.2 EP Statistics Refresh (Agentic Workflow)

Property Value
Workflow File .github/workflows/refresh-stats.yml
Trigger Weekly (Monday 06:00 UTC cron), Manual dispatch
Duration ~5 min
Node.js Version node-version: 26
Permissions contents: write

Purpose:

The refresh-stats.yml workflow is an agentic GitHub workflow that automatically refreshes precomputed European Parliament statistics in src/data/generatedStats.ts. It fetches live counts from the EP Open Data Portal API, validates both raw and computed statistics, and commits updates on successful validation. This is an example of the Continuous AI pattern — automated intelligence gathering with validation guardrails.

Jobs:

Job Purpose Key Steps
refresh-stats Refresh EP stats Check out repo, setup Node.js 26.x, install deps, run refresh script, validate stats, commit if changed

Workflow Features:

  • Agentic execution: Autonomous weekly data refresh without human intervention
  • Validation gates: Validates raw EP API counts + computed statistics before commit
  • Idempotent: Commits only if stats have actually changed
  • Rollback safe: Uses standard git commit workflow — errors can be reverted via Git

Stage 8: Repository Management

8.1 Setup Repository Labels

Property Value
Workflow File .github/workflows/setup-labels.yml
Trigger Manual dispatch (workflow_dispatch)
Duration ~1 min
Input recreate_all (boolean) — destructively recreate all labels

Features:

  • Creates 50+ standardized labels with consistent colors and descriptions
  • Categories: features, bugs, MCP-specific, EP-specific, infrastructure, testing, security, docs, dependencies, priorities, sizes
  • Validates labeler configuration compatibility
  • Optional destructive recreation mode

8.2 Copilot Setup Steps

Property Value
Workflow File .github/workflows/copilot-setup-steps.yml
Trigger workflow_call (reusable workflow)
Duration ~2 min
Node.js Version node-version: 26

Setup Steps:

  1. Checkout repository with full history
  2. Cache APT packages and npm modules
  3. Setup Node.js 26.x with npm cache
  4. Install global MCP servers (@modelcontextprotocol/server-filesystem, -memory, -sequential-thinking, @playwright/mcp)
  5. Install project dependencies (npm ci)
  6. Verify all MCP server installations

💾 Caching & Resilience

Workflows are tuned for fast, reproducible builds and graceful degradation when external registries (npm, GitHub Releases, OS mirrors) experience transient failures.

Caching Strategy — Single Source of Truth

Rule: exactly one cache statement per logical artifact. Never stack actions/cache on top of actions/setup-node's built-in cache for the same path.

Cache Mechanism Path Where Why
npm package cache actions/setup-node@v6.4.0 with cache: "npm" (built-in) ~/.npm All Node-based workflows Official, automatically keyed on package-lock.json + Node major version, automatically pruned. No extra actions/cache step required.
TypeScript build output actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 dist/ test-and-report.yml (build-validation) Reuses prior dist/ output across workflow runs with identical inputs and skips npm run build on cache hit.

Pinned cache action (the only explicit one in the repo):

uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5

Cache Key Design

Property Value Rationale
Version prefix build-v2-… Bumping the prefix atomically expires every old cache entry (cheap rotation / forced invalidation).
Runner OS ${{ runner.os }} Linux/macOS binaries are not interchangeable.
Node major node${{ env.NODE_VERSION }} Conservative runtime-compatibility and policy-driven invalidation signal when the workflow Node major changes.
Lockfile hash ${{ hashFiles('**/package-lock.json') }} Dep changes invalidate dependent caches.
Source hash ${{ hashFiles('src/**/*.ts', 'tsconfig*.json') }} Source or compiler-config change invalidates the build cache.
Restore-keys Cascading prefixes Allows partial reuse when only the source hash changed.
- name: Cache build artifacts
  uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
  with:
    path: dist
    key: build-v2-${{ runner.os }}-node${{ env.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('src/**/*.ts', 'tsconfig*.json') }}
    restore-keys: |
      build-v2-${{ runner.os }}-node${{ env.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}-
      build-v2-${{ runner.os }}-node${{ env.NODE_VERSION }}-

Cache Expiration

  • GitHub-managed eviction — Actions cache entries expire automatically after 7 days of no read access and the repository pool is capped at 10 GB (least-recently-used eviction).
  • Forced invalidation — bump the build-v2- prefix to build-v3- to expire every existing build cache entry on the next run.
  • Lockfile-driven invalidation — every package-lock.json change produces a new key; old entries fall off naturally.

Resilience Against External Registry Failures

Failure Mode Mitigation
npm registry slow / flaky Workflow-level env: NPM_CONFIG_FETCH_RETRIES=5, NPM_CONFIG_FETCH_RETRY_MINTIMEOUT=20000, NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT=120000, NPM_CONFIG_FETCH_TIMEOUT=300000. Native npm honours these on every fetch.
npm install hangs copilot-setup-steps.yml wraps every npm install -g in timeout 300 and a 3-attempt retry with exponential backoff. The local npm ci is wrapped in timeout 600 + 3 attempts.
Playwright / browser binary download fails @playwright/mcp is installed via the resilient retry wrapper; browser binaries are downloaded lazily on first use (no eager npx playwright install at setup time, eliminating a known flaky step).
GitHub Releases asset (sbomqs) download fails curl --fail --retry 5 --retry-delay 5 --retry-max-time 120 --connect-timeout 30 --max-time 180.
OS package mirror (apt) failure No apt installs are required by the current pipeline. Any future apt step must use sudo apt-get update -o Acquire::Retries=5 && sudo apt-get install -y --no-install-recommends … per the resilience policy below.
Concurrent runs piling up knip.yml uses concurrency.cancel-in-progress per ref; recommended for any new fast-feedback workflow.

Resilience Policy for Future External Tooling

Whenever a workflow downloads or installs anything from an external host:

  1. Bound the operation — wrap with timeout <seconds> so a hung process cannot occupy the runner.
  2. Retry on failure — at least 3 attempts with exponential backoff (e.g. sleep $((attempt * 10))).
  3. Use registry-native retry knobs when available (NPM_CONFIG_FETCH_RETRIES, curl --retry, apt -o Acquire::Retries).
  4. Pin to a SHA / version (no floating tags).
  5. Document the install in WORKFLOWS.md so reviewers can audit the supply-chain entry point.

What Was Removed (December 2025 Hardening)

  • Removed 6 redundant actions/cache blocks for ~/.npm from release.yml (×3) and test-and-report.yml (×3). They duplicated actions/setup-node's built-in npm cache and could cause cache-restore races / wasted storage.
  • Replaced npm install with npm ci in test-and-report.yml's prepare and unit-tests jobs (lockfile-faithful, deterministic).
  • Hardened the sbomqs download with explicit curl retries / timeouts.
  • Added workflow-level npm fetch-retry env to every Node workflow.
  • Added retry + timeout wrappers around all global MCP server installs in copilot-setup-steps.yml.

🔒 Security Controls

Defense-in-Depth Layers

graph LR
    subgraph "Layer 1: Runner Hardening"
        H1["🔒 step-security/harden-runner<br>Egress audit mode"]
    end
    subgraph "Layer 2: Action Pinning"
        H2["📌 SHA256-pinned actions<br>No mutable tag references"]
    end
    subgraph "Layer 3: Least Privilege"
        H3["🔑 Scoped permissions<br>read-all default"]
    end
    subgraph "Layer 4: Secret Management"
        H4["🔐 GitHub OIDC<br>No long-lived tokens"]
    end
    subgraph "Layer 5: Audit Trail"
        H5["📊 Egress monitoring<br>Step Security dashboard"]
    end

    H1 --> H2 --> H3 --> H4 --> H5

    style H1 fill:#e74c3c,stroke:#c0392b,color:#fff
    style H2 fill:#e67e22,stroke:#d35400,color:#fff
    style H3 fill:#f1c40f,stroke:#d4ac0f,color:#333
    style H4 fill:#2ecc71,stroke:#27ae60,color:#fff
    style H5 fill:#3498db,stroke:#2980b9,color:#fff
Loading

Security Controls Matrix

Control Implementation Workflows Applied Evidence
Runner Hardening step-security/harden-runner with egress audit All 11 workflows Egress audit logs
Action Pinning All actions pinned to full SHA256 commit hash All 11 workflows No @v* tag references
Least Privilege permissions: read-all default, scoped per job All 11 workflows Workflow YAML audit
OIDC Authentication GitHub OIDC for npm publish (no stored tokens) release.yml, slsa-provenance.yml id-token: write
Secret Scoping Secrets scoped to specific jobs/environments release.yml, integration-tests.yml Job-level secret access
Egress Monitoring Outbound connection tracking and alerting All 11 workflows Step Security dashboard
SARIF Upload Security findings uploaded to GitHub Security tab codeql.yml, scorecard.yml Code scanning alerts
Attestation Signing Sigstore-backed artifact attestations release.yml, slsa-provenance.yml gh attestation verify

Secrets Inventory

Secret Used In Purpose Rotation
NPM_TOKEN release.yml, slsa-provenance.yml npm registry publish On rotation schedule
CODECOV_TOKEN integration-tests.yml Coverage upload Auto-managed
GITHUB_TOKEN All workflows Repository access (auto-generated) Per-workflow run

📊 Quality Gates

Pre-Merge Quality Gates (PR)

# Gate Tool Threshold Required Workflow
1 TypeScript compilation tsc --noEmit 0 errors ✅ Yes test-and-report.yml
2 Linting ESLint 10.x 0 errors, 0 warnings ✅ Yes test-and-report.yml
3 Unused code detection Knip 0 unused exports ✅ Yes knip.yml (dedicated), test-and-report.yml (build-validation)
4 Unit tests Vitest All tests pass ✅ Yes test-and-report.yml
5 Code coverage Vitest coverage (v8) ≥80% lines ⚠️ Warning test-and-report.yml
6 License compliance license-checker MIT, Apache-2.0, BSD, ISC only ✅ Yes test-and-report.yml
7 SBOM quality SBOMQS ≥7.0/10 ✅ Yes test-and-report.yml
8 Security analysis CodeQL No high/critical findings ✅ Yes codeql.yml
9 Dependency review GitHub Dependency Review No known vulnerabilities ✅ Yes dependency-review.yml
10 Integration tests Vitest (E2E) All tests pass ✅ Yes integration-tests.yml
11 npm audit npm audit No moderate+ vulnerabilities ✅ Yes integration-tests.yml

Post-Merge / Release Quality Checks

# Check Frequency Tool Target
1 OpenSSF Scorecard Weekly ossf/scorecard-action ≥8.0/10
2 SLSA Provenance Per release slsa-framework/slsa-github-generator Level 3
3 SBOM Generation Per release Syft (Anchore) Quality ≥7.0
4 Vulnerability Scan Per release Grype No critical CVEs
5 Attestation Verification Per release gh attestation verify All pass

🛡️ ISMS Compliance

ISO 27001:2022 Controls

Control Requirement Workflow Implementation Evidence
A.8.9 Configuration Management setup-labels.yml — standardized repository configuration Label inventory, labeler config
A.8.25 Secure Development Lifecycle test-and-report.yml — automated build, lint, test pipeline Test reports, coverage data
A.8.26 Application Security Requirements codeql.yml — SAST scanning with CWE coverage SARIF reports, security alerts
A.8.27 Secure System Architecture dependency-review.yml — dependency vulnerability scanning PR review comments
A.8.28 Secure Coding test-and-report.yml + knip.yml — ESLint, type checking, Knip unused-code detection Lint reports, Knip job summaries, build logs
A.8.31 Separation of Development, Test, Production release.yml — tagged releases with provenance Release artifacts, npm provenance
A.8.33 Test Information integration-tests.yml — comprehensive test suite (unit, integration, E2E) Test reports, coverage data
A.14.2.8 System Security Testing codeql.yml + scorecard.yml — weekly security scans SARIF, Scorecard results

NIST CSF 2.0 Mapping

Function Category Subcategory Workflow Implementation
GOVERN (GV) GV.SC Supply Chain Risk Management scorecard.yml, dependency-review.yml — supply chain monitoring
IDENTIFY (ID) ID.AM-2 Software Inventory test-and-report.yml, release.yml — SPDX JSON SBOM generation with SBOMQS quality gate
PROTECT (PR) PR.DS-6 Integrity Checking slsa-provenance.yml — SLSA Level 3 build provenance
PROTECT (PR) PR.DS-1 Data-at-Rest Protection release.yml — signed artifacts with attestations
DETECT (DE) DE.CM-8 Vulnerability Scanning codeql.yml — weekly SAST, dependency-review.yml — PR dep scan
RESPOND (RS) RS.AN-5 Processes Established All workflows — automated CI/CD pipeline with quality gates

CIS Controls v8.1 Mapping

Control Safeguard Workflow Implementation Measurement
2.1 Establish Software Inventory test-and-report.yml, release.yml — SPDX JSON SBOM with SBOMQS scoring and attestation SBOM quality score ≥7.0
2.2 Ensure Authorized Software dependency-review.yml — license + vulnerability check Blocked PRs with violations
4.1 Establish Secure Configuration test-and-report.yml — ESLint security rules, type checking Zero lint errors
7.1 Establish Vulnerability Management codeql.yml + scorecard.yml — continuous scanning SARIF findings, Scorecard ≥8.0
16.1 Establish Application Security Process All CI workflows — automated DevSecOps pipeline Pipeline pass rate
16.6 Use Standard Security Features slsa-provenance.yml — Sigstore signing, attestations SLSA Level 3 verified
16.12 Implement Code-Level Security Checks codeql.yml — SAST with CWE coverage Zero high/critical findings

🔗 Related Documentation

Document Description Link
Future Workflows CI/CD pipeline evolution roadmap FUTURE_WORKFLOWS.md
Architecture C4 system architecture and design ARCHITECTURE.md
Security Architecture Security controls and defense-in-depth SECURITY_ARCHITECTURE.md
Threat Model STRIDE-based threat analysis THREAT_MODEL.md
CRA Assessment EU Cyber Resilience Act conformity CRA-ASSESSMENT.md
Developer Guide Local development setup and testing DEVELOPER_GUIDE.md
Local Testing Running tests locally LOCAL_TESTING.md
Integration Testing Integration test documentation INTEGRATION_TESTING.md
Performance Guide Performance optimization and benchmarks PERFORMANCE_GUIDE.md
Secure Development Policy ISMS development guidelines Secure_Development_Policy.md
Open Source Policy ISMS open source governance Open_Source_Policy.md
Documentation Portal Generated API docs, coverage, test reports hack23.github.io

Built with ❤️ by Hack23 AB
CI/CD pipeline documentation for European Parliament MCP Server v0.6.2 — aligned with ISO 27001, NIST CSF 2.0, and CIS Controls v8.1