Skip to content

Latest commit

 

History

History
3832 lines (2907 loc) · 159 KB

File metadata and controls

3832 lines (2907 loc) · 159 KB

Hack23 Logo

🛡️ EU Parliament Monitor — Security Architecture

🔐 Security-by-Design for European Parliament Intelligence
🎯 Comprehensive Security Framework for Multi-Language News Platform

Owner Version Effective Date Review Cycle OpenSSF Best Practices

📋 Document Owner: CEO | 📄 Version: 2.1 | 📅 Last Updated: 2026-04-20 (UTC)
🔄 Review Cycle: Annual | ⏰ Next Review: 2027-04-20
🏷️ Classification: Public (Open Source European Parliament Monitoring Platform)


📚 Architecture Documentation Map

Document Focus Description Documentation Link
Architecture 🏛️ Architecture C4 model showing current system structure View Source
Future Architecture 🏛️ Architecture C4 model showing future system structure View Source
Mindmaps 🧠 Concept Current system component relationships View Source
Future Mindmaps 🧠 Concept Future capability evolution View Source
SWOT Analysis 💼 Business Current strategic assessment View Source
Future SWOT Analysis 💼 Business Future strategic opportunities View Source
Data Model 📊 Data Current data structures and relationships View Source
Future Data Model 📊 Data Enhanced European Parliament data architecture View Source
Flowcharts 🔄 Process Current data processing workflows View Source
Future Flowcharts 🔄 Process Enhanced AI-driven workflows View Source
State Diagrams 🔄 Behavior Current system state transitions View Source
Future State Diagrams 🔄 Behavior Enhanced adaptive state transitions View Source
Security Architecture 🛡️ Security Current security implementation View Source
Future Security Architecture 🛡️ Security Security enhancement roadmap View Source
Threat Model 🎯 Security STRIDE threat analysis View Source
Classification 🏷️ Governance CIA classification & BCP View Source
CRA Assessment 🛡️ Compliance Cyber Resilience Act View Source
Workflows ⚙️ DevOps CI/CD documentation View Source
Future Workflows 🚀 DevOps Planned CI/CD enhancements View Source
Business Continuity Plan 🔄 Resilience Recovery planning View Source
Financial Security Plan 💰 Financial Cost & security analysis View Source
End-of-Life Strategy 📦 Lifecycle Technology EOL planning View Source
Unit Test Plan 🧪 Testing Unit testing strategy View Source
E2E Test Plan 🔍 Testing End-to-end testing View Source
Performance Testing ⚡ Performance Performance benchmarks View Source
Security Policy 🔒 Security Vulnerability reporting & security policy View Source

🎯 Executive Summary

EU Parliament Monitor is a static website generator that creates multi-language news articles about European Parliament activities. The system operates as an automated intelligence platform, generating news content through GitHub Actions workflows with minimal attack surface and public data transparency.

System Purpose

EU Parliament Monitor v0.8.40+ (post-2026-04-24 aggregator migration) publishes 1927 static HTML articles across 14 languages and 8 article types (breaking, week-ahead, week-in-review, month-ahead, month-in-review, committee-reports, motions, propositions), generated by 9 unified gh-aw agentic workflows (8 news-<type>.md article workflows + news-translate.md for 14-language flush translation). Article HTML is rendered deterministically by src/aggregator/** from committed Stage-B analysis artifacts (analysis/daily/<date>/<slug>-run<NN>/) — there is no AI-authored HTML step. The posture is validated by 3061+ automated tests across the test suite. Primary delivery is AWS S3 + CloudFront via OIDC federation; GitHub Pages remains the documented fallback. Release artifacts are signed with npm provenance and SLSA Level 3 build attestations. OpenSSF Scorecard + OpenSSF Best Practices #12068 certify the posture.

🔐 Security Posture Change: Aggregator Migration (April 2026)

The April-2026 aggregator migration eliminated an entire class of agent-prose-injection defects at the root by removing the AI-authored HTML step. Template-prose leaks of the form that produced the 2026-04-20-motions-run46-en.html regression are no longer possible because there is no template-prose layer — the aggregator reads committed markdown artifacts verbatim through markdown-it + the sanitiser in src/utils/html-sanitize.ts. Residual risks have shifted:

  • Malicious markdown in a committed artifact — mitigated by src/aggregator/clean-artifact.ts (front-matter strip, heading demote, ReDoS-safe relative-link rewrite, FNV-1a-hashed mermaid dedup) + src/utils/html-sanitize.ts (allowlist-based HTML sanitisation) + markdown-it's secure defaults (raw HTML disabled)
  • Mermaid XSS via committed diagram — mitigated by the markdown-it mermaid-fence override that emits <figure> wrappers only (diagram rendering is client-side via vendored mermaid.esm.min.mjs loaded with script-src 'self')
  • Purged validatorssrc/utils/content-validator.ts, src/utils/validate-articles.ts, src/utils/validate-analysis-completeness.ts, the FALLBACK_TEMPLATE_PATTERNS scanner, the Wave-2 OR-gate and Wave-3/Wave-4 strict IMF runtime gates. Enforcement moved to Stage-C agent-side review — this is a defence-in-depth reduction that is safe because the root cause (AI-authored HTML) was removed in the same commit. Future regressions would need to surface as editorial quality gaps in the committed artifacts, which are reviewable in the analysis PR.

The platform automatically generates and publishes news articles covering:

  • Breaking News: Rapid-response coverage of urgent parliamentary developments
  • Week Ahead: Preview of upcoming parliamentary events
  • Week In Review: Analysis of the previous week's activities
  • Month Ahead: Preview of upcoming monthly parliamentary events
  • Month In Review: Analysis of the previous month's activities
  • Committee Reports: Analysis of committee activities
  • Propositions: Legislative proposals analysis
  • Motions: Parliamentary motions analysis

Security Classification

Per Hack23 ISMS Classification Framework:

Dimension Level Rationale
Confidentiality Public (Level 1) All data from European Parliament open data sources, no private information
Integrity Medium (Level 2) News accuracy critical for democratic transparency, incorrect information could mislead public
Availability Medium (Level 2) Daily updates expected, but 24-hour outages acceptable
RTO 24 hours Manual workflow trigger available, automated recovery via GitHub Actions
RPO 1 day Daily generation schedule, previous day's content acceptable

Security Posture Overview

Defense Strategy: Defense-in-depth with minimal attack surface

  • Static Content: No server-side execution, no databases
  • GitHub-Hosted: GitHub Pages infrastructure security
  • Minimal Dependencies: 28 devDependencies, 1 production dependency (european-parliament-mcp-server), automated updates
  • Automated Security: CodeQL, Dependabot, SonarCloud, npm audit
  • Supply Chain Security: SHA-pinned GitHub Actions, SBOM generation, SLSA Level 3 provenance
  • Workflow Hardening: StepSecurity harden-runner, OpenSSF Scorecard
  • Ephemeral Execution: GitHub-hosted runners, no persistent infrastructure

Compliance Status

Framework Status Evidence
ISO 27001 ✅ Compliant Architecture documentation, access control, vulnerability management
GDPR ✅ Compliant No PII collected, data protection by design
NIS2 ✅ Compliant Static site architecture, minimal attack surface, incident response
EU CRA ✅ Aligned SBOM generation, vulnerability disclosure, security updates

🧱 gh-aw 5-Layer Security Model

The EU Parliament Monitor implements GitHub Agentic Workflows (gh-aw) with a comprehensive 5-layer defense-in-depth security model. This architecture ensures that AI-driven news generation operates within strict security boundaries while maintaining deterministic, auditable, and tamper-evident execution.

Layer 1: AWF Squid Egress Firewall

Purpose: Default-deny network access with allowlist-only egress control.

Implementation: Squid proxy enforces allowlist for all outbound network traffic from agentic workflow containers:

Allowed Endpoints:

  • GitHub API: api.github.com, github.com (workflow control, PR creation)
  • npm Registry: registry.npmjs.org (dependency installation)
  • European Parliament MCP Gateway: host.docker.internal:80/mcp/european-parliament (Docker bridge, local-only)
  • World Bank MCP: World Bank data integration
  • IMF Data Services: dataservices.imf.org/REST/SDMX_3.0/ (economic context data)
  • LLM APIs: Copilot API, Claude API, Codex API (AI inference)

Default Behavior: All other outbound connections are blocked (default-deny).

Security Benefits:

  • Prevents data exfiltration
  • Blocks command-and-control channels
  • Mitigates supply chain compromise (no arbitrary package downloads)
  • Enforces principle of least privilege at network layer

Layer 2: Sandboxed Docker Runner

Purpose: Restricted shell execution environment with pattern-based exploit prevention.

Security Controls:

  1. Blocked Shell Patterns (prompt injection defense):

    • ❌ Nested $() inside $(( )) arithmetic expansion
    • ${VAR:-$(cmd)} default-with-fallback command substitution
    • ❌ Complex variable indirection chains
  2. Schema-Enforced Tool Calls:

    • Every bash tool invocation requires explicit command + description fields
    • Tool schema validation prevents obfuscated command injection
    • TypeScript type safety enforced at compile time
  3. Container Isolation:

    • Read-only file system for system directories
    • No privileged escalation (--cap-drop=ALL)
    • Resource limits (CPU, memory) enforced by Docker

ISMS Alignment: Secure Development Policy § Shell Security

Layer 3: Safe-Outputs Constraints

Purpose: Limit blast radius of AI-generated content changes through size and review controls.

Implementation:

  • create-pull-request Safe-Output Limits:

    • Default max patch size: 1024 KB (enforced for most workflows)
    • Extended limit for news-translate.md: 10240 KB (14-language fan-out requires larger patches)
    • Single PR per workflow run (enforced by gh-aw framework)
  • Mandatory Review Workflow:

    • All AI-generated PRs require human review before merge
    • Branch protection rules enforce status checks + approvals
    • No auto-merge allowed for content changes

Security Benefits:

  • Prevents repository flooding attacks (size-bounded patches)
  • Ensures human-in-the-loop oversight for AI-generated content
  • Traceable approval chain for all changes

Layer 4: JSONL Audit Trail

Purpose: Immutable forensic trail of all tool invocations for post-incident analysis.

Implementation:

  • Log Format: JSON Lines (JSONL) — one tool call per line
  • Log File: agent-stdio.log in workflow run artifacts
  • Retention: Retained as GitHub Actions workflow artifacts (90-day default retention)

Logged Data:

  • Timestamp (ISO 8601)
  • Tool name + parameters
  • Input data (sanitized)
  • Output/response (truncated if >10KB)
  • Execution duration
  • Exit code/status

Use Cases:

  • Security incident investigation
  • Compliance auditing (ISMS § Audit & Logging)
  • Workflow debugging and optimization
  • Anomaly detection (baseline deviation)

Layer 5: Lock-File Compilation

Purpose: Deterministic, tamper-evident workflow execution with version-pinned toolchain.

Implementation:

  1. gh aw compile --validate (pinned to v0.69.0):

    • Enforced by .github/workflows/compile-agentic-workflows.yml
    • Any version drift = CI failure
    • Version mismatch blocks PR merge
  2. Workflow Source Control:

    • Source: .github/workflows/*.md (human-readable, version-controlled)
    • Artifact: .github/workflows/*.lock.yml (deterministic, compiled)
    • Compilation is reproducible (same input = same output)
  3. Branch Protection:

    • Direct edits to .lock.yml files blocked by CODEOWNERS
    • Changes to .md sources trigger recompilation via CI
    • Recompiled .lock.yml must match expected SHA-256 hash

Security Benefits:

  • Prevents workflow tampering (lock files are deterministic)
  • Ensures toolchain integrity (pinned gh-aw version)
  • Branch protection enforces review-before-merge
  • Audit trail for all workflow changes (Git history)

ISMS Alignment: Secure Development Policy § Change Management

5-Layer Security Model Diagram

graph TB
    subgraph "Layer 5: Lock-File Compilation"
        MD[.md Workflow Source]
        COMPILE[gh aw compile v0.69.0]
        LOCK[.lock.yml Artifact]
        MD --> COMPILE
        COMPILE --> LOCK
    end

    subgraph "Layer 4: JSONL Audit Trail"
        LOG[agent-stdio.log]
        ARTIFACT[Workflow Artifacts<br/>90-day Retention]
        LOG --> ARTIFACT
    end

    subgraph "Layer 3: Safe-Outputs"
        PR[create-pull-request]
        SIZE[max-patch-size: 1024 KB]
        REVIEW[Mandatory Human Review]
        PR --> SIZE
        SIZE --> REVIEW
    end

    subgraph "Layer 2: Sandboxed Runner"
        DOCKER[Docker Container]
        SHELL[Restricted Shell]
        PATTERN[Blocked Patterns]
        DOCKER --> SHELL
        SHELL --> PATTERN
    end

    subgraph "Layer 1: AWF Firewall"
        SQUID[Squid Proxy]
        ALLOWLIST[Endpoint Allowlist]
        DENY[Default Deny]
        SQUID --> ALLOWLIST
        ALLOWLIST --> DENY
    end

    subgraph "Agentic Workflow Execution"
        RUN[Workflow Run]
    end

    LOCK --> RUN
    RUN --> LOG
    RUN --> PR
    RUN --> DOCKER
    RUN --> SQUID

    style LOCK fill:#e8f5e9
    style LOG fill:#e1f5ff
    style PR fill:#ffe1e1
    style DOCKER fill:#fff4e1
    style SQUID fill:#ffe1e1
    style RUN fill:#f0f0f0
Loading

Defense-in-Depth Principle: Each layer provides independent security controls. Compromise of any single layer does not bypass the entire security model.

ISMS Compliance:

  • ISO 27001 Annex A.8.31 (Separation of development, testing, and production environments)
  • NIST CSF 2.0 PR.AC-4 (Access permissions managed, incorporating least privilege)
  • CIS Controls v8.1 Control 4.1 (Establish and maintain a secure configuration process)

🔌 MCP Gateway Security

The EU Parliament Monitor integrates with Model Context Protocol (MCP) servers to access European Parliament data, economic context (World Bank, IMF), and other external data sources. MCP gateway security ensures secure, resilient, and tamper-evident data access with drift-proofing controls.

European Parliament MCP

Endpoint: EP_MCP_GATEWAY_URL=http://host.docker.internal:80/mcp/european-parliament

Communication Model:

  • Protocol: Local stdio JSON-RPC over Docker bridge network
  • Trust Boundary: Docker bridge itself provides isolation (container-to-container communication)
  • Transport Security: No TLS required — traffic never leaves the Docker host
  • Authentication: Tokens extracted via scripts/mcp-setup.sh (no jq dependency)
  • Client Library: src/mcp/ep-mcp-client.ts (compiled to scripts/mcp/ep-mcp-client.js)
    • Reads EP_MCP_GATEWAY_URL and auth environment variables at runtime
    • Type-safe TypeScript interfaces for all MCP tool schemas

Security Considerations:

  • Docker Bridge Isolation: Traffic confined to Docker internal network (host.docker.internal)
  • Ephemeral Credentials: Auth tokens are workflow-scoped, expire after job completion
  • No External Exposure: MCP gateway never exposed to public internet
  • Input Validation: All MCP responses validated against TypeScript schemas before use

IMF Data Services

Endpoint: https://dataservices.imf.org/REST/SDMX_3.0/

Communication Model:

  • Protocol: HTTPS (native fetch API)
  • Transport Security: TLS 1.2+ / 1.3 enforced (Node.js 25 default)
  • Authentication: Public API, no credentials required
  • Request Timeout: Per-request AbortController timeout enforced via IMF_API_TIMEOUT_MS environment variable (default 30 000 ms)

Security Controls:

  • Certificate Validation: Node.js built-in TLS certificate chain validation
  • HTTPS-Only: IMF requests target the fixed https://dataservices.imf.org/REST/SDMX_3.0/ base URL (configurable via IMF_API_BASE_URL)
  • Failure Handling: Network failures, non-2xx responses, and timeouts return an empty fallback payload (not cached/sample data) so downstream content falls back to the OR-gate (when WAVE3_IMF_STRICT=false) or fails Stage-C (when strict mode is on)
  • Verification: Integration tests in test/integration/mcp/imf-mcp.test.js exercise the client with an injected fetchImpl to cover success and failure paths

World Bank MCP

Endpoint: Configured via worldbank-mcp@1.0.1 npm package

Communication Model:

  • Protocol: MCP stdio (same model as EP MCP)
  • Transport Security: Local-only, no network transit
  • Authentication: None required (public World Bank API)
  • Client Library: World Bank MCP client integrated via .github/copilot-mcp.json

Security Controls:

  • Package Integrity: npm provenance verification (SLSA L3)
  • Version Pinning: Exact version lock in package-lock.json
  • Vulnerability Scanning: Dependabot monitors worldbank-mcp for CVEs
  • Input Validation: World Bank API responses validated before use

Drift-Proofing Controls

Purpose: Detect upstream MCP tool schema changes that could break workflows.

Implementation:

  1. Canonical Tool Lists (exported from the MCP client modules):

    • IMF_MCP_TOOLS in src/mcp/imf-mcp-client.ts — expected IMF economic data tools
    • WORLD_BANK_MCP_TOOLS in src/mcp/worldbank-mcp-client.ts — expected World Bank data tools
    • (No canonical EP_MCP_TOOLS export exists yet in src/mcp/ep-mcp-client.ts; see CRA-ASSESSMENT.md §5ᵇ gap table row 13.)
  2. Integration Tests:

    • test/integration/mcp/imf-mcp.test.js asserts the expected IMF tool list matches IMF_MCP_TOOLS
    • test/integration/mcp/worldbank-mcp.test.js asserts the expected World Bank tool list matches WORLD_BANK_MCP_TOOLS
    • Any upstream tool rename, addition, or removal for IMF/WB = test failure
    • Blocks PR merge until drift is reviewed and the canonical lists are updated
    • EP MCP coverage is provided by test/integration/mcp-integration.test.js (contract suite), pending a dedicated EP_MCP_TOOLS drift guard
  3. Semantic Versioning Enforcement:

    • Breaking changes to MCP server require major version bump
    • CI/CD fails if MCP server version doesn't match expected semver range
    • Manual review required for major version upgrades

Drift Detection Benefits:

  • Early Warning: Detect breaking changes before production deployment
  • Change Approval: Enforce review for upstream schema changes
  • Audit Trail: Git history tracks when and why tool lists changed

Economic Context Gate (Wave-3 IMF-primary + Wave-2 OR-gate fallback)

Purpose: IMF as primary economic source under Wave-3 editorial policy with World Bank retained for non-economic resilience and pre-Wave-2 article back-compat.

Implementation:

  • Wave-3 strict (dark-launched) (articlePolicyHasIMFEconomicEvidence):

    • IMF SDMX 3.0 evidence required for every economic claim
    • Activated by WAVE3_IMF_STRICT=true environment variable (parsed by isWave3IMFStrictEnabled)
    • Will become the default in Wave-4
  • Wave-2 OR-gate (default) (articlePolicyHasEconomicContext):

    • Accepts World Bank OR IMF evidence
    • Pre-Wave-2 articles citing only World Bank remain green
    • The default validator path until Wave-4 flips the strict gate on
  • Legacy soft-check (articlePolicyHasWorldBank):

    • Retained as a non-breaking helper for diagnostic reporting and historical tests
    • No longer the primary validator gate

Resilience Benefits:

  • Editorial discipline: Wave-3 mandates IMF as the single authoritative economic source — eliminates ambiguity over which dataset takes precedence
  • Graceful degradation: When WAVE3_IMF_STRICT is false (default), workflows still succeed on WB-only evidence for back-compat
  • Diverse sources for non-economic context: WB retained for health, education, social, environment, demographics, defence, agriculture, innovation, governance — IMF does not cover these

MCP Configuration Management

Configuration File: .github/copilot-mcp.json

Purpose: Centralized registry of all MCP servers used by the project.

Change Management:

  • Classification: Changes to .github/copilot-mcp.json are Normal Changes under ISMS Change Management Policy
  • Review Required: All MCP server additions/removals require PR review
  • Validation: CI tests verify MCP server availability after configuration changes
  • Rollback: Git history allows instant rollback to previous working config

Example Configuration:

{
  "mcpServers": {
    "european-parliament": {
      "command": "npx",
      "args": ["-y", "european-parliament-mcp-server@1.2.15"],
      "env": {
        "EP_MCP_GATEWAY_URL": "http://host.docker.internal:80/mcp/european-parliament"
      }
    },
    "worldbank": {
      "command": "npx",
      "args": ["-y", "worldbank-mcp@1.0.1"]
    }
  }
}

ISMS Alignment:

Related Documents

Document Focus Link
🔐 Security Architecture Current State This document
🚀 Future Security Architecture Roadmap FUTURE_SECURITY_ARCHITECTURE.md
⚙️ CI/CD Workflows Current workflows WORKFLOWS.md
🚀 Future Workflows Planned enhancements FUTURE_WORKFLOWS.md
📊 Data Model Data Structures DATA_MODEL.md
📈 Security Flow Process Flows FLOWCHART.md
📚 Documentation Hub Release documentation docs/README.md
📋 Release Process Release procedures docs/RELEASE_PROCESS.md
🎯 Threat Model Risk Analysis #-threat-model
🛡️ ISMS Secure Development Policy Framework ISMS-PUBLIC

📑 Table of Contents


🔐 ISMS Policy Alignment

This security architecture implements controls aligned with Hack23 AB's publicly available ISMS framework. For complete policy mapping, see the Hack23 ISMS-PUBLIC repository.

Related ISMS Policies

Policy Domain Policy Relevance to Architecture
🔐 Core Security Information Security Policy Overall security governance and framework
🛠️ Development Secure Development Policy Security-integrated SDLC practices, CodeQL SAST scanning
🌐 Network Network Security Policy GitHub Pages CDN security, HTTPS enforcement
🔒 Cryptography Cryptography Policy TLS 1.3, HTTPS-only, Content Security Policy
🔍 Vulnerability Vulnerability Management Dependabot, CodeQL, npm audit, weekly scans
🚨 Incident Response Incident Response Plan GitHub Security Advisories, coordinated disclosure
🤝 Third-Party Third Party Management GitHub ecosystem assessment (GitHub Pages, Actions, npm)
🔓 Open Source Open Source Policy Apache-2.0 licensing, REUSE compliance, SBOM generation
📋 Compliance Compliance Checklist ISO 27001, NIST CSF, CIS Controls alignment
🏷️ Classification Classification Framework Public data classification (Level 1 confidentiality)
🇪🇺 CRA Compliance CRA Conformity Assessment Process CRA-ASSESSMENT.md self-assessment

Security Control Implementation Status

ISMS Control Domain Implementation Status Notes
🔑 Access Control ✅ Implemented GitHub CODEOWNERS, branch protection, required reviews
🔒 Cryptography ✅ Implemented TLS 1.3, HTTPS-only, HSTS
🌐 Network Security ✅ Implemented GitHub Pages CDN, DDoS protection, edge caching
🛠️ Secure Development ✅ Implemented CodeQL SAST, ESLint, TypeScript, Prettier, pre-commit hooks
🔍 Vulnerability Management ✅ Implemented Dependabot (weekly), CodeQL (push/PR), npm audit
📊 Monitoring & Logging ⚠️ Limited GitHub Actions logs, CDN access logs (no backend logging)
💾 Data Protection ✅ Implemented No persistent storage, ephemeral build environment
🚨 Incident Response ✅ Documented SECURITY.md, GitHub Security Advisories, 90-day disclosure

🏗️ System Context (C4 Level 1)

The EU Parliament Monitor operates as a static content generation platform within the GitHub ecosystem, interfacing with the European Parliament MCP Server for data access.

graph TB
    subgraph "External Actors"
        User[👥 EU Citizens & Researchers]
        EP_API[🏛️ European Parliament<br/>Open Data API]
    end

    subgraph "GitHub Infrastructure"
        GHA[⚙️ GitHub Actions<br/>Automated Workflows]
        GHP[🌐 GitHub Pages<br/>Static Hosting]
        GH_SECURITY[🔒 GitHub Security<br/>CodeQL, Dependabot, Secrets]
    end

    subgraph "EU Parliament Monitor"
        EuPM[📰 EU Parliament Monitor<br/>Static Website Generator]
        EPMCP[🔌 European Parliament<br/>MCP Server Client]
    end

    User -->|Browse News<br/>HTTPS| GHP
    GHP -->|Serve Static<br/>HTML/CSS| User

    GHA -->|Trigger Scheduled<br/>Weekday Crons| EuPM
    GHA -->|Monitor Security| GH_SECURITY

    EuPM -->|Connect via<br/>stdio/localhost| EPMCP
    EPMCP -->|Query Parliamentary<br/>Data| EP_API
    EP_API -->|Return JSON<br/>Public Data| EPMCP

    EuPM -->|Generate<br/>Articles| GHP
    GH_SECURITY -->|Scan Code<br/>Dependencies| EuPM

    style User fill:#e1f5ff
    style EP_API fill:#fff4e1
    style GHA fill:#f0f0f0
    style GHP fill:#f0f0f0
    style GH_SECURITY fill:#ffe1e1
    style EuPM fill:#e8f5e9
    style EPMCP fill:#e8f5e9
Loading

Trust Boundaries

8 Trust Boundaries enforce security zones:

  1. Citizen/Reader ↔ CloudFront: HTTPS (TLS 1.2+/1.3)
  2. CloudFront ↔ S3 Origin: OAC (Origin Access Control), versioned bucket, private S3
  3. GH Actions Runner ↔ AWF Firewall ↔ Internet: Squid egress allowlist (Layer 1)
  4. gh-aw Container ↔ MCP Gateway: Docker bridge (local-only, no TLS required)
  5. gh-aw Container ↔ LLM API: HTTPS to Copilot/Claude/Codex APIs
  6. Maintainer ↔ GitHub Repo: 2FA, signed commits, required reviews, branch protection
  7. Release Pipeline ↔ npm Registry: OIDC provenance (SLSA L3)
  8. Release Pipeline ↔ AWS: OIDC federation (no long-lived keys)

Data Flow

flowchart LR
    subgraph "Data Sources"
        EP[European Parliament<br/>Open Data API]
    end

    subgraph "Processing"
        MCP[MCP Server]
        GEN[News Generator]
        VAL[HTML Validator]
    end

    subgraph "Storage & Delivery"
        GIT[Git Repository]
        PAGES[GitHub Pages]
    end

    subgraph "Consumers"
        USERS[End Users]
    end

    EP -->|Public JSON| MCP
    MCP -->|Structured Data| GEN
    GEN -->|HTML Articles| VAL
    VAL -->|Validated HTML| GIT
    GIT -->|Deploy| PAGES
    PAGES -->|HTTPS| USERS

    style EP fill:#fff4e1
    style MCP fill:#e8f5e9
    style GEN fill:#e8f5e9
    style VAL fill:#e1f5ff
    style GIT fill:#f0f0f0
    style PAGES fill:#f0f0f0
    style USERS fill:#e1f5ff
Loading

📦 Container Architecture (C4 Level 2)

The system consists of stateless containers executing in GitHub Actions with no persistent infrastructure.

graph TB
    subgraph "GitHub Actions Runner (Ubuntu Latest)"
        subgraph "News Generation Container"
            CLI[📝 generate-news-enhanced.ts<br/>TypeScript CLI Script]
            TEMPLATE[🎨 article-template.ts<br/>HTML Generator]
            CLIENT[🔌 ep-mcp-client.ts<br/>MCP Client Library]
        end

        subgraph "Index Generation Container"
            IDX[📋 generate-news-indexes.ts<br/>Index Generator]
        end

        subgraph "Sitemap Generation Container"
            SITE[🗺️ generate-sitemap.ts<br/>Sitemap Generator]
        end

        subgraph "European Parliament MCP Server"
            MCP[🏛️ MCP Server Process<br/>stdio Communication]
        end

        subgraph "Validation Container"
            HTML[✅ htmlhint<br/>HTML Validator]
            LINT[🔍 ESLint<br/>Code Quality]
            TEST[🧪 Vitest<br/>Test Suite]
        end
    end

    subgraph "GitHub Infrastructure"
        REPO[📚 Git Repository<br/>news/, *.html, sitemap.xml]
        PAGES[🌐 GitHub Pages<br/>Static Hosting]
        SECRETS[🔐 GitHub Secrets<br/>Tokens, Variables]
    end

    subgraph "External Services"
        EP_API[🏛️ European Parliament API<br/>data.europarl.europa.eu]
    end

    CLI -->|Initialize| CLIENT
    CLIENT -->|Spawn Process| MCP
    MCP -->|HTTPS| EP_API
    EP_API -->|JSON Response| MCP
    MCP -->|Structured Data| CLIENT
    CLIENT -->|Parliamentary Data| CLI
    CLI -->|Generate HTML| TEMPLATE
    TEMPLATE -->|Write Files| REPO

    IDX -->|Read Articles| REPO
    IDX -->|Generate Indexes| REPO

    SITE -->|Scan Files| REPO
    SITE -->|Generate sitemap.xml| REPO

    HTML -->|Validate| REPO
    LINT -->|Check Quality| CLI
    TEST -->|Run Tests| CLI

    REPO -->|Deploy| PAGES
    SECRETS -->|Provide Tokens| CLI

    style CLI fill:#e8f5e9
    style TEMPLATE fill:#e8f5e9
    style CLIENT fill:#e8f5e9
    style IDX fill:#e8f5e9
    style SITE fill:#e8f5e9
    style MCP fill:#fff4e1
    style HTML fill:#e1f5ff
    style LINT fill:#e1f5ff
    style TEST fill:#e1f5ff
    style REPO fill:#f0f0f0
    style PAGES fill:#f0f0f0
    style SECRETS fill:#ffe1e1
    style EP_API fill:#fff4e1
Loading

Container Security Characteristics

Container Runtime Privileges Network Access Persistence
News Generation Node.js 25 Read/Write repo Localhost only None (ephemeral)
Index Generation Node.js 25 Read/Write repo None None (ephemeral)
Sitemap Generation Node.js 25 Read/Write repo None None (ephemeral)
MCP Server Node.js 25 Read-only HTTPS to EP API None (ephemeral)
Validation Node.js 25 Read-only None None (ephemeral)

🔧 Component Architecture (C4 Level 3)

Detailed component-level architecture showing internal structure and security boundaries.

graph TB
    subgraph "News Generation Components"
        direction TB
        MAIN[Main CLI<br/>Command Parser]
        LANG[Language Manager<br/>14 Languages]
        TYPE[Article Type Manager<br/>5 Types]

        subgraph "MCP Client Components"
            CONN[Connection Manager<br/>Retry Logic]
            REQ[Request Handler<br/>JSON-RPC 2.0]
            RESP[Response Parser<br/>Data Validator]
        end

        subgraph "Template Components"
            META[Metadata Generator<br/>SEO, Schema.org]
            HTML[HTML Builder<br/>Sanitization]
            CSS[Style Injector<br/>Inline CSS]
        end

        subgraph "Fallback Components"
            CACHE[Content Cache<br/>Placeholder Data]
            ERR[Error Handler<br/>Graceful Degradation]
        end
    end

    subgraph "Validation Components"
        HTMLV[HTML Validator<br/>htmlhint rules]
        JSDOC[JSDoc Checker<br/>Documentation]
        SECUR[Security Scanner<br/>eslint-plugin-security]
    end

    subgraph "Index Components"
        SCAN[Article Scanner<br/>File Discovery]
        PARSE[Metadata Parser<br/>Extract Info]
        INDEX[Index Generator<br/>Multi-language]
    end

    subgraph "Sitemap Components"
        CRAWLER[File Crawler<br/>Recursive Scan]
        URL[URL Builder<br/>Canonical URLs]
        XML[XML Generator<br/>Sitemap Protocol]
    end

    MAIN --> LANG
    MAIN --> TYPE
    LANG --> CONN
    TYPE --> CONN

    CONN --> REQ
    REQ --> RESP
    RESP --> META
    RESP --> ERR

    META --> HTML
    HTML --> CSS

    ERR --> CACHE
    CACHE --> HTML

    HTML --> HTMLV
    CSS --> HTMLV

    MAIN --> JSDOC
    MAIN --> SECUR

    SCAN --> PARSE
    PARSE --> INDEX

    CRAWLER --> URL
    URL --> XML

    style MAIN fill:#e8f5e9
    style CONN fill:#fff4e1
    style REQ fill:#fff4e1
    style RESP fill:#fff4e1
    style META fill:#e1f5ff
    style HTML fill:#e1f5ff
    style CSS fill:#e1f5ff
    style CACHE fill:#f0f0f0
    style ERR fill:#ffe1e1
    style HTMLV fill:#e1f5ff
    style JSDOC fill:#e1f5ff
    style SECUR fill:#ffe1e1
Loading

Component Security Responsibilities

Component Security Function Controls
Connection Manager MCP server connection security Retry limits, timeout enforcement, error handling
Request Handler JSON-RPC protocol integrity Schema validation, request ID tracking
Response Parser Input validation & sanitization Data type checking, XSS prevention
HTML Builder Output encoding HTML entity encoding, CSP compliance
Error Handler Fail-secure behavior Fallback content, no sensitive data exposure
HTML Validator Content integrity htmlhint rules, standards compliance
Security Scanner SAST detection eslint-plugin-security, sonarjs rules

🔒 Security Controls

Authentication & Authorization

GitHub Actions Authentication

flowchart TD
    subgraph "GitHub Actions Identity"
        WF[Workflow Trigger<br/>Schedule/Manual]
        TOKEN[GITHUB_TOKEN<br/>Auto-generated]
        PERMS[Permissions<br/>contents: write]
    end

    subgraph "Repository Operations"
        READ[Read Repository<br/>Checkout Code]
        WRITE[Write Changes<br/>Commit & Push]
    end

    subgraph "Security Boundaries"
        SCOPE[Token Scope<br/>Repository Only]
        EXPIRE[Token Expiry<br/>Job Duration]
    end

    WF -->|Provision| TOKEN
    TOKEN -->|Grant| PERMS
    PERMS -->|Allow| READ
    PERMS -->|Allow| WRITE

    TOKEN --> SCOPE
    TOKEN --> EXPIRE

    style WF fill:#f0f0f0
    style TOKEN fill:#ffe1e1
    style PERMS fill:#ffe1e1
    style READ fill:#e8f5e9
    style WRITE fill:#e8f5e9
    style SCOPE fill:#e1f5ff
    style EXPIRE fill:#e1f5ff
Loading

Controls:

  • Minimal Permissions: contents: write only, no admin/secrets access
  • Auto-expiring Tokens: GITHUB_TOKEN valid only for job duration
  • SHA-pinned Actions: All actions pinned to commit SHA for supply chain security
  • Branch Protection: Required reviews, status checks before merge
  • No Persistent Credentials: Tokens destroyed after job completion

ISMS Alignment:

Static Site Access Control

Control Implementation:

  • No Authentication Required: Public content by design
  • Read-Only Access: Users cannot modify content
  • HTTPS Enforcement: GitHub Pages forces HTTPS
  • No Server-Side Execution: No authentication bypass risks

Security Rationale:

  • All content is public information from European Parliament
  • No PII or sensitive data
  • Read-only static files eliminate authentication attack surface

Data Protection & Key Management

Input Validation & Sanitization

flowchart TD
    subgraph "External Data Sources"
        EP[European Parliament API<br/>Untrusted Input]
    end

    subgraph "Validation Pipeline"
        SCHEMA[Schema Validation<br/>JSON Structure Check]
        TYPE[Type Validation<br/>Data Type Enforcement]
        RANGE[Range Validation<br/>Bounds Checking]
    end

    subgraph "Sanitization Pipeline"
        HTML_STRIP[HTML Tag Stripping<br/>Remove Dangerous Tags]
        ENTITY[Entity Encoding<br/>HTML Special Chars]
        SCRIPT[Script Removal<br/>XSS Prevention]
    end

    subgraph "Output Generation"
        SAFE[Safe HTML<br/>Validated Content]
    end

    EP -->|Raw JSON| SCHEMA
    SCHEMA -->|Valid| TYPE
    SCHEMA -->|Invalid| ERR[Log Error &<br/>Use Fallback]
    TYPE -->|Valid| RANGE
    TYPE -->|Invalid| ERR
    RANGE -->|Valid| HTML_STRIP
    RANGE -->|Invalid| ERR

    HTML_STRIP --> ENTITY
    ENTITY --> SCRIPT
    SCRIPT --> SAFE

    style EP fill:#fff4e1
    style SCHEMA fill:#e1f5ff
    style TYPE fill:#e1f5ff
    style RANGE fill:#e1f5ff
    style HTML_STRIP fill:#ffe1e1
    style ENTITY fill:#ffe1e1
    style SCRIPT fill:#ffe1e1
    style SAFE fill:#e8f5e9
    style ERR fill:#f0f0f0
Loading

Validation Controls:

  1. Schema Validation: MCP response structure validation
  2. Type Checking: Enforce expected data types (string, number, date)
  3. Range Checking: Validate date ranges, text lengths
  4. Encoding Enforcement: UTF-8 only, reject invalid encodings

Sanitization Controls:

  1. HTML Entity Encoding: Convert <, >, &, ", ' to entities
  2. Script Tag Removal: Strip all <script> tags from input
  3. Event Handler Removal: Remove onclick, onerror, etc.
  4. URL Validation: Validate and sanitize all href/src attributes

ISMS Alignment:

Data Classification & Handling

Data Type Classification Storage Encryption Retention
News Articles Public Git repository At-rest (GitHub) Indefinite
EP API Responses Public Ephemeral (runtime only) In-transit (TLS 1.3) None
Generation Metadata Public Git repository At-rest (GitHub) Indefinite
GitHub Tokens Secret GitHub Secrets Encrypted Auto-rotate
MCP Communication Internal Localhost only N/A (local) None

ISMS Alignment:

No PII Collection

Control Implementation:

  • No User Tracking: No cookies, no analytics, no tracking scripts
  • No Form Inputs: No data collection forms
  • No User Accounts: No registration or login
  • Static Content Only: No server-side processing of user data
  • No JavaScript: No client-side scripts of any kind in generated pages

GDPR Compliance:

  • Article 25 (Data Protection by Design): No PII by design
  • Article 32 (Security of Processing): Public data only, no processing of personal data
  • No Data Protection Impact Assessment (DPIA) required

Key Management

Cryptographic Key Lifecycle:

As a static site generator, EU Parliament Monitor has a minimal key management footprint:

Key Type Purpose Management Rotation
GitHub Actions GITHUB_TOKEN CI/CD authentication Auto-generated per job Per-workflow run (ephemeral)
MCP PAT EP MCP Server access GitHub Secrets (encrypted at rest) Manual rotation, 90-day recommended
TLS Certificates HTTPS for GitHub Pages GitHub-managed (Let's Encrypt) Auto-renewed every 90 days
GPG Signing Keys Commit verification Developer-managed Per policy, minimum 2048-bit RSA

Key Security Controls:

  • No Hardcoded Secrets: All secrets stored in GitHub Secrets (encrypted at rest with libsodium sealed boxes)
  • Ephemeral Tokens: GITHUB_TOKEN scoped to job duration and repository
  • Least Privilege: Token permissions explicitly declared per workflow (permissions: block)
  • Secret Scanning: GitHub secret scanning enabled to detect exposed credentials
  • No Application-Managed Persistent Keys: Static site requires no application-managed long-lived cryptographic keys; all platform keys (TLS, GPG) are externally managed
  • TLS 1.2+: All external connections use TLS 1.2 or higher; TLS 1.3 preferred where supported by peers (GitHub Pages, npm registry)

ISMS Alignment:

Network Security & Perimeter Protection

Network Architecture

graph TB
    subgraph "External Network"
        direction TB
        USERS[🌍 Internet Users<br/>Public Access]
        EP_NET[🏛️ European Parliament<br/>data.europarl.europa.eu]
    end

    subgraph "GitHub Infrastructure"
        direction TB
        GH_CDN[🌐 GitHub Pages CDN<br/>HTTPS Only]
        GH_RUNNER[⚙️ GitHub Actions Runner<br/>Ephemeral VM]
    end

    subgraph "Application Layer"
        direction TB
        STATIC[📄 Static HTML/CSS<br/>Read-Only Files]
        MCP[🔌 MCP Server<br/>localhost:random_port]
    end

    USERS -->|HTTPS 443<br/>TLS 1.3| GH_CDN
    GH_CDN -->|Serve| STATIC

    GH_RUNNER -->|HTTPS 443<br/>TLS 1.3| EP_NET
    GH_RUNNER -->|localhost<br/>stdio/pipe| MCP
    MCP -->|HTTPS 443| EP_NET

    style USERS fill:#e1f5ff
    style EP_NET fill:#fff4e1
    style GH_CDN fill:#f0f0f0
    style GH_RUNNER fill:#f0f0f0
    style STATIC fill:#e8f5e9
    style MCP fill:#e8f5e9
Loading

Network Security Controls:

  1. HTTPS Enforcement

    • GitHub Pages enforces HTTPS for all connections
    • TLS 1.3 with strong cipher suites
    • Automatic HSTS header: max-age=31536000
  2. Localhost-Only MCP Communication

    • MCP server binds to localhost only
    • stdio/pipe communication (no network sockets)
    • Process isolation within GitHub Actions runner
  3. No Exposed Ports

    • Static site: No server ports
    • MCP server: Not exposed externally
    • GitHub Actions: Ephemeral runners, no persistent infrastructure
  4. Outbound Restrictions

    • Only HTTPS to European Parliament API
    • No other external connections
    • DNS: GitHub-managed

ISMS Alignment:

Content Security Policy

Current Security Headers (GitHub Pages Defaults):

GitHub Pages provides the following default security headers:

  • X-Content-Type-Options: nosniff - Prevent MIME sniffing

HTML Meta Tags (Implemented):

The generated HTML pages include no inline JavaScript and no external scripts, which provides inherent XSS protection. A Content-Security-Policy meta tag is also emitted in every generated article page.

Implemented Security Meta Tags:

  • Content-Security-Policy - Emitted in every article page via src/templates/article-template.ts:377-399 as a <meta http-equiv> tag (not a CloudFront response-headers policy):
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self'; frame-src 'none'; base-uri 'self'; form-action 'none'">
  • X-Content-Type-Options: nosniff - Emitted in every article page (meta tag)
  • Referrer-Policy: no-referrer - Emitted in every article page (meta tag)
  • X-Frame-Options - Relies on GitHub Pages / CloudFront defaults (no meta-tag equivalent)

Policy decisions:

  • script-src 'self' — no inline <script> blocks in generated HTML; all executable JS is externalised to js/index-runtime.js (index pages) and js/article-runtime.js (article pages). JSON-LD blocks use type="application/ld+json" which is non-executable and exempt from script-src.
  • style-src 'self' 'unsafe-inline' — required for existing inline style attributes in article content (Chart.js containers, CSS variables)
  • img-src 'self' https: data: — permits EU Parliament remote images and data URIs
  • connect-src 'self' — permits same-origin fetch/XHR (Chart.js data, runtime JS); no third-party network calls allowed at runtime
  • frame-src 'none', form-action 'none', base-uri 'self' — hard deny on embedding and form posts; restrict base URL

CSP Delivery Mechanism:

CSP is delivered per-page via <meta http-equiv> rather than via CloudFront response headers, so the policy ships with the generated HTML and applies identically whether the site is served from AWS S3+CloudFront (primary) or GitHub Pages (fallback). Additional hardening headers (HSTS, Strict-Transport-Security, X-Content-Type-Options: nosniff, Permissions-Policy) are applied at the CloudFront edge as defence-in-depth; evaluating a CloudFront response-headers policy that duplicates the CSP is tracked as CRA-ASSESSMENT.md §5ᵇ gap table row 9.

HTML Sanitization: src/utils/html-sanitize.ts sanitizes all MCP-derived strings before HTML emission

Privacy: No cookies; localStorage limited to theme preference (non-PII)

Application Security

XSS Prevention

Multi-Layer XSS Defense:

flowchart TD
    INPUT[EP API Data /<br/>External Input]

    subgraph "Defense Layer 1: Input Validation"
        VAL[Schema Validation]
        TYPE[Type Checking]
    end

    subgraph "Defense Layer 2: Sanitization"
        STRIP[HTML Tag Stripping]
        ENCODE[Entity Encoding]
    end

    subgraph "Defense Layer 3: Output Encoding"
        HTML_ENCODE[HTML Context Encoding]
        ATTR_ENCODE[Attribute Encoding]
    end

    subgraph "Defense Layer 4: CSP"
        CSP[Content Security Policy]
        META[CSP Meta Tags]
    end

    OUTPUT[Safe HTML Output]

    INPUT --> VAL
    VAL --> TYPE
    TYPE --> STRIP
    STRIP --> ENCODE
    ENCODE --> HTML_ENCODE
    HTML_ENCODE --> ATTR_ENCODE
    ATTR_ENCODE --> CSP
    CSP --> META
    META --> OUTPUT

    style INPUT fill:#fff4e1
    style VAL fill:#e1f5ff
    style TYPE fill:#e1f5ff
    style STRIP fill:#ffe1e1
    style ENCODE fill:#ffe1e1
    style HTML_ENCODE fill:#ffe1e1
    style ATTR_ENCODE fill:#ffe1e1
    style CSP fill:#e8f5e9
    style META fill:#e8f5e9
    style OUTPUT fill:#e8f5e9
Loading

XSS Controls:

  1. Input Validation: Reject invalid data at API boundary
  2. HTML Sanitization: Remove dangerous tags (<script>, <iframe>, etc.)
  3. Entity Encoding: Convert special characters to HTML entities via escapeHTML() in src/utils/file-utils.ts
  4. URL Validation: isSafeURL() validates URL schemes (http/https only)
  5. No JavaScript Execution: Generated articles contain zero JavaScript — XSS is architecturally impossible in the output

Testing:

  • ESLint security plugin detects XSS patterns
  • htmlhint validates HTML structure
  • Unit tests validate sanitization functions
  • Integration tests verify end-to-end XSS prevention

Dependency Security

Supply Chain Security Controls:

graph TB
    subgraph "Dependency Management"
        PKG[package.json<br/>29 Dependencies]
        LOCK[package-lock.json<br/>Locked Versions]
    end

    subgraph "Automated Scanning"
        DEP[Dependabot<br/>Weekly Scans]
        AUDIT[npm audit<br/>CI Checks]
        CODEQL[CodeQL<br/>SAST]
    end

    subgraph "Update Process"
        PR[Auto PR<br/>Version Updates]
        TEST[CI Tests<br/>Validation]
        MERGE[Merge<br/>After Review]
    end

    subgraph "Enforcement"
        FAIL[Block PR<br/>on Vulnerabilities]
        BADGE[Security Badge<br/>Status]
    end

    PKG --> LOCK
    LOCK --> DEP
    LOCK --> AUDIT
    LOCK --> CODEQL

    DEP --> PR
    AUDIT --> FAIL

    PR --> TEST
    TEST --> MERGE
    CODEQL --> FAIL

    MERGE --> BADGE

    style PKG fill:#e8f5e9
    style LOCK fill:#e8f5e9
    style DEP fill:#e1f5ff
    style AUDIT fill:#e1f5ff
    style CODEQL fill:#ffe1e1
    style PR fill:#f0f0f0
    style TEST fill:#e1f5ff
    style MERGE fill:#e8f5e9
    style FAIL fill:#ffe1e1
    style BADGE fill:#e8f5e9
Loading

Dependency Security:

  • Minimal Dependencies: 28 devDependencies, 1 production dependency (european-parliament-mcp-server)
  • npm provenance + SLSA Level 3: Release artifacts signed via OIDC publish (no long-lived npm token)
  • AWS OIDC Federation: .github/workflows/deploy-s3.yml uses OIDC (no long-lived AWS keys)
  • Dependabot: Weekly scans, auto-generate PRs for updates
  • npm audit: CI validation, fail on moderate+ vulnerabilities
  • gh-advisory-database: Gate on new dependencies before merge
  • Version Locking: package-lock.json ensures reproducible builds
  • SHA Pinning: GitHub Actions pinned to commit SHA
  • Husky pre-commit: Local gate with lint-staged validation
  • ESLint 10.2.1: sonarjs 4.0.3, security 4.0.0, jsdoc 62.9.0
  • Vendored Libraries: Chart.js 4.5.1, D3 7.9.0 copied locally via npm run copy-vendor with SRI (no CDN risk)
  • CI/CD Gates: codeql.yml, dependency-review.yml, scorecards.yml, reuse.yml (SPDX via REUSE.toml)

Current Dependencies:

  • All devDependencies (28 packages) plus 1 production dependency (european-parliament-mcp-server)
  • Latest versions with security patches
  • No known vulnerabilities (npm audit clean)

ISMS Alignment:

Infrastructure Security

GitHub Actions Security

Workflow Security Controls:

flowchart TD
    subgraph "Workflow Trigger"
        SCHED[Schedule Trigger<br/>Weekday Crons]
        MANUAL[Manual Trigger<br/>workflow_dispatch]
    end

    subgraph "Security Checks"
        PIN[SHA-Pinned Actions<br/>Supply Chain]
        PERM[Minimal Permissions<br/>contents: write]
        RUNNER[GitHub-Hosted Runner<br/>Ephemeral]
    end

    subgraph "Execution"
        CHECKOUT[Checkout Code]
        INSTALL[npm ci<br/>Reproducible Build]
        GENERATE[Generate News]
        VALIDATE[Validate HTML]
    end

    subgraph "Security Scans"
        AUDIT[npm audit<br/>Vulnerability Check]
        CODEQL_SCAN[CodeQL<br/>SAST]
        LINT[ESLint Security<br/>Code Quality]
    end

    subgraph "Commit"
        COMMIT[Commit Changes<br/>Automated]
        PUSH[Push to GitHub]
    end

    SCHED --> PIN
    MANUAL --> PIN
    PIN --> PERM
    PERM --> RUNNER
    RUNNER --> CHECKOUT

    CHECKOUT --> INSTALL
    INSTALL --> AUDIT
    AUDIT --> GENERATE
    GENERATE --> VALIDATE

    VALIDATE --> LINT
    LINT --> CODEQL_SCAN

    CODEQL_SCAN --> COMMIT
    COMMIT --> PUSH

    style SCHED fill:#f0f0f0
    style MANUAL fill:#f0f0f0
    style PIN fill:#ffe1e1
    style PERM fill:#ffe1e1
    style RUNNER fill:#e1f5ff
    style AUDIT fill:#ffe1e1
    style CODEQL_SCAN fill:#ffe1e1
    style LINT fill:#e1f5ff
    style COMMIT fill:#e8f5e9
    style PUSH fill:#e8f5e9
Loading

Infrastructure Controls:

  1. Ephemeral Runners

    • GitHub-hosted runners (Ubuntu latest)
    • Destroyed after each job
    • No persistent state or credentials
    • Clean environment for each execution
  2. Secrets Management

    • GITHUB_TOKEN: Auto-generated, auto-expiring
    • No custom secrets required for current operation
    • Future: COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN for org access
  3. Workflow Permissions

    • contents: write - Repository read/write only
    • No secrets, issues, or admin access
    • Token scope limited to repository
  4. Supply Chain Security

    • All GitHub Actions SHA-pinned
    • Dependabot monitors action updates
    • SBOM generation for releases
  5. Workflow Hardening (StepSecurity Harden Runner)

    • step-security/harden-runner deployed across all CI/CD workflows
    • Egress policy: audit mode (monitors outbound network calls)
    • Egress policy: block mode on deployment workflows (only allowed endpoints)
    • Detects and reports anomalous network activity during builds

ISMS Alignment:

GitHub Pages Security

Hosting Security:

  • HTTPS Enforcement: Automatic HTTPS redirect
  • TLS 1.2+/1.3: Modern protocols enforced for all outbound HTTPS (Copilot API, Claude API, Codex API, IMF REST, WB MCP, GitHub API, npm registry, AWS)
  • EP MCP: Local-only Docker bridge — no TLS required (trust boundary is Docker bridge itself)
  • crypto.randomUUID() / crypto.randomBytes(): Secure RNG only; Math.random() banned by ESLint
  • Deprecated Crypto Banned: MD5, SHA-1, DES, 3DES prohibited by ISMS policy
  • DDoS Protection: GitHub's CDN infrastructure
  • Automatic Patching: GitHub manages server updates
  • No Server Configuration: Zero server attack surface

Static Site Security:

  • No Databases: No SQL injection risk
  • No Server-Side Code: No RCE vulnerabilities
  • Read-Only Files: Users cannot modify content
  • No User Input: No injection attack vectors
  • No Sessions: No session hijacking risk

🧠 AI-First Quality & Prompt Injection Defense

Purpose: Prevent AI-generated content leakage of placeholder templates and ensure production-quality intelligence output.

2-Pass Validator: validate-analysis-completeness.js scans rendered HTML for:

  • FALLBACK_TEMPLATE_PATTERNS: Detects template placeholder leaks
  • AI_MARKER sentinels: Zero-tolerance for [AI_ANALYSIS_REQUIRED] markers

APIs:

  • scanHtmlForFallbackLeaks(htmlContent): Scan single HTML string
  • scanArticleHtmlFiles(directory): Scan all generated articles

Pre-Translation Gate: news-translate.md scans English sources before 14-language fan-out to block bad content propagation

Quality Thresholds (from analysis/methodologies/reference-quality-thresholds.json):

  • intelligence/mcp-reliability-audit.md ≥200 words (breaking ≥385)
  • intelligence/reference-analysis-quality.md ≥140 words (breaking ≥190)

Zero-Tolerance Enforcement:

  • CI fails on [AI_ANALYSIS_REQUIRED] sentinel presence
  • PR merge blocked until all placeholder markers removed
  • Human review required for all AI-generated content

Prompt Injection Defense:

  • MCP data is stringly typed + sanitized via src/utils/html-sanitize.ts
  • No untrusted input reaches shell (safe bash patterns enforced by Layer 2 sandboxing)
  • Schema validation at API boundaries rejects malformed data

ISMS Alignment: AI Policy — AI content quality assurance


Agentic Workflow Security

The 10 news generation workflows (breaking, week-ahead, week-in-review, month-ahead, month-in-review, committee-reports, motions, propositions, news-article-generator, news-translate) use the GitHub Agentic Workflows (gh-aw) framework with built-in security controls:

Workflow Hardening:

  • Timeout Enforcement: timeout-minutes: 45 hard stop prevents runaway execution
  • Allowed Domains Whitelist: Network access restricted to data.europarl.europa.eu, *.europa.eu, github.com, and required infrastructure endpoints via safe-outputs configuration
  • Deterministic Branch Naming: news/{type}-{date} pattern (e.g., news/week-ahead-2026-02-23) prevents branch conflicts
  • PR Creation Limits: Maximum 1 pull request per workflow run enforced by gh-aw constraints
  • Comment Limits: Maximum 1 comment per run, 65536 character limit, 10 mention limit
  • Concurrency Control: concurrency: gh-aw-${{ github.workflow }} prevents parallel execution of the same workflow
  • Read-Only Default Permissions: permissions: {} at workflow level, elevated only where needed
  • SHA-Pinned Actions: All gh-aw actions pinned to specific commit SHA

MCP Data Resilience:

  • 🔄 Fallback Data: Automatic fallback to cached/sample data if MCP server unavailable
  • Scheduled Retries: Multiple daily cron triggers ensure eventual success

📜 Data Integrity & Auditing

EU Parliament Monitor ensures data integrity throughout its news generation pipeline, from European Parliament source data through to published content. As a static site generator operating on public parliamentary data, integrity controls focus on content accuracy, tamper-evident change tracking, and build reproducibility.

flowchart TD
    subgraph "Data Integrity Architecture"
        direction TB
        EP[🏛️ EP Open Data API] -->|HTTPS/TLS 1.3| VALIDATE[📋 Input Validation<br/>Schema + Type + Range]
        VALIDATE -->|Valid Data| TRANSFORM[🔄 Content Transform<br/>Multi-language Generation]
        VALIDATE -->|Invalid| REJECT[⚠️ Reject & Log<br/>Fallback to Cached]
        TRANSFORM -->|HTML Output| SANITIZE[🛡️ HTML Sanitization<br/>XSS Prevention]
        SANITIZE -->|Safe Content| COMMIT[📝 Git Commit<br/>Immutable History]
        COMMIT -->|SHA Verified| DEPLOY[🚀 GitHub Pages<br/>CDN Distribution]
    end

    subgraph "Audit Trail"
        direction TB
        GIT_LOG[📊 Git Log<br/>Immutable Audit Trail]
        GHA_LOG[📋 GitHub Actions Logs<br/>90-day Retention]
        CODEQL[🔍 CodeQL Findings<br/>SAST Audit]
        DEP_AUDIT[📦 Dependency Audit<br/>npm audit History]
    end

    COMMIT --> GIT_LOG
    COMMIT --> GHA_LOG

    style EP fill:#fff4e1
    style VALIDATE fill:#e1f5ff
    style SANITIZE fill:#ffe1e1
    style COMMIT fill:#e8f5e9
    style DEPLOY fill:#e8f5e9
Loading

Change Tracking & Tamper-Evident Logging

Control Implementation Evidence
Immutable Commit History Git SHA-256 hash chain, signed commits via GPG Every content change has traceable commit
Branch Protection Required reviews, status checks, no force pushes Main branch protected against unauthorized changes
Build Provenance GitHub Actions workflow logs with SLSA Level 3 Reproducible builds with attestation
Content Checksums Generated HTML has deterministic output from same inputs Build reproducibility verification
Dependency Lock package-lock.json ensures reproducible installs npm ci for deterministic dependency resolution

Audit Capabilities

  • Git Audit Trail: Complete history of all content changes, author attribution, timestamps
  • GitHub Actions Logs: Build execution logs retained for 90 days
  • CodeQL SAST Reports: Security scan history with finding lifecycle
  • Dependabot History: Dependency vulnerability alerts and resolution timeline
  • PR Review Trail: Code review comments and approval history for all changes
  • REUSE Compliance: License compliance audit trail via REUSE tool

ISMS Alignment:


📊 Session & Action Tracking

EU Parliament Monitor, as a static website generator, implements tracking mechanisms appropriate for its architecture—focusing on build-time operations and privacy-respecting analytics. There are no user sessions, cookies, or client-side tracking.

flowchart TD
    subgraph "Build Session Tracking"
        direction TB
        A[⏰ GitHub Actions Trigger] -->|"Daily Cron"| B[🔄 Workflow Run]
        B -->|"Create"| C[📝 Build Session]

        B -->|"Execute"| D[🛠️ Build Steps]
        D -->|"Generate"| E[📊 Build Events]
        E -->|"Associated with"| C

        C -->|"Contains"| F[📋 Session Metadata]
        F -->|"Records"| G[🔑 Run ID]
        F -->|"Records"| H[👤 Actor/Trigger]
        F -->|"Records"| I[🌿 Branch/Commit]
        F -->|"Records"| J[⏰ Timestamps]

        E -->|"Contains"| K[📋 Event Metadata]
        K -->|"Records"| L[🔍 Operation Type]
        K -->|"Records"| M[📄 Step Name]
        K -->|"Records"| N[✅ Success/Failure]
        K -->|"Records"| O[⏱️ Duration]

        C & E -->|"Store"| P[💾 GitHub Actions Logs]
        P -->|"Analysis"| Q[📊 Workflow Insights]
        P -->|"Audit"| R[🔍 Security Review]
    end

    style A fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style B fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    style C,E fill:#FF3D00,stroke:#BF360C,stroke-width:2px,color:white,font-weight:bold
    style D fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style F,K fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style G,H,I,J,L,M,N,O fill:#00E676,stroke:#00C853,stroke-width:2px,color:black,font-weight:bold
    style P fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    style Q,R fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    classDef default font-weight:bold
Loading

GitHub Actions Build Session Tracking

Every workflow execution creates a tracked session with comprehensive metadata:

Build Session Metadata:

  • 🔑 Unique Run Identification: Each workflow run has a unique GITHUB_RUN_ID
  • 👤 Trigger Attribution: Tracked via GITHUB_ACTOR and GITHUB_TRIGGERING_ACTOR
  • 🌿 Source Context: Branch (GITHUB_REF), commit SHA (GITHUB_SHA)
  • ⏰ Temporal Tracking: Start time, end time, duration
  • 🔄 Workflow Type: Scheduled (cron), manual (workflow_dispatch), push, pull_request
  • 📊 Outcome: Success, failure, cancelled, skipped

Implementation:

# .github/workflows/generate-news.yml
env:
  RUN_ID: ${{ github.run_id }}
  ACTOR: ${{ github.actor }}
  COMMIT_SHA: ${{ github.sha }}
  BRANCH: ${{ github.ref_name }}

Build Action Event Tracking

Every build step generates trackable events:

Build Event Metadata:

  • 🔄 Operation Type: Checkout, setup, install, test, build, validate, deploy
  • 📊 Step Context: Step name, job name, workflow name
  • ✅ Success/Failure: Exit code, error messages
  • ⏱️ Duration: Step execution time
  • 📦 Artifacts: Generated files, logs, reports

Key Build Events Tracked:

  1. Node.js Setup: Version, cache hits
  2. Dependency Installation: npm install duration, vulnerability counts
  3. MCP Server Pre-installation: Success/failure, fallback triggers
  4. News Generation: Articles generated per language, processing time
  5. HTML Validation: W3C validation results, error counts
  6. Deployment: GitHub Pages deploy success, deployed URLs

Privacy-Compliant Visitor Analytics

Approach: No client-side tracking (no JavaScript analytics), privacy-first

Analytics Sources:

  1. GitHub Pages CDN Logs (limited access):

    • Aggregate page view counts
    • Geographic distribution (country-level only)
    • Referrer sources
    • No individual visitor tracking
  2. Repository Insights:

    • Traffic views (14-day retention)
    • Popular content
    • Referrer analytics
    • Clone/fork statistics

Privacy Protections:

  • ❌ No cookies
  • ❌ No fingerprinting
  • ❌ No individual user tracking
  • ❌ No third-party analytics (Google Analytics, etc.)
  • ✅ Aggregate statistics only
  • ✅ GDPR-compliant by design

Audit Trail Capabilities

GitHub Actions Logs:

  • Retention: 90 days for public repositories
  • Access: Repository maintainers only
  • Contents: Full build logs, environment variables (secrets redacted)
  • Export: Downloadable via GitHub CLI or API

Security Benefits:

  • 🔍 Complete build reproducibility
  • 🚨 Anomaly detection (unusual build patterns)
  • 📊 Performance monitoring (build time trends)
  • 🔒 Security event correlation (failed builds after dependency updates)

⚡ Threat Detection & Security Event Monitoring

EU Parliament Monitor implements security event monitoring appropriate for a static site generator, focusing on build-time security events and dependency vulnerabilities.

flowchart TD
    subgraph "Security Event Monitoring"
        direction TB
        A[🛡️ GitHub Security<br>Events] --> B[✅ Workflow Success]
        A --> C[⚠️ Workflow Failure]

        D[🔍 Dependency<br>Security] --> E[🚨 Dependabot Alert]
        D --> F[🔄 Automated PR]

        G[🔒 Code<br>Scanning] --> H[🔍 CodeQL Analysis]
        G --> I[⚠️ Security Finding]

        B & C & E & F & H & I -->|"Generate"| J[📝 Security Event]

        J -->|"Contains"| K[📋 Event Metadata]
        K -->|"Records"| L[🔍 Event Type]
        K -->|"Records"| M[⚡ Severity]
        K -->|"Records"| N[🔗 Affected Component]
        K -->|"Records"| O[⏱️ Timestamp]

        J -->|"Triggers"| P[🚨 Notification]
        P -->|"If Critical"| Q[👥 Security Team Alert]

        J -->|"Store"| R[💾 GitHub Security]
        R -->|"Dashboard"| S[📊 Security Overview]
        R -->|"Compliance"| T[📋 Audit Reports]
    end

    style A,D,G fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style B fill:#00E676,stroke:#00C853,stroke-width:2px,color:black,font-weight:bold
    style C,E,I fill:#FF3D00,stroke:#BF360C,stroke-width:2px,color:white,font-weight:bold
    style F,H fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style J fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    style K,P fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style L,M,N,O fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    style Q fill:#FF3D00,stroke:#BF360C,stroke-width:2px,color:white,font-weight:bold
    style R fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    style S,T fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    classDef default font-weight:bold
Loading

Security Event Types

Our system monitors several categories of security events:

1. 🔄 GitHub Actions Security Events

Workflow Execution Events:

  • ✅ Successful builds (baseline for anomaly detection)
  • ⚠️ Failed builds (potential security issues)
  • 🔄 Cancelled builds (manual intervention tracking)
  • ⏱️ Timeout events (potential DoS indicators)

Authentication Events:

  • 🔑 GitHub token usage (GITHUB_TOKEN)
  • 🔐 Secret access patterns
  • 👤 Actor changes (unexpected triggers)

Implementation:

# .github/workflows/generate-news.yml
- name: Monitor Build Security
  if: failure()
  run: |
    echo "::warning::Build failed - security review required"
    echo "Actor: ${{ github.actor }}"
    echo "Commit: ${{ github.sha }}"

2. 🚨 Dependency Vulnerability Events

Dependabot Alerts:

  • 🔴 Critical vulnerabilities (CVSS ≥ 9.0)
  • 🟠 High vulnerabilities (CVSS 7.0-8.9)
  • 🟡 Medium vulnerabilities (CVSS 4.0-6.9)
  • 🔵 Low vulnerabilities (CVSS < 4.0)

Automated Response:

  • Weekly Dependabot scans
  • Automated pull requests for patches
  • Auto-merge for dev dependencies (low-risk)
  • Manual review for breaking changes

Monitoring:

# npm audit in CI/CD pipeline
npm audit --audit-level=moderate

3. 🔍 Code Scanning Events

CodeQL Analysis:

  • Triggers: Every push to main, every pull request
  • Languages: JavaScript/TypeScript (Node.js 25)
  • Security queries: OWASP Top 10, CWE Top 25
  • Findings: XSS, injection, path traversal, crypto issues

Alert Handling:

  • 🚨 Critical: Block PR merge
  • ⚠️ High: Require security review
  • 💡 Medium/Low: Create issue for remediation

Implementation:

# .github/workflows/codeql.yml
- name: Perform CodeQL Analysis
  uses: github/codeql-action/analyze@v3
  with:
    category: '/language:javascript'

4. 🌐 GitHub Pages Deployment Events

Deployment Security:

  • ✅ Successful deployments
  • ⚠️ Failed deployments
  • 🔍 Asset integrity checks
  • 📊 Deployment frequency anomalies

Health Checks:

  • HTTPS certificate validation
  • CSP header verification
  • HTML validation results
  • Link integrity checks

Real-Time Monitoring Approach

GitHub Security Dashboard:

  • Location: Repository → Security tab
  • Features:
    • Dependabot alerts (real-time)
    • Code scanning results (per commit)
    • Secret scanning (not applicable for public repos)
    • Security policies (SECURITY.md)

Notification Channels:

  1. Email: Security alerts to repository maintainers
  2. GitHub Notifications: In-app alerts
  3. Security Advisories: Public disclosure (90-day embargo)

Response SLAs:

  • 🔴 Critical: 24 hours
  • 🟠 High: 7 days
  • 🟡 Medium: 30 days
  • 🔵 Low: 90 days or next release

Event Retention & Analysis

GitHub Actions Logs:

  • Retention: 90 days
  • Contents: Full workflow execution logs
  • Access: Repository maintainers only

Security Alert History:

  • Retention: Indefinite (until resolved)
  • Status Tracking: Open, fixed, dismissed
  • Audit Trail: All status changes logged

🔍 Vulnerability Management

EU Parliament Monitor implements a comprehensive vulnerability management program covering code, dependencies, infrastructure, and content delivery.

flowchart TD
    subgraph "Vulnerability Detection"
        direction TB
        CODEQL[🔍 CodeQL SAST<br/>Push & PR Scans]
        DEPBOT[🤖 Dependabot<br/>Weekly Scans]
        NPM_AUDIT[📦 npm audit<br/>CI/CD Pipeline]
        SECRET[🔑 Secret Scanning<br/>Continuous]
        ESLINT[📝 ESLint Security<br/>Pre-commit]
    end

    subgraph "Triage & Prioritization"
        direction TB
        CVSS[📊 CVSS Scoring]
        SLA[⏱️ SLA Assignment]
        ASSIGN[👤 Owner Assignment]
    end

    subgraph "Remediation"
        direction TB
        PATCH[🔧 Apply Patch]
        TEST[🧪 Test Fix]
        DEPLOY[🚀 Deploy]
        VERIFY[✅ Verify]
    end

    CODEQL --> CVSS
    DEPBOT --> CVSS
    NPM_AUDIT --> CVSS
    SECRET --> CVSS
    ESLINT --> CVSS
    CVSS --> SLA --> ASSIGN
    ASSIGN --> PATCH --> TEST --> DEPLOY --> VERIFY

    style CODEQL fill:#e1f5ff
    style DEPBOT fill:#e1f5ff
    style NPM_AUDIT fill:#e1f5ff
    style CVSS fill:#fff4e1
    style VERIFY fill:#e8f5e9
Loading

Vulnerability SLA Targets

Severity CVSS Range Response Time Resolution Time Escalation
🔴 Critical 9.0-10.0 4 hours 24 hours Immediate CEO notification
🟠 High 7.0-8.9 24 hours 7 days Weekly security review
🟡 Medium 4.0-6.9 48 hours 30 days Monthly maintenance
🟢 Low 0.1-3.9 7 days 90 days Quarterly update

Current Vulnerability Posture

  • Zero Known Vulnerabilities: npm audit clean, no open CodeQL alerts
  • Dependabot PRs: Reviewed and merged within 48 hours
  • CodeQL Findings: Triaged weekly, zero open critical/high findings
  • Secret Scanning: No exposed credentials detected
  • SBOM: Software Bill of Materials generated for supply chain transparency

Scanning Schedule

Scanner Trigger Frequency Coverage
CodeQL Push to main, PR Per-commit JavaScript/TypeScript SAST
Dependabot Scheduled Weekly (Monday) npm ecosystem
npm audit CI pipeline Every build Direct + transitive deps
Secret Scanning Push Continuous All committed content
ESLint Security Pre-commit Every commit Code quality + security rules
REUSE CI pipeline Every build License compliance

ISMS Alignment:


⚙️ Configuration & Compliance Management

EU Parliament Monitor manages configuration as code, ensuring all infrastructure and application settings are version-controlled, reviewed, and auditable.

Infrastructure as Code

Configuration Source of Truth Validation Change Process
GitHub Actions Workflows .github/workflows/*.yml YAML lint, action SHA pinning PR review + required checks
TypeScript Configuration tsconfig.json (strict mode) tsc --noEmit type checking PR review
ESLint Rules eslint.config.js npm run lint PR review
Dependabot Config .github/dependabot.yml GitHub validation PR review
Content Security Policy article-template.ts E2E tests verify CSP headers PR review + automated tests
Branch Protection GitHub Repository Settings GitHub API audit Admin-only changes
MCP Server Config .github/copilot-mcp.json Schema validation PR review

Configuration Drift Detection

  • Git Version Control: All configuration changes tracked with full audit history
  • Required PR Reviews: No direct pushes to main branch
  • CI/CD Validation: Every configuration change validated by automated pipeline
  • Lock Files: package-lock.json prevents dependency drift
  • SHA-Pinned Actions: GitHub Actions pinned to commit SHAs for reproducibility
  • Strict TypeScript: strict: true with all additional strict checks enabled

Compliance Monitoring

Framework Automated Check Frequency Evidence
REUSE (SPDX) reuse lint in CI Every build License compliance
OpenSSF Scorecard GitHub-integrated Weekly Supply chain security
SLSA GitHub attestation Per-release Build provenance
HTMLHint npm run htmlhint Every build Content standards
TypeScript Strict tsc --noEmit Every build Type safety
Prettier npm run format:check Every build Code consistency

ISMS Alignment:


📈 Security Monitoring & Analytics

EU Parliament Monitor collects security metrics and monitoring data appropriate for its static site architecture, focusing on build-time security events and supply chain monitoring.

Security Metrics Collection

flowchart LR
    subgraph "Data Sources"
        GHA[📊 GitHub Actions<br/>Build Metrics]
        CODEQL_M[🔍 CodeQL<br/>Finding Trends]
        DEP_M[📦 Dependabot<br/>Alert Metrics]
        AUDIT_M[🔐 npm audit<br/>Vulnerability Count]
    end

    subgraph "Metrics Dashboard"
        KPI[📈 Security KPIs]
        TREND[📉 Trend Analysis]
        SLA_M[⏱️ SLA Compliance]
    end

    GHA --> KPI
    CODEQL_M --> KPI
    DEP_M --> KPI
    AUDIT_M --> KPI
    KPI --> TREND
    KPI --> SLA_M

    style KPI fill:#e8f5e9
    style TREND fill:#e1f5ff
Loading

Key Security Indicators

Metric Target Measurement Current
Mean Time to Detect (MTTD) < 1 hour Automated scanning detection ✅ Real-time (CI/CD)
Mean Time to Remediate (MTTR) < 48 hours (high) Alert to fix merge ✅ < 48 hours
Vulnerability Backlog 0 critical/high Open findings count ✅ 0
Dependency Currency < 30 days behind Package age analysis ✅ Weekly updates
Build Success Rate > 95% CI/CD pipeline metrics ✅ > 98%
Security Test Coverage > 80% line Vitest coverage report ✅ 82%+
SAST False Positive Rate < 10% CodeQL triage ratio ✅ < 5%

Threat Intelligence Integration

  • GitHub Advisory Database: Automatic CVE matching via Dependabot
  • npm Security Advisories: Real-time vulnerability alerts for dependencies
  • CodeQL Query Packs: Community-maintained security query updates
  • ENISA Threat Landscape: Annual threat assessment reference (documented in THREAT_MODEL.md)

ISMS Alignment:


🏗️ High Availability & Resilience

EU Parliament Monitor's static architecture inherently provides high availability through GitHub Pages' globally distributed CDN infrastructure.

graph TD
    subgraph "GitHub Pages Global CDN"
        A[🌐 Global CDN] --> B[🌍 Edge Locations<br>Worldwide]
        B --> C[🇪🇺 Europe]
        B --> D[🇺🇸 Americas]
        B --> E[🌏 Asia-Pacific]
    end

    subgraph "Content Delivery"
        F[👤 User Request] -->|"DNS Resolution"| G[📡 Nearest Edge]
        G -->|"Cache Hit"| H[⚡ Serve Cached]
        G -->|"Cache Miss"| I[🔄 Origin Fetch]
        I --> J[💾 GitHub Origin]
        J --> G
        G --> F
    end

    subgraph "Build Redundancy"
        K[🔄 Daily Build] -->|"Trigger"| L[☁️ GitHub-Hosted<br>Runner]
        L -->|"Success"| M[✅ Deploy]
        L -->|"Failure"| N[🔄 Manual Retry]
        M --> O[📦 Static Assets]
        O --> J
    end

    style A fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    style B fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style C,D,E fill:#FF3D00,stroke:#BF360C,stroke-width:2px,color:white,font-weight:bold
    style F fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style G,H,I fill:#00E676,stroke:#00C853,stroke-width:2px,color:black,font-weight:bold
    style J fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    style K,L,N fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style M,O fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    classDef default font-weight:bold
Loading

GitHub Pages CDN Architecture

Global Distribution:

  • Edge Locations: 200+ worldwide via GitHub's CDN provider (Fastly)
  • Geographic Coverage: All continents, optimized for EU access
  • Latency: <50ms for 95% of European users
  • Bandwidth: Unlimited for static content

Availability Features:

  • Automatic Failover: Multi-origin redundancy
  • 🔄 Self-Healing: Failed edge nodes automatically replaced
  • 📊 Load Balancing: Traffic distributed across edge locations
  • 💾 Persistent Cache: Content cached at edge for fast delivery

Availability Targets & SLAs

GitHub Pages SLA:

  • Uptime Target: 99.9% (GitHub's historical performance: >99.95%)
  • Planned Downtime: None (rolling updates)
  • Unplanned Downtime: <30 minutes/month average

EU Parliament Monitor Targets:

  • Content Availability: 99.9% (inherits GitHub Pages SLA)
  • Content Freshness: Daily updates (24-hour refresh cycle)
  • Build Availability: 99.5% (GitHub Actions SLA)

Calculated Availability:

  • Static Content: 99.9% (GitHub Pages)
  • Build Process: 99.5% (GitHub Actions)
  • Overall System: 99.4% (content always available, builds may fail)

Multi-Region Delivery

Content Delivery Network (CDN):

  • Primary: GitHub Pages CDN (Fastly)
  • Regions: Global distribution with EU edge nodes
  • Fallback: GitHub's origin servers

DNS Configuration:

  • Primary: euparliamentmonitor.hack23.com (GitHub Pages custom domain)
  • CNAME: Points to hack23.github.io
  • CDN: Automatic edge routing via DNS

Edge Caching:

  • Static Assets: 24-hour cache (HTML, CSS, images)
  • Cache Invalidation: Automatic on new deployments
  • Stale-While-Revalidate: Serve stale content during revalidation

Disaster Recovery Approach

Static Site Advantages:

  • No Database: No data loss risk
  • Git-Backed: Complete history in version control
  • Reproducible: Rebuild from source at any time
  • No State: Stateless architecture simplifies recovery

Recovery Procedures:

1. GitHub Pages Outage:

  • Detection: Automated health checks, GitHub Status page
  • Response: Wait for GitHub to resolve (typically <30 minutes)
  • Mitigation: Deploy to alternative hosting (Netlify, Vercel) if extended
  • Recovery Time: <1 hour (manual deployment to alternative CDN)

2. Build Failure:

  • Detection: GitHub Actions workflow failure notification
  • Response: Review logs, fix issues, re-run workflow
  • Mitigation: Manual workflow trigger with workflow_dispatch
  • Recovery Time: <1 hour (investigate + fix + rebuild)

3. Repository Compromise:

  • Detection: Unauthorized commits, CodeQL alerts
  • Response: Revert commits, rotate secrets, audit access
  • Mitigation: Protected branches, required reviews, signed commits
  • Recovery Time: <4 hours (investigation + remediation)

4. European Parliament MCP Server Outage:

  • Detection: Build fails to fetch MCP data
  • Response: Automatic fallback to cached data
  • Mitigation: Pre-installed MCP server with sample data
  • Recovery Time: 0 (automatic fallback)

Resilience Features

Build Resilience:

  • 🔄 Retry Logic: MCP client retries failed requests (3 attempts, exponential backoff)
  • 💾 Data Caching: LRU cache prevents repeated API calls
  • 🔄 Fallback Data: Sample MEP data if MCP unavailable
  • Scheduled Retries: Daily cron ensures eventual success

Content Resilience:

  • 📦 Immutable Assets: Once deployed, content persists
  • 🔄 Version Control: Full history in Git
  • 📊 Atomic Deployments: All-or-nothing deployments
  • 🔐 Branch Protection: Prevents accidental deletions

Infrastructure Resilience:

  • ☁️ Ephemeral Runners: GitHub-hosted runners (no persistent state)
  • 🌐 CDN Redundancy: Multiple edge nodes per region
  • 🔒 Origin Redundancy: GitHub's distributed infrastructure

⚡ Resilience & Operational Readiness

EU Parliament Monitor's resilience strategy leverages the inherent reliability of static site architecture combined with GitHub's infrastructure.

flowchart TD
    subgraph "Resilience & Operational Readiness"
        A[🏗️ Static Site<br>Architecture] --> B[📊 Resilience<br>Assessment]
        B --> C[🔍 Resilience<br>Characteristics]

        C --> D[📝 Recovery Time<br>Objective: 24h]
        C --> E[📝 Recovery Point<br>Objective: 1 day]

        F[🔄 Resilience<br>Validation] --> G[🧪 Build<br>Testing]
        F --> H[🔄 Deployment<br>Testing]
        F --> I[🚨 Failover<br>Testing]

        J[⚡ Operational<br>Readiness] --> K[📑 Runbooks]
        J --> L[👥 Response<br>Procedures]
        J --> M[🔄 Automated<br>Recovery]

        N[📊 Business<br>Continuity] --> O[🌐 CDN<br>Distribution]
        N --> P[💾 Git<br>Backup]
        N --> Q[📋 Recovery<br>Plans]
    end

    style A fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style B,C fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    style D,E fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style F,J,N fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    style G,H,I,K,L,M,O,P,Q fill:#00E676,stroke:#00C853,stroke-width:2px,color:black,font-weight:bold
    classDef default font-weight:bold
Loading

Static Site Resilience Characteristics

Inherent Resilience Advantages:

  1. 📦 No Dynamic State:

    • No session data to lose
    • No database to corrupt
    • No cache coherency issues
    • Complete recovery from Git
  2. 🔄 Reproducible Builds:

    • Deterministic build process
    • Same input → same output
    • Version-pinned dependencies
    • Reproducible at any time
  3. 🌐 Global Distribution:

    • GitHub Pages CDN (200+ edge locations)
    • No single point of failure
    • Automatic edge failover
    • Multi-region redundancy
  4. 💾 Git-Backed Persistence:

    • Complete history in version control
    • Multiple repository copies (GitHub, local clones)
    • Instant rollback capability
    • Immutable commit history

Recovery Objectives

Recovery Time Objective (RTO): 24 hours

Scenario Detection Time Recovery Action Total RTO Impact
GitHub Pages Outage <5 minutes Wait for GitHub or deploy to alternative CDN <1 hour Low (GitHub SLA: 99.9%)
Build Failure <5 minutes Fix issue + re-run workflow <1 hour Low (daily updates acceptable)
Repository Compromise <1 hour Revert commits + rotate secrets <4 hours Medium (requires investigation)
MCP Server Outage <5 minutes Automatic fallback to cached data 0 (automatic) None (transparent failover)

Recovery Point Objective (RPO): 1 day

Data Type Backup Frequency Max Data Loss Recovery Source
Source Code Every commit 0 (Git-backed) GitHub repository, local clones
Generated Content Daily build 1 day Regenerate from MCP data
Build Configuration Every commit 0 (Git-backed) .github/workflows/
Dependencies Weekly scans 0 (npm lockfile) package-lock.json

Build Pipeline Resilience

Build Failure Handling:

  1. 🔄 Automatic Retry:

    # .github/workflows/generate-news.yml
    - name: Generate News with Retry
      uses: nick-fields/retry@v2
      with:
        timeout_minutes: 10
        max_attempts: 3
        command: npm run generate-news
  2. 💾 Dependency Caching:

    - name: Cache npm dependencies
      uses: actions/cache@v4
      with:
        path: ~/.npm
        key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
  3. 🔄 Manual Trigger:

    • workflow_dispatch event for manual execution
    • Allows re-running failed builds immediately
    • No waiting for next scheduled run
  4. ⏰ Scheduled Execution:

    • Weekday crons: Committee (04:00), Propositions (05:00), Motions (06:00), Week Ahead (Fridays 07:00 UTC)
    • Ensures fresh content even after failures
    • Multiple retry opportunities per week

Deployment Resilience:

  • Atomic Deployments: GitHub Pages deploys all files or none
  • Rollback Capability: Revert commit + re-deploy previous version
  • Zero-Downtime: Old content served until new deployment completes
  • Immutable URLs: Assets never change once deployed

Operational Readiness Procedures

Runbooks:

  1. [RUNBOOK-001] Build Failure Response:

    • Check GitHub Actions logs
    • Review error messages
    • Test locally: npm run generate-news
    • Fix issue → commit → push
    • Or: manual trigger via workflow_dispatch
  2. [RUNBOOK-002] Deployment Failure Response:

    • Verify GitHub Pages settings
    • Check branch protection rules
    • Review CNAME configuration
    • Re-run deployment workflow
  3. [RUNBOOK-003] MCP Server Outage:

    • Verify MCP server status
    • Check fallback data activation
    • Monitor automated retries
    • Escalate if outage >24 hours
  4. [RUNBOOK-004] Security Incident Response:

    • Follow SECURITY.md procedures
    • Review GitHub Security Advisories
    • Assess impact → contain → remediate → recover
    • Document lessons learned

Response Teams:

  • Primary: Repository maintainers (GitHub notifications)
  • Escalation: Hack23 security team (security@hack23.com)
  • External: European Parliament MCP team (for MCP issues)

Automated Recovery:

  • Dependabot: Automatic PRs for dependency updates
  • Branch Protection: Prevents accidental deletions
  • Status Checks: Block merges that fail tests
  • MCP Fallback: Automatic data fallback on failures

Business Continuity Features

1. 🌐 Multi-Region CDN Distribution:

  • GitHub Pages serves from 200+ edge locations
  • EU users served from European edge nodes
  • Automatic failover between edge nodes
  • <50ms latency for 95% of EU users

2. 💾 Git-Based Disaster Recovery:

  • Repository Copies: GitHub + local clones + forks
  • Backup Strategy: Git inherently creates distributed backups
  • Recovery: Clone from any copy + re-deploy
  • Time to Recover: <1 hour

3. 📋 Alternative Hosting Plans:

  • Primary: GitHub Pages
  • Alternative 1: Netlify (similar static hosting)
  • Alternative 2: Vercel (Edge Functions for future enhancements)
  • Alternative 3: AWS S3 + CloudFront (if GitHub entirely unavailable)

4. 🔄 Build Reproducibility:

  • Node.js version pinned (25.x, upgrading to 26.x LTS ~Apr 2026)
  • Dependencies locked (package-lock.json)
  • Environment variables documented
  • Can rebuild on any system with Node.js

Key Resilience Metrics

Availability Metrics:

  • Current Uptime: 99.95% (last 12 months, per GitHub Pages)
  • Mean Time to Recovery (MTTR): <1 hour
  • Mean Time Between Failures (MTBF): 2,190 hours (91 days)

Build Metrics:

  • Build Success Rate: 98.5% (last 90 days)
  • Average Build Duration: 3m 45s
  • Deployment Success Rate: 99.8%

Recovery Capabilities:

  • Automated Recovery: 80% of failures (MCP fallback, retry logic)
  • Manual Recovery Time: <1 hour (simple issues)
  • Disaster Recovery Time: <4 hours (complex issues)

🤖 Automated Security Operations

EU Parliament Monitor implements automated security operations through GitHub's native security features and CI/CD automation.

flowchart TD
    subgraph "Automated Security Maintenance"
        A[⏱️ Weekly<br>Schedule] --> B[🔄 Automated<br>Operations]

        B --> C[🔍 Dependency<br>Scanning]
        B --> D[🛠️ Automated<br>Updates]
        B --> E[🔒 Code<br>Analysis]
        B --> F[📊 Compliance<br>Checks]

        C --> G[📝 Dependabot<br>Alerts]
        D --> H[🔄 Automated<br>PRs]
        E --> I[🔍 CodeQL<br>Results]
        F --> J[✅ REUSE<br>Compliance]

        G & H & I & J --> K[📦 Security<br>Dashboard]
    end

    style A fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style B fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    style C,D,E,F fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style G,H,I,J fill:#FF3D00,stroke:#BF360C,stroke-width:2px,color:white,font-weight:bold
    style K fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    classDef default font-weight:bold
Loading

Dependabot Automated Security Updates

Configuration:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
      day: 'monday'
      time: '08:00'
      timezone: 'Europe/Stockholm'
    open-pull-requests-limit: 10
    reviewers:
      - 'pethers'
    assignees:
      - 'pethers'
    commit-message:
      prefix: 'chore(deps)'
      include: 'scope'

Automated Actions:

  • 🔍 Weekly Scans: Every Monday 08:00 Europe/Stockholm
  • 🔄 Automated PRs: Up to 10 concurrent pull requests
  • 🎯 Severity-Based: Critical/High prioritized first
  • 👤 Auto-Assign: PRs assigned to maintainers
  • Auto-Merge: Dev dependencies (low risk) auto-merged if tests pass

Severity Handling:

Severity Response Time Action Auto-Merge
Critical 24 hours Immediate review + merge ❌ No (breaking changes risk)
High 7 days Priority review + merge ❌ No
Medium 30 days Standard review ⚠️ If dev dependency
Low 90 days Batch with other updates ✅ Yes (if dev dependency)

CodeQL Automated SAST Scanning

Configuration:

# .github/workflows/codeql.yml
name: 'CodeQL Advanced'
on:
  push:
    branches: ['main']
  pull_request:
    branches: ['main']
  schedule:
    - cron: '0 8 * * 1' # Weekly Monday 08:00 UTC

jobs:
  analyze:
    name: Analyze (javascript-typescript)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: javascript-typescript
          queries: security-extended

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: '/language:javascript-typescript'

Automated Scanning:

  • Trigger Events: Push to main, pull requests, weekly scheduled
  • 🔍 Query Suite: security-extended (OWASP Top 10, CWE Top 25)
  • 📊 Language: JavaScript/TypeScript
  • 🚨 Blocking: High/Critical findings block PR merge

Alert Management:

  • Auto-Dismiss: False positives marked by maintainers
  • Auto-Close: Fixed issues automatically closed when remediated
  • Auto-Comment: CodeQL comments on PRs with findings

GitHub Actions Security Automation

Build-Time Security Checks:

  1. npm audit (every build):

    - name: Run npm audit
      run: npm audit --audit-level=moderate
  2. HTML Validation (every build):

    - name: Validate HTML
      run: npm run validate:html
  3. REUSE Compliance (every build):

    - name: REUSE Compliance Check
      uses: fsfe/reuse-action@v4
  4. Dependency Review (on PRs):

    - name: Dependency Review
      uses: actions/dependency-review-action@v4

Security Gates:

  • All checks must pass before merge
  • 🚫 Blocking: npm audit failures (moderate+)
  • ⚠️ Warning: HTML validation errors (non-blocking)
  • Required: REUSE compliance

Automated Compliance Verification

REUSE Compliance Automation:

# .github/workflows/reuse.yml
name: REUSE Compliance
on: [push, pull_request]
jobs:
  reuse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: REUSE Compliance Check
        uses: fsfe/reuse-action@v4

What It Checks:

  • License Headers: All source files have SPDX identifiers
  • License Files: LICENSES/ directory contains license texts
  • Copyright Statements: Copyright information present
  • REUSE.toml: Configuration file valid

Benefits:

  • 🔐 License Compliance: Automated license header verification
  • 📋 Audit Trail: Every file's licensing clearly documented
  • Fast Feedback: <1 minute check on every push
  • 🚫 Enforcement: Blocks PRs without proper licensing

Automated Security Notifications

GitHub Security Notifications:

Event Notification Channel Response Time
Dependabot Alert Email + GitHub UI 24h (Critical), 7d (High)
CodeQL Finding PR Comment + Email Immediate (blocks merge)
Workflow Failure Email <1 hour (during business hours)
Secret Scanning Email + Security Tab Immediate

Integration with External Tools:

  • 🔔 Slack/Discord: (Future) Webhook notifications
  • 📧 Email: Built-in GitHub notifications
  • 📱 Mobile: GitHub mobile app push notifications

Automation Benefits

Efficiency Gains:

  • Time Savings: ~8 hours/week (manual security checks eliminated)
  • 🔄 Consistency: 100% of commits scanned (no human error)
  • 🚀 Speed: Dependabot PRs created within 1 hour of vulnerability disclosure
  • 📊 Coverage: 29/29 dependencies monitored (100%)

Security Improvements:

  • 🔍 Early Detection: Vulnerabilities found before production
  • 🛡️ Defense-in-Depth: Multiple automated security layers
  • 📈 Continuous Improvement: Weekly scans catch new vulnerabilities
  • 🔐 Supply Chain Security: Automated dependency review

🛡️ Application Security Controls

EU Parliament Monitor implements comprehensive application-level security controls focused on input validation, output encoding, and content integrity for its static site generation pipeline.

Input Validation Framework

Layer Control Implementation
Schema Validation JSON structure verification MCP response schema validation before processing
Type Enforcement TypeScript strict mode Compile-time type safety with strict: true
Range Checking Bounds validation Date ranges, string lengths, numeric bounds
HTML Sanitization XSS prevention html-sanitize.ts strips dangerous HTML tags and attributes
Content Validation Article quality scoring article-quality-scorer.ts validates generated content

Output Encoding Controls

  • HTML Entity Encoding: All European Parliament data HTML-encoded before insertion
  • CSP Hash-Based Script Allowlisting: Inline scripts allowed only via SHA-256 hash
  • No Dynamic Script Generation: All content is static HTML, no runtime script evaluation
  • Template Escaping: article-template.ts uses safe template patterns
  • Multi-Language Safety: Content validators check all 14 language variants for XSS vectors

Content Integrity Verification

  • Article Validation: validate-articles.ts checks all generated articles for structural integrity
  • HTML Standards Compliance: htmlhint validates HTML5 standards compliance
  • Accessibility Testing: WCAG 2.1 AA compliance via axe-core in E2E tests
  • Link Integrity: Internal links validated during build process
  • Metadata Consistency: news-metadata.ts ensures article metadata integrity across languages

ISMS Alignment:


🏆 Defense-in-Depth Strategy

EU Parliament Monitor implements a defense-in-depth security strategy with multiple overlapping layers of protection, ensuring that a compromise of any single layer does not lead to complete security failure.

graph TB
    subgraph "Defense-in-Depth Layers"
        direction TB
        A[🌐 Edge/CDN Layer] --> B[🔒 Network Layer]
        B --> C[🛡️ Application Layer]
        C --> D[🔐 Data Layer]
        D --> E[💾 Storage Layer]
        E --> F[🏗️ Infrastructure Layer]
        F --> G[📊 Monitoring Layer]

        A --> A1[GitHub Pages CDN<br>DDoS Protection<br>TLS 1.3]
        B --> B1[HTTPS-Only<br>CSP Headers<br>Secure Headers]
        C --> C1[Input Validation<br>XSS Prevention<br>Dependency Security]
        D --> D1[No Persistent Data<br>Public Data Only<br>Sanitization]
        E --> E1[Git-Backed Storage<br>Immutable History<br>Signed Commits]
        F --> F1[GitHub Actions<br>Ephemeral Runners<br>Minimal Secrets]
        G --> G1[CodeQL SAST<br>Dependabot<br>Audit Logs]
    end

    style A,B,C,D,E,F,G fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style A1,B1,C1,D1,E1,F1,G1 fill:#00E676,stroke:#00C853,stroke-width:2px,color:black,font-weight:bold
    classDef default font-weight:bold
Loading

Layer 1: Edge/CDN Security

GitHub Pages CDN Protection:

  • 🌐 Global Distribution: 200+ edge locations (Fastly-powered)
  • 🛡️ DDoS Mitigation: Automatic traffic scrubbing at edge
  • 🔒 TLS 1.3: Modern encryption for all traffic
  • ⚡ Rate Limiting: Edge-level request throttling
  • 🔐 Certificate Management: Automatic Let's Encrypt renewal

Security Benefits:

  • Absorbs DDoS attacks before reaching origin
  • Reduces attack surface (no exposed servers)
  • Prevents protocol downgrade attacks
  • Ensures always-on HTTPS

Layer 2: Network Security

HTTP Security Headers:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff

Note: HSTS and nosniff are provided by GitHub Pages. CSP is implemented via HTML meta tags in article pages. X-Frame-Options and Permissions-Policy are planned as future enhancements.

Network Controls:

  • HTTPS-Only: No HTTP traffic (301 redirects)
  • HSTS Preloading: Browser-enforced HTTPS
  • No JavaScript: Architectural XSS prevention (no scripts to execute)
  • No Inline Scripts: HTML output contains zero JavaScript

Security Benefits:

  • Prevents man-in-the-middle attacks via HTTPS/HSTS
  • XSS is architecturally prevented (no JavaScript in output)
  • Prevents MIME-type confusion attacks
  • Enforces secure communication

Layer 3: Application Security

Input Validation & Sanitization:

// src/utils/file-utils.ts
export function escapeHTML(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

export function isSafeURL(url: string): boolean {
  try {
    const parsed = new URL(url);
    return parsed.protocol === 'http:' || parsed.protocol === 'https:';
  } catch {
    return false;
  }
}

Dependency Security:

  • 📦 Minimal Dependencies: 28 devDependencies, 1 production dependency
  • 🔒 Lock Files: package-lock.json ensures reproducible builds
  • 🔍 Weekly Scans: Dependabot monitors for vulnerabilities
  • ✅ Automated Updates: Auto-merge dev dependency patches

Code Security:

  • 🔍 CodeQL SAST: Scans for OWASP Top 10, CWE Top 25
  • 📝 ESLint: Enforces secure coding patterns
  • ⚡ Type Safety: TypeScript type system with strict checks
  • 🔒 No eval(): No dynamic code execution

Security Benefits:

  • Prevents XSS attacks via sanitization
  • Detects vulnerabilities before production
  • Minimizes supply chain attack surface
  • Enforces secure coding standards

Layer 4: Data Security

Data Minimization:

  • No User Data: No authentication, no user accounts
  • Public Data Only: European Parliament open data sources
  • No Cookies: No tracking, no session data
  • No Analytics: No third-party tracking (privacy by design)

Data Validation:

// src/clients/ep-mcp-client.ts - Build-time data validation
// MCP responses are validated and sanitized before HTML generation
const rawData = await mcpClient.callTool('get_meps', params);
const sanitizedName = escapeHTML(rawData.name);
const validUrl = isSafeURL(rawData.photoUrl) ? rawData.photoUrl : '';

Security Benefits:

  • GDPR compliance by design (no PII)
  • No data breach risk (no sensitive data)
  • Privacy-preserving (no tracking)
  • Integrity protection (schema validation)

Layer 5: Storage Security

Git-Backed Security:

  • 💾 Immutable History: All changes tracked in Git
  • ✍️ Signed Commits: (Future) GPG-signed commits for authenticity
  • 🔒 Branch Protection: Main branch requires reviews
  • 🔐 Required Checks: Tests + CodeQL + REUSE must pass

Repository Security:

# Branch protection rules (main branch)
- Require pull request reviews: 1 reviewer
- Dismiss stale reviews: true
- Require status checks: [CodeQL, REUSE, npm audit]
- Require signed commits: false (future: true)
- Lock branch: false

Security Benefits:

  • Complete audit trail of all changes
  • Prevents unauthorized modifications
  • Enables instant rollback
  • Detects unauthorized access

Layer 6: Infrastructure Security

GitHub Actions Security:

  • ☁️ Ephemeral Runners: Fresh VM for each build
  • 🔒 Minimal Secrets: Only GITHUB_TOKEN (auto-generated)
  • 📌 SHA Pinning: Actions pinned to specific commits
  • 🔐 Read-Only Tokens: Restricted permissions

Build Environment:

permissions:
  contents: read # Read repository
  pages: write # Deploy to GitHub Pages
  id-token: write # OIDC token for GitHub Pages
  security-events: write # CodeQL results

Security Benefits:

  • No persistent infrastructure to compromise
  • Secrets automatically rotated
  • Supply chain attack prevention (pinned actions)
  • Least privilege access (scoped tokens)

Layer 7: Monitoring & Detection

Continuous Monitoring:

  • 🔍 CodeQL: Every push, every PR
  • 📦 Dependabot: Weekly dependency scans
  • 🔒 Secret Scanning: (GitHub built-in, not applicable for public repo)
  • 📊 Workflow Monitoring: Build success/failure tracking

Audit Logging:

  • Git History: All code changes logged
  • GitHub Actions Logs: 90-day retention
  • Security Events: Dependabot/CodeQL alerts logged
  • Deployment History: GitHub Pages deployment log

Security Benefits:

  • Early vulnerability detection
  • Real-time security monitoring
  • Complete audit trail
  • Incident response capabilities

Strategic Implementation Summary

The defense-in-depth approach ensures:

  1. No Single Point of Failure: Compromise of one layer doesn't break entire security
  2. Overlapping Controls: Multiple layers protect same assets (e.g., XSS prevented by CSP + sanitization + CodeQL)
  3. Detection at Multiple Levels: Security events detected at application layer, infrastructure layer, and monitoring layer
  4. Graceful Degradation: If one control fails, others still provide protection

Example Attack Scenario:

🚨 XSS Attack Attempt via European Parliament Data
├─ Layer 1 (CDN): ✅ Passes (static content delivery)
├─ Layer 2 (Network): 🛡️ No JavaScript in output (architectural prevention)
├─ Layer 3 (Application): 🧹 escapeHTML() sanitizes malicious content
├─ Layer 4 (Data): ✅ Schema validation rejects invalid input
├─ Layer 6 (Infrastructure): 🔒 Build fails if XSS in templates
└─ Layer 7 (Monitoring): 🔍 CodeQL detects XSS vulnerability in code

Result: Attack blocked by 4 independent layers

🎯 Threat Model

Note: This section provides a summary of the threat model. For comprehensive threat analysis including detailed STRIDE analysis, attack scenarios, and mitigation strategies, see THREAT_MODEL.md.

Executive Summary

Assets

Asset Value Confidentiality Integrity Availability
Generated News Articles High Public High Medium
European Parliament Data Accuracy High Public High Medium
Website Availability Medium N/A N/A Medium
Repository Code Medium Public High Medium
Git History Medium Public High Low

Threat Analysis (STRIDE)

Threat 1: Cross-Site Scripting (XSS) via Parliamentary Data

Category: Injection (STRIDE: Tampering)

Scenario: Malicious actor injects JavaScript via European Parliament API responses, executed in user browsers.

Attack Vector:

  1. Attacker compromises EP API or performs MITM
  2. Injects malicious <script> tags in session titles or descriptions
  3. News generator includes malicious script in HTML
  4. User browsers execute script, potentially redirecting users to malicious sites

Likelihood: Low (EP API is authoritative source, HTTPS prevents MITM)

Impact: High (could compromise user trust, redirect to malicious sites)

Controls:

  • Input Validation: Schema validation on MCP responses
  • HTML Sanitization: escapeHTML() encodes all dangerous characters
  • Entity Encoding: Convert <, >, &, ", ' to HTML entities
  • URL Validation: isSafeURL() validates URL schemes (http/https only)
  • No JavaScript: Generated articles contain zero JavaScript — XSS cannot execute in the output
  • Testing: ESLint security plugin, XSS test cases

Residual Risk: Low - Multiple defense layers make successful XSS extremely difficult

MITRE ATT&CK Mapping: T1189 (Drive-by Compromise)


Threat 2: Supply Chain Attack via npm Dependencies

Category: Elevation of Privilege (STRIDE: Elevation of Privilege)

Scenario: Malicious code injected into npm dependency, executed during news generation.

Attack Vector:

  1. Attacker compromises npm package used by project
  2. Malicious code injected into package update
  3. Dependabot creates PR with compromised package
  4. PR merged without detecting malicious code
  5. GitHub Actions executes malicious code with write access to repository

Likelihood: Low (minimal dependencies, Dependabot alerts, code review)

Impact: High (could compromise repository, inject malicious content)

Controls:

  • Minimal Dependencies: 28 devDependencies, 1 production dependency
  • Dependabot: Automated vulnerability scanning, weekly updates
  • npm audit: CI validation fails on moderate+ vulnerabilities
  • Code Review: All PRs require review before merge
  • Version Locking: package-lock.json prevents unexpected updates
  • SBOM: Software Bill of Materials for releases
  • SHA Pinning: GitHub Actions pinned to commit SHA

Residual Risk: Low - Multiple validation layers and minimal attack surface

MITRE ATT&CK Mapping: T1195.002 (Supply Chain Compromise: Compromise Software Supply Chain)


Threat 3: Data Integrity - Incorrect News Generation

Category: Information Disclosure / Tampering (STRIDE: Tampering)

Scenario: Incorrect or misleading news articles generated due to API changes, bugs, or data corruption.

Attack Vector:

  1. European Parliament API changes data format
  2. MCP client fails to validate new format
  3. News generator produces incorrect articles
  4. Public consumes misleading information about parliamentary activities

Likelihood: Medium (APIs evolve, schema drift possible)

Impact: High (misinformation damages credibility, public trust)

Controls:

  • Schema Validation: Strict JSON schema validation on MCP responses
  • Type Checking: Enforce expected data types
  • Fallback Content: Graceful degradation to placeholder content
  • Error Logging: All validation failures logged for investigation
  • Manual Review: Generated content should be spot-checked (future)
  • ⚠️ Automated Testing: Integration tests validate MCP client (current)
  • 🔮 Digital Signatures: Future enhancement for content verification

Residual Risk: Medium - Schema validation reduces risk, but manual review not automated

MITRE ATT&CK Mapping: T1565.001 (Data Manipulation: Stored Data Manipulation)


Threat 4: Denial of Service - GitHub Actions Downtime

Category: Denial of Service (STRIDE: Denial of Service)

Scenario: GitHub Actions unavailable, preventing news generation.

Attack Vector:

  1. GitHub Actions experiences downtime (service interruption)
  2. Scheduled workflow fails to execute
  3. News articles not generated for extended period
  4. Website becomes stale, missing recent parliamentary activities

Likelihood: Low (GitHub has high availability SLA)

Impact: Medium (24-hour RTO acceptable per classification)

Controls:

  • Manual Trigger: workflow_dispatch allows manual execution
  • Cached Content: Previous articles remain available
  • Monitoring: GitHub Actions status visible
  • RTO/RPO Alignment: 24-hour RTO, 1-day RPO acceptable
  • 🔮 Alternative Hosting: Future multi-region deployment
  • 🔮 Uptime Monitoring: Future Pingdom/StatusCake integration

Residual Risk: Low - GitHub's infrastructure is highly reliable, manual trigger available

MITRE ATT&CK Mapping: T1499 (Endpoint Denial of Service)


Threat 5: Repository Compromise - Unauthorized Code Changes

Category: Tampering / Elevation of Privilege (STRIDE: Tampering, Elevation of Privilege)

Scenario: Attacker gains unauthorized access to repository, injects malicious code.

Attack Vector:

  1. Attacker compromises developer account (phishing, credential theft)
  2. Pushes malicious code to repository
  3. Malicious code bypasses code review (social engineering)
  4. GitHub Actions executes malicious code with repository write access
  5. Malicious content injected into generated articles

Likelihood: Low (GitHub account security, branch protection, code review)

Impact: High (could compromise website integrity, user trust)

Controls:

  • Branch Protection: Required reviews, status checks before merge
  • Code Review: All changes reviewed by maintainers
  • CodeQL: Automated SAST scanning detects common vulnerabilities
  • ESLint Security: Static analysis for security issues
  • MFA Required: GitHub organization requires MFA for all members
  • Audit Logs: Git history provides immutable audit trail
  • Revert Capability: Easy rollback via git revert

Residual Risk: Low - Multiple security layers prevent and detect unauthorized changes

MITRE ATT&CK Mapping: T1078 (Valid Accounts), T1190 (Exploit Public-Facing Application)


Threat 6: MCP Server Compromise - Malicious MCP Server

Category: Spoofing / Tampering (STRIDE: Spoofing, Tampering)

Scenario: Malicious MCP server provides false data or attempts to compromise news generator.

Attack Vector:

  1. Attacker replaces legitimate MCP server with malicious version
  2. Malicious server returns crafted responses
  3. News generator processes malicious data
  4. Articles contain injected content or malicious links

Likelihood: Very Low (MCP server runs locally, no external MCP server connections)

Impact: High (could inject malicious content, compromise integrity)

Controls:

  • Localhost Only: MCP server runs on localhost, not exposed externally
  • Process Isolation: MCP server spawned by news generator, not pre-existing process
  • Input Validation: All MCP responses validated against schema
  • Ephemeral Execution: MCP server destroyed after news generation
  • No Persistent State: MCP server has no persistence between runs
  • 🔮 Mutual TLS: Future enhancement for authenticated MCP communication
  • 🔮 Response Signatures: Future cryptographic verification of MCP responses

Residual Risk: Very Low - MCP server process isolation and input validation prevent compromise

MITRE ATT&CK Mapping: T1557 (Adversary-in-the-Middle)


Threat Summary Matrix

Threat Category Likelihood Impact Residual Risk Priority
XSS via Parliamentary Data Injection Low High Low P3
Supply Chain Attack Privilege Escalation Low High Low P2
Data Integrity Issues Tampering Medium High Medium P1
GitHub Actions Downtime Denial of Service Low Medium Low P4
Repository Compromise Tampering Low High Low P2
MCP Server Compromise Spoofing Very Low High Very Low P5

Priority Key:

  • P1: High priority - requires additional controls
  • P2: Medium priority - monitor and review
  • P3: Low priority - current controls sufficient
  • P4-P5: Very low priority - accept risk

Risk Treatment Plan:

  • P1 (Data Integrity): Implement automated content verification (Q3 2026)
  • P2 (Supply Chain, Repository): Continue current controls, annual review
  • P3-P5: Accept residual risk, monitor for changes

📋 Compliance Framework Mapping

EU Parliament Monitor aligns with multiple compliance frameworks to ensure security, privacy, and operational excellence.

graph TD
    subgraph "Compliance Integration"
        A[🏛️ Compliance<br>Framework] --> B[🔍 NIST CSF 2.0]
        A --> C[🔐 ISO 27001:2022]
        A --> D[🛡️ CIS Controls v8.1]
        A --> E[🇪🇺 GDPR]
        A --> F[🇪🇺 NIS2 Directive]
        A --> G[🇪🇺 EU CRA]

        B --> H[🎯 Govern]
        B --> I[👁️ Identify]
        B --> J[🛡️ Protect]
        B --> K[🔎 Detect]
        B --> L[⚡ Respond]
        B --> M[🔄 Recover]

        C --> N[👥 A.9 Access<br>Control]
        C --> O[🔒 A.8 Asset<br>Management]
        C --> P[⚙️ A.5 Policies]
        C --> Q[📡 A.8 Security<br>Operations]

        D --> R[🔧 Control 1:<br>Inventory]
        D --> S[🔒 Control 4:<br>Secure Config]
        D --> T[🛡️ Control 10:<br>Malware Defense]
    end

    style A fill:#673AB7,stroke:#311B92,stroke-width:2px,color:white,font-weight:bold
    style B,C,D,E,F,G fill:#00C853,stroke:#007E33,stroke-width:2px,color:white,font-weight:bold
    style H,I,J,K,L,M fill:#2979FF,stroke:#0D47A1,stroke-width:2px,color:white,font-weight:bold
    style N,O,P,Q fill:#FFD600,stroke:#FF8F00,stroke-width:2px,color:black,font-weight:bold
    style R,S,T fill:#FF3D00,stroke:#BF360C,stroke-width:2px,color:white,font-weight:bold
    classDef default font-weight:bold
Loading

NIST Cybersecurity Framework 2.0

Govern (GV)

  • GV.PO-01: Security policies aligned with ISMS-PUBLIC
  • GV.RM-01: Risk management via threat model
  • GV.SC-01: Supply chain security (Dependabot, SBOM)

Identify (ID)

  • ID.AM-01: Asset inventory (threat model assets)
  • ID.RA-01: Vulnerability scanning (Dependabot, CodeQL)
  • ID.RA-02: Threat intelligence (GitHub Security Advisories)

Protect (PR)

  • PR.AA-01: Authentication (GitHub CODEOWNERS, MFA)
  • PR.DS-01: Data protection (HTTPS-only, CSP)
  • PR.IP-01: Baseline configurations (ESLint, branch protection)

Detect (DE)

  • DE.AE-02: Security event analysis (GitHub Actions logs)
  • DE.CM-01: Network monitoring (CDN logs)
  • DE.CM-08: Vulnerability scans (weekly Dependabot)

Respond (RS)

  • RS.MA-01: Incident response plan (SECURITY.md)
  • RS.CO-02: Coordinated disclosure (90-day embargo)
  • RS.AN-03: Forensics (Git history, Actions logs)

Recover (RC)

  • RC.RP-01: Recovery plan (runbooks)
  • RC.CO-01: Communication plan (SECURITY.md)
  • RC.IM-01: Recovery improvements (lessons learned)

ISO 27001:2022 Alignment

A.5 Organizational Controls

  • A.5.1: Information security policies ✅
  • A.5.10: Acceptable use of information ✅
  • A.5.23: Information security for cloud services ✅

A.8 Technological Controls

  • A.8.3: Information backup ✅ (Git)
  • A.8.9: Configuration management ✅ (Infrastructure as Code)
  • A.8.23: Web filtering ✅ (CSP)
  • A.8.24: Use of cryptography ✅ (TLS 1.3, HTTPS)
  • A.8.28: Secure coding ✅ (CodeQL, ESLint)

CIS Controls v8.1 Implementation

CIS Control Safeguard Description Implementation IG Level Status
1 1.1 Establish and maintain detailed enterprise asset inventory SBOM (sbom.json), package.json IG1
2 2.1 Establish and maintain software inventory npm dependency tree, TypeScript source IG1
2 2.2 Ensure authorized software is supported Dependabot updates, Node.js 25 Current (upgrading to Node.js 26 LTS ~Apr 2026) IG1
4 4.1 Establish and maintain secure configuration process ESLint, Prettier, htmlhint rules IG1
4 4.7 Manage default accounts No default accounts (static site) IG1 N/A
5 5.1 Establish and maintain inventory of accounts GitHub organization accounts IG1
5 5.3 Disable dormant accounts GitHub access review process IG1
6 6.1 Establish access control foundation GitHub MFA, branch protection rules IG1
6 6.2 Establish access grants for least privilege contents:write only for GitHub Actions IG1
7 7.1 Establish vulnerability management process Dependabot automated PRs, npm audit IG1
7 7.4 Perform automated vulnerability scanning CodeQL SAST weekly scans IG2
7 7.5 Perform automated patch management Dependabot auto-updates IG2
8 8.2 Collect audit logs GitHub Actions logs 90-day retention IG1
8 8.5 Collect detailed audit logs Git commit history (immutable) IG2
9 9.1 Ensure use of only fully supported browsers Static HTML/CSS/JS, no custom browser code IG1 N/A
11 11.2 Perform automated backups Git distributed backup (all clones) IG1
11 11.3 Protect recovery data GitHub repository integrity IG1
12 12.2 Establish network infrastructure management No server infrastructure (static site) IG1 N/A
14 14.1 Establish/maintain security awareness CONTRIBUTING.md, SECURITY.md IG1
16 16.1 Establish secure application development process CodeQL, ESLint security, branch protection IG1
16 16.2 Establish secure coding training Secure coding guidelines documented IG2
16 16.6 Remediate detected software vulnerabilities 7-day SLA for high CVEs, Dependabot IG2
18 18.1 Establish penetration testing program Future DAST implementation (Q3 2026) IG3 🔮

GDPR Compliance

Data Protection Principles:

Principle Implementation Article
Lawfulness, Fairness, Transparency Public data, no user tracking Art. 5(1)(a)
Purpose Limitation Single purpose: EU Parliament news Art. 5(1)(b)
Data Minimisation No PII collected, public data only Art. 5(1)(c)
Accuracy European Parliament authoritative source Art. 5(1)(d)
Storage Limitation No persistent user data stored Art. 5(1)(e)
Integrity & Confidentiality HTTPS, TLS 1.3, CSP headers Art. 5(1)(f)
Accountability ISMS policies, audit trail Art. 5(2)

Data Subject Rights:

  • Not applicable (no personal data collected)
  • No data processing activities requiring GDPR compliance

NIS2 Directive Compliance

Risk Management Measures (Article 21):

  • ✅ Risk analysis (threat model)
  • ✅ Incident handling (SECURITY.md)
  • ✅ Business continuity (resilience section)
  • ✅ Supply chain security (Dependabot, SBOM)
  • ✅ Secure development (CodeQL, ESLint)
  • ✅ Vulnerability management (weekly scans)

Reporting Obligations (Article 23):

  • 24-hour initial notification
  • Incident details via security@hack23.com
  • Follow-up reports as needed

EU Cyber Resilience Act (CRA) Alignment

Essential Cybersecurity Requirements:

Requirement Implementation Annex I Reference
Secure by Default HTTPS-only, CSP, minimal attack surface Part I, §1
Vulnerability Handling Coordinated disclosure, 90-day embargo Part I, §2
Security Updates Dependabot automated PRs, weekly scans Part I, §2
Software Bill of Materials npm list --json > sbom.json Part I, §2(3)
Secure Development CodeQL SAST, secure coding guidelines Part II, §1
Incident Reporting SECURITY.md, GitHub Security Advisories Part II, §2

Conformity Assessment:

  • Category: Non-critical product (static website generator)
  • No CE marking required
  • Self-assessment sufficient
  • Documentation publicly available (this document)

Compliance Evidence Location

Framework Evidence Documents Repository Locations
ISO 27001 SECURITY_ARCHITECTURE.md, ISMS-PUBLIC This document, ISMS-PUBLIC
NIST CSF THREAT_MODEL.md, WORKFLOWS.md THREAT_MODEL.md, WORKFLOWS.md
CIS Controls Security controls documentation This document (Security Controls section)
GDPR Privacy policy (no data collection) This document (Data Protection section)
NIS2 Incident response plan SECURITY.md
EU CRA SBOM, vulnerability disclosure sbom.json, SECURITY.md

✅ Compliance Matrix

ISO 27001:2022 Annex A Controls Mapping

Theme 5 — Organizational Controls (5.1–5.37)

Control Requirement Implementation Status Evidence
5.1 Information security policies ISMS-PUBLIC policy reference This document, ISMS-PUBLIC repo
5.2 Information security roles and responsibilities CEO as document owner Document header
5.9 Inventory of information and other assets Asset inventory in threat model Threat Model section
5.12 Classification of information Public data classification Executive Summary, Classification Framework
5.14 Information transfer TLS 1.3 in transit Network Security section
5.15 Access control Minimal GitHub Actions permissions Authentication & Authorization section
5.16 Identity management GitHub account MFA GitHub organization settings
5.17 Authentication information Code review requirements Branch protection rules
5.24 Information security incident management planning and preparation GitHub Issues for incidents CONTRIBUTING.md
5.29 Information security during disruption Manual trigger, cached content Infrastructure Security section
5.36 Compliance with policies, rules and standards This document Compliance Matrix section
5.37 Documented operating procedures CI/CD workflows documented .github/workflows/

Theme 6 — People Controls (6.1–6.8)

Control Requirement Implementation Status Evidence
6.3 Information security awareness, education and training CONTRIBUTING.md security guidance CONTRIBUTING.md

Theme 7 — Physical Controls (7.1–7.14)

Control Requirement Implementation Status Evidence
7.10 Storage media Git-based version control GitHub repository

Theme 8 — Technological Controls (8.1–8.34)

Control Requirement Implementation Status Evidence
8.3 Information access restriction GITHUB_TOKEN auto-expiry GitHub Actions configuration
8.7 Protection against malware CodeQL, ESLint security Application Security section
8.8 Management of technical vulnerabilities Dependabot, npm audit Dependency Security section
8.13 Information backup Git version control GitHub repository
8.15 Logging GitHub Actions logs GitHub Actions audit logs
8.16 Monitoring activities Dependabot & CodeQL continuous scans Security Operations section
8.20 Networks security HTTPS only, localhost MCP Network Security section
8.24 Use of cryptography TLS 1.3, GitHub Pages HTTPS Network Security section
8.25 Secure development lifecycle SAST, dependency scanning Application Security section
8.27 Secure system architecture and engineering principles Code review, branch protection Security Operations section
8.33 Test information No production data in tests test/fixtures/ uses mock data

Overall ISO 27001:2022 Compliance: ✅ Compliant (25/25 applicable controls implemented)

NIST CSF 2.0 Subcategory Mappings

Subcategory Description Implementation Status
GV.OC-01 Organizational mission understood and informs cybersecurity risk management Democratic transparency mandate
GV.OC-05 Outcomes, capabilities, and services that the organization depends on are understood and communicated to supply chain Public ISMS documentation
GV.RM-01 Risk management objectives are established and agreed to by organizational stakeholders ISMS risk framework
GV.RM-02 Risk appetite and risk tolerance statements are established, communicated, and maintained Low risk tolerance (public platform)
GV.PO-01 Policy for managing cybersecurity risks is established based on organizational context ISMS-PUBLIC policies
GV.RR-01 Organizational leadership is responsible and accountable for cybersecurity risk CEO document ownership
GV.SC-01 A cybersecurity supply chain risk management program, strategy, objectives, policies, and processes are established Dependabot, SHA-pinned actions
GV.SC-06 Planning and due diligence are performed to reduce risks before entering into formal supplier or other third-party relationships Minimal dependencies, SCA scanning
ID.AM-01 Inventories of hardware managed by the organization are maintained SBOM, package.json, GitHub repo
ID.AM-02 Inventories of software, services, and systems managed by the organization are maintained npm dependency tree, Dependabot
ID.AM-08 Systems, hardware, software, services, and data are managed throughout their life cycles ARCHITECTURE.md C4 diagrams
ID.RA-01 Vulnerabilities in assets are identified, validated, and recorded CodeQL SAST, Dependabot SCA
ID.RA-05 Threats, vulnerabilities, likelihoods, and impacts are used to understand inherent risk and inform risk response prioritization THREAT_MODEL.md STRIDE analysis
ID.RA-06 Risks are prioritized, responded to, and communicated to applicable stakeholders Risk register, threat model
ID.IM-01 Improvements are identified from security assessments Annual security review cycle
PR.AA-01 Identities and credentials for authorized users, services, and hardware are managed by the organization GitHub MFA, auto-expiring GITHUB_TOKEN
PR.AA-05 Access permissions, entitlements, and authorizations are defined in a policy, managed, enforced, and reviewed Branch protection, CODEOWNERS, least privilege
PR.AT-01 Personnel are provided with awareness and training so that they possess the knowledge and skills to perform general tasks with cybersecurity risks in mind CONTRIBUTING.md, SECURITY.md
PR.DS-01 The confidentiality, integrity, and availability of data-at-rest are protected Git repository integrity, immutable history
PR.DS-02 The confidentiality, integrity, and availability of data-in-transit are protected TLS 1.3 HTTPS-only, GitHub Pages enforcement
PR.DS-10 The confidentiality, integrity, and availability of data-in-use are protected No PII processing, public data only
PR.IR-01 Networks and environments are protected from unauthorized logical access and usage No server network, localhost MCP only
PR.IR-02 The organization's technology assets are protected from environmental threats No sensitive data collected
PR.PS-01 Configuration management practices are established and applied ESLint config, branch protection rules
PR.PS-02 Software is maintained, replaced, and removed commensurate with risk Dependabot, npm audit, Node.js LTS
DE.AE-02 Potentially adverse events are analyzed to better characterize them and detect cybersecurity incidents GitHub Security Alerts, CodeQL findings
DE.AE-06 Information on adverse events is provided to authorized staff and tools Public SECURITY.md, GitHub Security Advisories
DE.CM-01 Networks and network services are monitored to find potentially adverse events Dependabot, CodeQL, npm audit continuous scanning
DE.CM-09 Computing hardware and software, runtime environments, and their data are monitored to find potentially adverse events GitHub Actions logs, audit trail
RS.MA-01 The incident response plan is executed in coordination with relevant third parties once an incident is declared SECURITY.md incident procedures
RS.AN-03 Analysis is performed to establish what has taken place during an incident and the root cause of the incident Git history, Actions logs forensics
RS.CO-02 Internal and external stakeholders are notified of incidents in a timely manner GitHub Security Advisories, SECURITY.md
RS.MI-02 Incidents are contained Revert commits, disable workflows
RC.RP-01 The recovery portion of the incident response plan is executed once initiated from the incident response process BCPPlan.md recovery procedures
RC.CO-03 Recovery activities and progress in restoring operational capabilities are communicated to designated internal and external stakeholders GitHub Issues, SECURITY.md
RC.IM-01 Recovery plans incorporate lessons learned Post-incident reviews documented

Overall NIST CSF 2.0 Compliance: ✅ Aligned (36/36 subcategories implemented across all 6 functions: GV, ID, PR, DE, RS, RC)

GDPR Compliance

Article Requirement Implementation Status Evidence
Art. 5 Principles of Processing No PII collected No tracking, no forms, static site
Art. 25 Data Protection by Design Security by design architecture Executive Summary, no PII by design
Art. 30 Records of Processing No processing of personal data Static site, no user data
Art. 32 Security of Processing Defense-in-depth controls Security Controls section
Art. 33 Breach Notification Incident response via GitHub Issues CONTRIBUTING.md
Art. 35 DPIA Not required (no PII) N/A - no high-risk processing

GDPR Compliance: ✅ Compliant - No personal data processing, data protection by design

DPIA Required: ❌ No - Static website with no PII collection

NIS2 Directive Compliance

Article Requirement Implementation Status Evidence
Art. 20 Cybersecurity Risk Management Threat modeling, risk assessment Threat Model section
Art. 21 Cybersecurity Measures Defense-in-depth controls Security Controls section
Art. 21(2)(a) Risk Analysis & Security Policies ISMS-PUBLIC policy framework ISMS alignment throughout
Art. 21(2)(b) Incident Handling GitHub Issues, audit logs Security Operations section
Art. 21(2)(c) Business Continuity RTO/RPO defined, manual trigger Executive Summary
Art. 21(2)(d) Supply Chain Security Dependabot, SHA-pinned actions Dependency Security section
Art. 21(2)(e) Effectiveness of Measures Annual review, monitoring Document header (annual review)
Art. 23 Incident Reporting 24-hour reporting to CSIRT ⚠️ Future implementation

NIS2 Compliance: ✅ Compliant - 7/8 requirements implemented Gap: Automated CSIRT reporting (future enhancement)

EU Cyber Resilience Act (CRA) Alignment

Requirement Implementation Status Evidence
SBOM Generated for releases .github/workflows/release.yml
Vulnerability Disclosure Public security advisories GitHub Security Advisories
Security Updates Dependabot automated updates .github/dependabot.yml
Security by Design Threat modeling, secure architecture This document
Conformity Assessment Annual security review Document header

CRA Alignment: ✅ Aligned - All applicable requirements implemented


🔍 Security Operations

Security Monitoring

Current Monitoring:

  • GitHub Actions Logs: Job execution logs retained for 90 days
  • CodeQL Alerts: Automated SAST findings triaged weekly
  • Dependabot Alerts: Dependency vulnerabilities addressed within 7 days
  • npm audit: Pre-commit and CI validation
  • Git Audit Trail: Immutable commit history

Future Monitoring (FUTURE_SECURITY_ARCHITECTURE.md):

  • 🔮 Uptime Monitoring: Pingdom/StatusCake (Q2 2026)
  • 🔮 Error Tracking: Sentry integration (Q2 2026)
  • 🔮 Security Metrics Dashboard: ISMS compliance scores (Q3 2026)

Incident Response

Incident Classification:

  • P0 (Critical): Repository compromise, malicious content injection
  • P1 (High): XSS vulnerability, dependency compromise
  • P2 (Medium): Data integrity issues, workflow failures
  • P3 (Low): Documentation errors, non-critical bugs

Response Procedures:

  1. Detection: GitHub Security Advisories, Dependabot alerts, manual reports
  2. Containment: Revert commits, disable workflows, remove compromised content
  3. Investigation: Review git logs, GitHub Actions logs, CodeQL findings
  4. Remediation: Apply patches, update dependencies, fix vulnerabilities
  5. Recovery: Deploy fixes, verify integrity, resume operations
  6. Post-Incident Review: Document lessons learned, update threat model

Communication:

  • GitHub Issues for tracking
  • Security Advisories for public disclosure
  • CHANGELOG.md for user notification

Vulnerability Management

See dedicated 🔍 Vulnerability Management section above for comprehensive scanning, SLA targets, and remediation processes.


📊 Security Metrics

Current Metrics

Metric Target Current Status
Known Vulnerabilities 0 0
Dependabot Alert Response Time < 7 days < 48 hours
Code Coverage > 80% 82%+
CodeQL Findings 0 critical/high 0
Security Test Pass Rate 100% 100%
Uptime SLA > 99% GitHub Pages SLA

Security Testing

Automated Testing:

  • Unit Tests: 87 tests covering core functionality
  • Integration Tests: 82 tests for MCP client, workflows
  • E2E Tests: 60+ Playwright tests (accessibility, responsive, multi-language)
  • SAST: CodeQL, ESLint security plugin
  • SCA: Dependabot, npm audit
  • HTML Validation: htmlhint in CI
  • ⚠️ DAST: Future implementation (Q3 2026)

Test Coverage:

  • Lines: 82%+
  • Branches: 83%+
  • Functions: 89%+
  • Statements: 82%+

OpenSSF Security Badges

EU Parliament Monitor demonstrates security excellence through public, verifiable evidence per Hack23 ISMS Open Source Policy:

Badge Status Score/Level Description
OpenSSF Scorecard ✅ Implemented Target ≥7.0 Supply chain security assessment
CII Best Practices 📝 Registration Pending Target: Passing Open source development best practices
SLSA Provenance ✅ Implemented Level 3 Build attestations and SBOM generation
SonarCloud ✅ Implemented Target: A Code quality and security analysis
FOSSA 📝 Setup Required Target: Clean License compliance scanning
REUSE ✅ Implemented Passing FSFE license header compliance

Badge Links:


📚 Documentation as Code Security

Automated Documentation Generation

The release workflow implements documentation-as-code principles, automatically generating comprehensive technical documentation with every release:

Documentation Pipeline:

graph LR
    A[Release Trigger] --> B[Run Tests]
    B --> C[Generate Coverage]
    C --> D[Generate API Docs]
    D --> E[Copy Reports]
    E --> F[Create Index]
    F --> G[Commit to Main]
    G --> H[Deploy to GitHub Pages]
Loading

Generated Documentation

Documentation Type Generator Security Controls
API Documentation JSDoc Input sanitization, no script injection
Test Coverage Vitest HTML Static HTML, no dynamic content
E2E Test Reports Playwright Screenshots sanitized, no PII
Documentation Index Custom script Static generation, XSS-safe

Security Benefits

Integrity:

  • Version Controlled: All documentation committed to git
  • Immutable History: Complete audit trail of changes
  • Reproducible: Regenerate docs from any release tag
  • Signed: Part of SLSA Level 3 attested artifacts

Transparency:

  • Public Access: Documentation on GitHub Pages
  • Evidence-Based: Generated from actual code and tests
  • Real-Time: Updated with every release
  • Comprehensive: API, coverage, E2E, all in one place

Compliance:

  • ISMS §3.2: Architecture documentation requirements met
  • ISO 27001 A.12.1.1: Documented operating procedures
  • Audit Trail: Full documentation history in git
  • Evidence: Automated generation eliminates documentation drift

Security Controls

Control Implementation Purpose
Static Generation No server-side execution Eliminates injection attacks
Input Sanitization JSDoc, HTML encoding Prevents XSS in generated docs
Access Control GitHub Pages authentication Public read, write via workflow only
Audit Trail Git commits for all changes Complete history and accountability
Attestations SLSA Level 3 provenance Verifiable documentation integrity

ISMS Evidence

Future Enhancements

See FUTURE_WORKFLOWS.md for planned documentation improvements:

  • Automated architecture diagram generation
  • Interactive documentation search
  • Documentation versioning (per release)
  • PDF export for compliance reports

🔒 Conclusion

EU Parliament Monitor implements a security-by-design architecture with defense-in-depth controls appropriate for a public information platform. The static site architecture eliminates common attack vectors (SQL injection, session hijacking, server-side vulnerabilities) while maintaining transparency and accessibility.

Key Security Strengths:

  1. Minimal Attack Surface: Static content, no databases, no server-side execution
  2. Automated Security: CodeQL, Dependabot, npm audit prevent vulnerabilities
  3. Supply Chain Security: SHA-pinned actions, minimal dependencies, SBOM generation
  4. Data Integrity: Input validation, HTML sanitization, CSP enforcement
  5. Compliance: ISO 27001, GDPR, NIS2, EU CRA aligned
  6. Transparency: Public code, public security advisories, ISMS framework

Residual Risks:

  • Medium: Data integrity (manual review not automated) - Addressed in Q3 2026
  • Low: Supply chain attacks - Mitigated by minimal dependencies and Dependabot
  • Low: Repository compromise - Mitigated by branch protection and code review

Future Enhancements:


Document Approval:

Role Name Date Signature
CEO (Document Owner) [Name] 2026-04-20 [Electronic]
CISO [Name] 2026-04-20 [Electronic]

Next Review Date: 2027-04-20


This document is maintained as part of Hack23 AB's Information Security Management System (ISMS)
ISMS Framework: Hack23/ISMS-PUBLIC