SECURITY_ARCHITECTURE.md

July 18, 2026 ยท View on GitHub

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.2 | ๐Ÿ“… Last Updated: 2026-05-03 (UTC)
๐Ÿ”„ Review Cycle: Annual | โฐ Next Review: 2027-05-03
๐Ÿท๏ธ Classification: Public (Open Source European Parliament Monitoring Platform)


๐Ÿ“š Architecture Documentation Map

DocumentFocusDescriptionDocumentation Link
Architecture๐Ÿ›๏ธ ArchitectureC4 model showing current system structureView Source
Future Architecture๐Ÿ›๏ธ ArchitectureC4 model showing future system structureView Source
Mindmaps๐Ÿง  ConceptCurrent system component relationshipsView Source
Future Mindmaps๐Ÿง  ConceptFuture capability evolutionView Source
SWOT Analysis๐Ÿ’ผ BusinessCurrent strategic assessmentView Source
Future SWOT Analysis๐Ÿ’ผ BusinessFuture strategic opportunitiesView Source
Data Model๐Ÿ“Š DataCurrent data structures and relationshipsView Source
Future Data Model๐Ÿ“Š DataEnhanced European Parliament data architectureView Source
Flowcharts๐Ÿ”„ ProcessCurrent data processing workflowsView Source
Future Flowcharts๐Ÿ”„ ProcessEnhanced AI-driven workflowsView Source
State Diagrams๐Ÿ”„ BehaviorCurrent system state transitionsView Source
Future State Diagrams๐Ÿ”„ BehaviorEnhanced adaptive state transitionsView Source
Security Architecture๐Ÿ›ก๏ธ SecurityCurrent security implementationView Source
Future Security Architecture๐Ÿ›ก๏ธ SecuritySecurity enhancement roadmapView Source
Threat Model๐ŸŽฏ SecuritySTRIDE threat analysisView Source
Classification๐Ÿท๏ธ GovernanceCIA classification & BCPView Source
CRA Assessment๐Ÿ›ก๏ธ ComplianceCyber Resilience ActView Source
Workflowsโš™๏ธ DevOpsCI/CD documentationView Source
Future Workflows๐Ÿš€ DevOpsPlanned CI/CD enhancementsView Source
Business Continuity Plan๐Ÿ”„ ResilienceRecovery planningView Source
Financial Security Plan๐Ÿ’ฐ FinancialCost & security analysisView Source
End-of-Life Strategy๐Ÿ“ฆ LifecycleTechnology EOL planningView Source
Unit Test Plan๐Ÿงช TestingUnit testing strategyView Source
E2E Test Plan๐Ÿ” TestingEnd-to-end testingView Source
Performance Testingโšก PerformancePerformance benchmarksView Source
Security Policy๐Ÿ”’ SecurityVulnerability reporting & security policyView 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.54+ (post-2026-04-24 aggregator migration; Look-Ahead epic complete 2026-05-02) publishes 1927+ static HTML articles across 14 languages and 14 article types (breaking, week-ahead, week-in-review, month-ahead, month-in-review, quarter-ahead, quarter-in-review, year-ahead, year-in-review, term-outlook, election-cycle, committee-reports, motions, propositions), generated by 15 unified gh-aw agentic workflows (14 news-<type>.md article workflows + news-translate.md for 14-language flush translation). Per-slug stage budgets (including the minute โ‰ค 45 PR call deadline within the 60-min cap) are sourced from src/config/article-horizons.ts. 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 validators โ€” src/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:

DimensionLevelRationale
ConfidentialityPublic (Level 1)All data from European Parliament open data sources, no private information
IntegrityMedium (Level 2)News accuracy critical for democratic transparency, incorrect information could mislead public
AvailabilityMedium (Level 2)Daily updates expected, but 24-hour outages acceptable
RTO24 hoursManual workflow trigger available, automated recovery via GitHub Actions
RPO1 dayDaily 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

FrameworkStatusEvidence
ISO 27001โœ… CompliantArchitecture documentation, access control, vulnerability management
GDPRโœ… CompliantNo PII collected, data protection by design
NIS2โœ… CompliantStatic site architecture, minimal attack surface, incident response
EU CRAโœ… AlignedSBOM generation, vulnerability disclosure, security updates

๐Ÿงฑ gh-aw Defense-in-Depth Security Architecture

Reference: GitHub Agentic Workflows Architecture โ€” the official specification for AW security layers, trust boundaries, and component isolation.

The EU Parliament Monitor implements GitHub Agentic Workflows (gh-aw v0.77.3) with a comprehensive defense-in-depth security architecture aligned to the official gh-aw 3-layer trust model. This architecture ensures that AI-driven news generation operates within strict security boundaries โ€” even if a compromised agent executes arbitrary code within its container, the layered isolation prevents unauthorized access or data exfiltration.

๐Ÿ—๏ธ gh-aw Trust Model Overview

The gh-aw architecture implements three nested trust layers that provide independent, composable security guarantees:

LayerTrust BoundaryEnforcementThreat Assumption
๐Ÿ”’ Layer 1: SubstrateHardware โ†’ kernel โ†’ container runtimeGitHub Actions VM, Docker, iptables, MCP GatewayAdversary fully controls user-level containers
๐Ÿ“‹ Layer 2: ConfigurationDeclarative specifications + toolchainSchema validation, SHA pinning, security scannersMisconfiguration, overly permissive specs
๐Ÿ“ Layer 3: PlanStaged execution + output vettingSafeOutputs, Threat Detection, stage boundariesIncorrect plan construction, stage bypass

Adversary Model: An adversary that may compromise untrusted user-level components (containers) and cause them to behave arbitrarily within granted privileges. The adversary may attempt to access other components' state, communicate over unintended channels, abuse legitimate channels for unintended actions, or confuse control logic.

๐Ÿ”’ Layer 1: Substrate-Level Trust (Runtime Isolation)

Purpose: Memory isolation, CPU/resource isolation, kernel-enforced communication boundaries โ€” guarantees that hold even if an untrusted component is fully compromised.

๐ŸŒ Agent Workflow Firewall (AWF)

The AWF containerizes the agent, binds it to a Docker network, and uses iptables to redirect HTTP/HTTPS traffic through a Squid proxy container with a configurable domain allowlist.

EU Parliament Monitor Allowlist (primary groups):

  • โœ… Base infrastructure: defaults, github, node, docker.io family
  • โœ… EU institutional data domains: *.europa.eu, ec.europa.eu, eur-lex.europa.eu, data.ecb.europa.eu and related EP sources
  • โœ… IMF domains: *.imf.org (including api.imf.org)
  • โœ… World Bank domains: *.worldbank.org
  • โœ… Project/platform domains: *.hack23.com, *.euparliamentmonitor.com and related project domains
  • โœ… host.docker.internal:8080 โ€” MCP Gateway (Docker bridge, local-only)
  • โœ… LLM API endpoints โ€” Copilot/Claude/Codex AI inference
  • ๐Ÿ“ Full authoritative list: .github/workflows/shared/config/news-common-settings.md
  • โŒ All other outbound connections BLOCKED (default-deny)

AWF Architecture:

  1. Isolated network namespace with Squid proxy enforcing network.allowed list
  2. Agent container egresses only through Squid โ€” no direct internet access
  3. host.docker.internal routes to MCP Gateway (Docker host alias)
  4. AWF drops iptables capabilities before launching the agent
  5. Chroot mode provides controlled access to host-installed binaries (Node.js 26, npm) via read-only mounts

Security Guarantees:

  • ๐Ÿ›ก๏ธ Prevents data exfiltration to unauthorized domains
  • ๐Ÿ›ก๏ธ Blocks command-and-control channels
  • ๐Ÿ›ก๏ธ Mitigates supply chain compromise (no arbitrary package downloads)
  • ๐Ÿ›ก๏ธ All network requests logged in firewall logs (artifact-preserved)

๐Ÿณ MCP Server Sandboxing

MCP servers execute within isolated Docker containers, enforcing substrate-level separation between the agent and each server instance:

  • Container Isolation: Each MCP server runs in its own Docker container with no shared state
  • Network Controls: Per-container domain allowlists enforced via Squid proxy
  • Tool Allowlisting: Explicit allowed: lists restrict available operations (unlisted tools blocked)
  • Secret Injection: Secrets passed via environment variables, never in configuration files
  • MCP Gateway: gh-aw-mcpg container publishes host port 80 โ†’ container port 8000, spawns isolated MCP server containers via Docker socket

๐Ÿ›ก๏ธ Container Runtime Security

  • Read-only file system for system directories
  • No privileged escalation (--cap-drop=ALL)
  • Resource limits (CPU, memory) enforced by Docker
  • Process isolation via Linux namespaces (PID, network, mount, IPC)

ISMS Alignment: Secure Development Policy ยง Infrastructure Security

๐Ÿ“‹ Layer 2: Configuration-Level Trust (Compilation-Time Security)

Purpose: Constrain which components are loaded, how they are connected, which communication channels are permitted, and what privileges are assigned โ€” validated before runtime.

๐Ÿ” Lock-File Compilation

Pinned Version: GH_AW_VERSION: v0.77.3 (enforced by compile-agentic-workflows.yml)

  1. Schema Validation: All workflow frontmatter validated against JSON schema (valid fields, correct types)
  2. Expression Safety: Only allowlisted expressions permitted โ€” no secrets in expressions
  3. Action SHA Pinning: All actions resolved to immutable commit SHAs (actions/checkout@sha # v4)
  4. Security Scanners: actionlint (workflow linting + shellcheck), zizmor (privilege escalation), poutine (supply chain risks)
  5. Strict Mode Enforcement:
    • โœ— No write permissions at top level
    • โœ“ Explicit network configuration required
    • โœ— No wildcard domains in allowlists
    • โœ— No deprecated fields

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)
  • Direct edits to .lock.yml files blocked by CODEOWNERS
  • Changes to .md sources trigger recompilation via CI

๐Ÿงน Content Sanitization (Activation Boundary)

User-generated content (issue titles, PR bodies, comments) is sanitized before being passed to the agent:

MechanismInput โ†’ OutputProtection
๐Ÿท๏ธ @mention Neutralization@user โ†’ `@user`Prevents unintended notifications
๐Ÿค– Bot Trigger Protectionfixes #123 โ†’ `fixes #123`Prevents automatic issue linking
๐Ÿ”’ XML/HTML Tag Conversion<script> โ†’ (script)Prevents injection via XML tags
๐ŸŒ URI Filteringhttp://evil.com โ†’ (redacted)Restricts to HTTPS from trusted domains
๐Ÿ”ค Unicode NormalizationHomoglyphs โ†’ NormalizedPrevents visual spoofing attacks
๐Ÿ“ Content LimitsLarge payloads โ†’ Truncated0.5 MB max, 65k lines max
๐Ÿšซ Control Character RemovalANSI escapes โ†’ StrippedRemoves terminal manipulation codes

๐Ÿ” Integrity Filtering

The MCP gateway intercepts tool calls and filters content based on author trust and merge status:

  • Public repositories auto-apply min-integrity: approved โ€” restricting content to owners, members, and collaborators
  • Items from blocked users or below minimum trust level removed transparently before AI engine sees them
  • Four configurable levels: merged โ†’ approved โ†’ unapproved โ†’ none (most โ†’ least restrictive)

๐Ÿงฉ Shell Safety Rules

Blocked shell patterns (prompt injection defense):

  • โŒ Nested $() inside $(( )) arithmetic expansion
  • โŒ ${VAR:-$(cmd)} default-with-fallback command substitution
  • โŒ Complex variable indirection chains
  • โœ… Every bash tool invocation requires explicit command + description fields
  • โœ… TypeScript-enforced schema validation at compile time

ISMS Alignment: Secure Development Policy ยง Change Management

๐Ÿ“ Layer 3: Plan-Level Trust (Staged Execution & Output Vetting)

Purpose: Constrain component behavior over time by decomposing workflows into stages with explicit inputs/outputs and mediated transitions. Important external side effects are explicit and undergo thorough vetting.

๐Ÿ›ก๏ธ SafeOutputs Permission Isolation

The SafeOutputs subsystem enforces permission separation โ€” the agent job never has direct write access to external state:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿค– Agent Job               โ”‚     โ”‚  ๐Ÿ” Threat Detection Job  โ”‚     โ”‚  โœ… Safe Output Jobs    โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚     โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚     โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚
โ”‚  โ€ข Read-only permissions    โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  โ€ข Download artifacts     โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  โ€ข create_pull_request  โ”‚
โ”‚  โ€ข Buffered outputs only    โ”‚     โ”‚  โ€ข AI + custom analysis   โ”‚     โ”‚  โ€ข contents: write      โ”‚
โ”‚  โ€ข agent_output.json        โ”‚     โ”‚  โ€ข Secret leak detection  โ”‚     โ”‚  โ€ข pull-requests: write โ”‚
โ”‚  โ€ข aw.patch (git diff)      โ”‚     โ”‚  โ€ข Malicious patch check  โ”‚     โ”‚  โ€ข Scoped permissions   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚  โ€ข Policy violation scan  โ”‚     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                    โ”‚  โ€ข Pass/Fail verdict      โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

EU Parliament Monitor Safe-Output Limits:

  • Default max patch size: 1024 KB (most workflows)
  • Extended limit for news-translate.md: 10240 KB (14-language fan-out)
  • Single PR per workflow run (enforced by gh-aw framework)
  • excluded-files: analysis/**/data/** (prevents large EP API responses from overflowing patch limit)

๐Ÿ” Threat Detection Pipeline

After the agent job completes, a separate detection job downloads buffered artifacts and analyzes them for threats:

Detection Checks:

  • ๐Ÿ”‘ Secret Leaks: API keys, tokens, credentials in outputs
  • ๐Ÿ› Malicious Patches: Backdoors, vulnerabilities, suspicious modifications
  • ๐Ÿ“‹ Policy Violations: Scope violations, unauthorized operations
  • ๐Ÿ”’ Custom Detection: Integration with security scanners (Semgrep, TruffleHog)

Detection Properties:

  • Isolated Execution: Separate job with no write permissions and no access to original agent's runtime state
  • Prompted Analysis: Same AI engine with security-focused system prompt
  • Artifact-Based: Only sees buffered artifacts (outputs, patches, context), not live repository state
  • Blocking Verdict: Must emit "safe" verdict before any safe output jobs execute
  • Fail-Safe: If detection fails, all writes are blocked

๐Ÿ” Secret Redaction

Before workflow artifacts are uploaded, all files in /tmp/gh-aw are scanned and redacted:

  • Automatic Detection: Scans workflow YAML for secrets.* patterns
  • Exact String Matching: Safe string matching (not regex) to prevent injection
  • Partial Visibility: First 3 characters + asterisks for debugging
  • Unconditional Execution: Runs with if: always() even if workflow fails

๐Ÿ“‹ JSONL Audit Trail & Observability

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

  • Log Format: JSON Lines (JSONL) โ€” one tool call per line
  • Log File: agent-stdio.log in workflow run artifacts
  • Retention: 90-day default retention as GitHub Actions artifacts
  • CLI Tools: gh aw logs (analyze runs), gh aw audit (investigate failures), gh aw status (health check)

Logged Data:

  • Timestamp (ISO 8601), tool name + parameters, input/output (sanitized), execution duration, exit code
  • Firewall logs: all network requests with domain, status, bytes transferred
  • Engine logs: token usage, timing, model selection

Use Cases:

  • ๐Ÿ” Security incident investigation
  • ๐Ÿ“‹ ISMS compliance auditing (ยง Audit & Logging)
  • ๐Ÿ› Workflow debugging and optimization
  • ๐Ÿ“Š Cost tracking (token usage per run)
  • ๐Ÿšจ Anomaly detection (baseline deviation)

๐Ÿ‘๏ธ Mandatory Human Review

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

๐Ÿ—๏ธ Complete gh-aw Security Architecture Diagram

flowchart TB
    subgraph Input["๐Ÿ“ฅ Input Layer"]
        WF[/"๐Ÿ“ Workflow .md Source"/]
        IMPORTS[/"๐Ÿ“ฆ Imports and Includes"/]
        EVENT[/"โšก GitHub Event<br/>Schedule / Manual Dispatch"/]
    end

    subgraph Compile["๐Ÿ” Compilation-Time Security (Layer 2)"]
        SCHEMA["๐Ÿ“‹ Schema Validation"]
        EXPR["๐Ÿ”’ Expression Safety Check"]
        PIN["๐Ÿ“Œ Action SHA Pinning"]
        SCAN["๐Ÿ” Security Scanners<br/>actionlint + zizmor + poutine"]
    end

    subgraph Runtime["๐Ÿ›ก๏ธ Runtime Security (Layer 3)"]
        PRE["๐Ÿšฆ Pre-Activation<br/>Role and Permission Checks"]
        ACT["๐Ÿงน Activation<br/>Content Sanitization"]
        AGENT["๐Ÿค– Agent Execution<br/>Read-Only Permissions"]
        REDACT["๐Ÿ”‘ Secret Redaction"]
    end

    subgraph Isolation["๐Ÿณ Isolation Layer (Layer 1)"]
        AWF["๐ŸŒ Agent Workflow Firewall<br/>Squid Proxy Egress Control"]
        PROXY["๐Ÿ”— API Proxy<br/>Agent auth-token isolation"]
        MCP["๐Ÿ“ฆ MCP Server Sandboxing<br/>Container Isolation"]
        TOOL["๐ŸŽฏ Tool Allowlisting<br/>Explicit Permissions"]
    end

    subgraph OutputSec["๐Ÿ” Output Security (Layer 3)"]
        DETECT["๐Ÿง  Threat Detection<br/>AI-Powered Analysis"]
        SAFE["โœ… Safe Outputs<br/>Permission Separation"]
        SANITIZE["๐Ÿงน Output Sanitization<br/>Content Validation"]
    end

    subgraph Result["โœ“ Controlled Actions"]
        PR["๐Ÿ“ Create Pull Request"]
    end

    WF --> SCHEMA
    IMPORTS --> SCHEMA
    SCHEMA --> EXPR
    EXPR --> PIN
    PIN --> SCAN
    SCAN -->|".lock.yml"| PRE

    EVENT --> ACT
    PRE --> ACT
    ACT --> AGENT

    AGENT <--> AWF
    AGENT <--> PROXY
    AGENT <--> MCP
    AGENT <--> TOOL

    AGENT --> REDACT
    REDACT --> DETECT
    DETECT --> SAFE
    SAFE --> SANITIZE

    SANITIZE --> PR

๐Ÿ”„ Job Execution Flow

flowchart TB
    subgraph PreAct["๐Ÿšฆ Pre-Activation"]
        ROLE["๐Ÿ‘ค Role Permission Check"]
        DEADLINE["โฐ Stop-After Deadline"]
        SKIP["๐Ÿ” Skip-If-Match Check"]
    end

    subgraph Activation["๐Ÿงน Activation"]
        CONTEXT["๐Ÿ“‹ Prepare Workflow Context"]
        SANITIZE2["๐Ÿ”’ Sanitize Event Text"]
        LOCK_CHECK["โœ… Validate Lock File"]
    end

    subgraph AgentJob["๐Ÿค– Agent Job"]
        CHECKOUT["๐Ÿ“ฅ Repository Checkout"]
        NODE_SETUP["โš™๏ธ Setup Node.js 26"]
        MCP_START["๐Ÿ”Œ Start MCP Containers"]
        PROMPT["๐Ÿ“ Generate Prompt"]
        EXECUTE["๐Ÿง  Execute AI Engine"]
        SECRET_REDACT["๐Ÿ”‘ Secret Redaction"]
        UPLOAD["๐Ÿ“ค Upload Output Artifact"]
    end

    subgraph DetectJob["๐Ÿ” Detection Job"]
        DOWNLOAD["๐Ÿ“ฅ Download Artifact"]
        ANALYZE["๐Ÿง  AI + Custom Analysis"]
        VERDICT["โš–๏ธ Security Verdict"]
    end

    subgraph SafeJobs["โœ… Safe Output Jobs"]
        CREATE_PR["๐Ÿ“ create_pull_request<br/>contents: write"]
    end

    ROLE --> DEADLINE --> SKIP
    SKIP -->|"Pass"| CONTEXT
    CONTEXT --> SANITIZE2 --> LOCK_CHECK
    LOCK_CHECK --> CHECKOUT

    CHECKOUT --> NODE_SETUP --> MCP_START --> PROMPT --> EXECUTE --> SECRET_REDACT --> UPLOAD

    UPLOAD --> DOWNLOAD --> ANALYZE --> VERDICT
    VERDICT -->|"Safe"| CREATE_PR
    VERDICT -->|"Threat"| BLOCK["๐Ÿšซ Block All Outputs"]

๐Ÿ“Š Security Layers Summary

LayerMechanismProtection AgainstEU Parliament Monitor Implementation
๐Ÿ”’ SubstrateGitHub Actions runner (VM, kernel)Memory corruption, privilege escalationUbuntu latest + Docker runtime
๐Ÿ”’ SubstrateDocker container runtimeProcess isolation bypass, shared state--cap-drop=ALL, resource limits
๐Ÿ”’ SubstrateAWF network controls (iptables + Squid)Data exfiltration, unauthorized API callsnetwork.allowed 30+ entries (EU/IMF/WB/Hack23 + infra), default-deny
๐Ÿ”’ SubstrateMCP sandboxing (container isolation)Container escape, unauthorized toolsEP/WB/IMF each in isolated containers
๐Ÿ“‹ ConfigurationSchema validation + expression allowlistInvalid configs, unauthorized expressionsgh aw compile --validate
๐Ÿ“‹ ConfigurationAction SHA pinningSupply chain attacks, tag hijackingAll actions pinned to commit SHA
๐Ÿ“‹ ConfigurationSecurity scannersPrivilege escalation, misconfigsactionlint + zizmor + poutine
๐Ÿ“‹ ConfigurationContent sanitizationPrompt injection, bot triggers@mention neutralization, URI filtering
๐Ÿ“‹ ConfigurationIntegrity filteringUntrusted content injectionmin-integrity: approved (public repo)
๐Ÿ“ PlanSafeOutputs permission isolationUnauthorized writes, state modificationRead-only agent โ†’ vetted PR only
๐Ÿ“ PlanThreat detection pipelineSecret leakage, malicious patchesAI detection + custom scanners
๐Ÿ“ PlanSecret redactionCredential leakage in artifactsUnconditional scan with if: always()
๐Ÿ“ PlanJSONL audit trailUndetected compromise, forensics gaps90-day retention, gh aw logs/audit

Defense-in-Depth Principle: Each layer provides independent security controls. Compromise of any single layer does not bypass the entire security model. Trust violations at the substrate level require vulnerabilities in the firewall, MCP Gateway, container runtime, kernel, hypervisor, or hardware.

ISMS Compliance:

  • ISO 27001 Annex A.8.31 (Separation of development, testing, and production environments)
  • ISO 27001 Annex A.8.25 (Secure development lifecycle)
  • NIST CSF 2.0 PR.AC-4 (Access permissions managed, incorporating least privilege)
  • NIST CSF 2.0 DE.CM (Security continuous monitoring)
  • CIS Controls v8.1 Control 4.1 (Establish and maintain a secure configuration process)
  • CIS Controls v8.1 Control 16.1 (Application software security)

๐Ÿ”Œ 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:8080/mcp/european-parliament

Configuration source: scripts/mcp-setup.sh is sourced by every agentic workflow .md body. It resolves gateway.port and gateway.domain dynamically from /home/runner/.copilot/mcp-config.json (gh-aw writes these per-run) and falls back to host.docker.internal:8080 for non-agentic callers. Token extraction reads gateway.apiKey (legacy) or mcpServers['european-parliament'].headers.Authorization (raw API key) using node -e JSON parsing โ€” no jq dependency, no shell expansion of untrusted JSON values. Sets EP_MCP_GATEWAY_URL, EP_MCP_GATEWAY_API_KEY, and MCP_CLIENT_TIMEOUT_MS=180000 (180 s default).

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 26 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.4.0"],
      "env": {
        "EP_MCP_GATEWAY_URL": "http://host.docker.internal:8080/mcp/european-parliament"
      }
    },
    "worldbank": {
      "command": "npx",
      "args": ["-y", "worldbank-mcp@1.0.1"]
    }
  }
}

ISMS Alignment:

DocumentFocusLink
๐Ÿ” Security ArchitectureCurrent StateThis document
๐Ÿš€ Future Security ArchitectureRoadmapFUTURE_SECURITY_ARCHITECTURE.md
โš™๏ธ CI/CD WorkflowsCurrent workflowsWORKFLOWS.md
๐Ÿš€ Future WorkflowsPlanned enhancementsFUTURE_WORKFLOWS.md
๐Ÿ“Š Data ModelData StructuresDATA_MODEL.md
๐Ÿ“ˆ Security FlowProcess FlowsFLOWCHART.md
๐Ÿ“š Documentation HubRelease documentationdocs/README.md
๐Ÿ“‹ Release ProcessRelease proceduresdocs/RELEASE_PROCESS.md
๐ŸŽฏ Threat ModelRisk Analysis#-threat-model
๐Ÿ›ก๏ธ ISMS Secure DevelopmentPolicy FrameworkISMS-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.

Policy DomainPolicyRelevance to Architecture
๐Ÿ” Core SecurityInformation Security PolicyOverall security governance and framework
๐Ÿ› ๏ธ DevelopmentSecure Development PolicySecurity-integrated SDLC practices, CodeQL SAST scanning
๐ŸŒ NetworkNetwork Security PolicyGitHub Pages CDN security, HTTPS enforcement
๐Ÿ”’ CryptographyCryptography PolicyTLS 1.3, HTTPS-only, Content Security Policy
๐Ÿ” VulnerabilityVulnerability ManagementDependabot, CodeQL, npm audit, weekly scans
๐Ÿšจ Incident ResponseIncident Response PlanGitHub Security Advisories, coordinated disclosure
๐Ÿค Third-PartyThird Party ManagementGitHub ecosystem assessment (GitHub Pages, Actions, npm)
๐Ÿ”“ Open SourceOpen Source PolicyApache-2.0 licensing, REUSE compliance, SBOM generation
๐Ÿ“‹ ComplianceCompliance ChecklistISO 27001, NIST CSF, CIS Controls alignment
๐Ÿท๏ธ ClassificationClassification FrameworkPublic data classification (Level 1 confidentiality)
๐Ÿ‡ช๐Ÿ‡บ CRA ComplianceCRA Conformity Assessment ProcessCRA-ASSESSMENT.md self-assessment

Security Control Implementation Status

ISMS Control DomainImplementation StatusNotes
๐Ÿ”‘ Access Controlโœ… ImplementedGitHub CODEOWNERS, branch protection, required reviews
๐Ÿ”’ Cryptographyโœ… ImplementedTLS 1.3, HTTPS-only, HSTS
๐ŸŒ Network Securityโœ… ImplementedGitHub Pages CDN, DDoS protection, edge caching
๐Ÿ› ๏ธ Secure Developmentโœ… ImplementedCodeQL SAST, ESLint, TypeScript, Prettier, pre-commit hooks
๐Ÿ” Vulnerability Managementโœ… ImplementedDependabot (weekly), CodeQL (push/PR), npm audit
๐Ÿ“Š Monitoring & Loggingโš ๏ธ LimitedGitHub Actions logs, CDN access logs (no backend logging)
๐Ÿ’พ Data Protectionโœ… ImplementedNo persistent storage, ephemeral build environment
๐Ÿšจ Incident Responseโœ… DocumentedSECURITY.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

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

๐Ÿ“ฆ 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 "Article Generation Container"
            CLI[๐Ÿ“ article-generator.ts<br/>TypeScript CLI (npm run generate-article)]
            AGG[๐Ÿงฉ analysis-aggregator.ts<br/>Artifact Aggregator]
            CLIENT[๐Ÿ”Œ ep-mcp-client.ts<br/>MCP Client Library]
        end

        subgraph "Index Generation Container"
            IDX[๐Ÿ“‹ news-indexes.ts<br/>Index Generator]
        end

        subgraph "Sitemap Generation Container"
            SITE[๐Ÿ—บ๏ธ sitemap.ts<br/>Sitemap + Political Intelligence 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

Container Security Characteristics

ContainerRuntimePrivilegesNetwork AccessPersistence
News GenerationNode.js 26Read/Write repoLocalhost onlyNone (ephemeral)
Index GenerationNode.js 26Read/Write repoNoneNone (ephemeral)
Sitemap GenerationNode.js 26Read/Write repoNoneNone (ephemeral)
MCP ServerNode.js 26Read-onlyHTTPS to EP APINone (ephemeral)
ValidationNode.js 26Read-onlyNoneNone (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

Component Security Responsibilities

ComponentSecurity FunctionControls
Connection ManagerMCP server connection securityRetry limits, timeout enforcement, error handling
Request HandlerJSON-RPC protocol integritySchema validation, request ID tracking
Response ParserInput validation & sanitizationData type checking, XSS prevention
HTML BuilderOutput encodingHTML entity encoding, CSP compliance
Error HandlerFail-secure behaviorFallback content, no sensitive data exposure
HTML ValidatorContent integrityhtmlhint rules, standards compliance
Security ScannerSAST detectioneslint-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

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

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:

Branded Type Safety System (Compile-Time XSS / Injection Prevention)

The TypeScript generation layer in src/generators/shared/ implements a phantom-brand type system that turns sanitisation contracts into compile-time guarantees. The branded types are erased by TypeScript (zero runtime cost) but prevent accidental interpolation of unsanitised strings into HTML, XML, or URL contexts.

Branded TypeProducer FunctionSource ModuleGuarantee
SafeHtmlStringtoSafeHtml(raw)src/generators/shared/html-escape.tsHTML-entity-escaped (&, <, >, ", ') โ€” safe for HTML interpolation
SafeXmlStringtoSafeXml(raw)src/generators/shared/html-escape.tsXML-entity-escaped โ€” safe for sitemap.xml / rss.xml interpolation
AbsoluteUrltoAbsoluteUrl(raw)src/generators/shared/html-escape.tsValidated https:// URL with attribute-safe character set
RelativeFilePathtoRelativeFilePath()src/generators/shared/html-escape.tsPOSIX-normalised, no leading slash, no .. traversal

Compile-time enforcement model:

flowchart LR
    RAW[raw: string<br/>untrusted MCP / EP / IMF input]
    PROD[Producer Function<br/>toSafeHtml / toSafeXml /<br/>toAbsoluteUrl / toRelativeFilePath]
    BRANDED[SafeHtmlString /<br/>SafeXmlString /<br/>AbsoluteUrl /<br/>RelativeFilePath]
    TPL[HTML / XML Template<br/>accepts only branded types]
    OUT[Generated artefact<br/>provably escaped at compile time]

    RAW -->|"escapeHTML / escapeXML /<br/>URL validation"| PROD
    PROD -->|"phantom brand:<br/>{readonly [__brand]: 'SafeHtml'}"| BRANDED
    BRANDED -->|"type-checked interpolation"| TPL
    TPL --> OUT

    BLOCK[โŒ raw string passed<br/>directly to template] -.->|"TS2322:<br/>Type 'string' is not<br/>assignable to 'SafeHtmlString'"| TPL

    style RAW fill:#fff4e1
    style PROD fill:#e1f5ff
    style BRANDED fill:#e8f5e9
    style TPL fill:#e8f5e9
    style OUT fill:#e8f5e9
    style BLOCK fill:#ffe1e1

Security properties:

  1. No runtime cost โ€” branded types are compile-time-only (TypeScript erases the phantom __brand symbol). They impose zero performance overhead on generated output.
  2. Single sanitisation gateway โ€” html-escape.ts is the only module that produces branded values. Every template parameter typed SafeHtmlString is provably escaped because it can only originate from toSafeHtml().
  3. Compile-time XSS prevention โ€” passing an unbranded string directly into a template that accepts SafeHtmlString is a TypeScript error (TS2322). The build fails before the artefact reaches CI.
  4. Multi-language correctness โ€” branded types are language-agnostic. The escaping logic is identical for all 14 supported languages (EN, SV, DA, NO, FI, DE, FR, ES, NL, AR, HE, JA, KO, ZH), including RTL scripts (Arabic, Hebrew) where mixed-direction injection attacks are otherwise easy to miss.
  5. No dangerouslySetInnerHTML equivalent โ€” the project ships no escape hatch that bypasses the brand. markdown-it runs with html: false and the result is post-processed by src/utils/html-sanitize.ts before being branded.

Verification:

  • Unit tests in test/unit/generators/shared/html-escape.test.js exercise each producer with hostile inputs (<script>, javascript:, RTL override characters, attribute-breakout payloads).
  • Integration tests in test/integration/html-article-pipeline.test.js verify the pipeline-level invariant: every generated HTML page passes HTMLHint, contains no inline <script>, and has CSP-compliant output across all 14 languages.
  • The shared barrel src/generators/shared/index.ts re-exports only the producers; the brand symbol itself is module-private, preventing user code from forging branded values.

ISMS Alignment:

  • Secure Development Policy โ€” secure-by-design output encoding
  • Cryptography Policy โ€” defence-in-depth with TLS in transit
  • OWASP A03:2021 (Injection) โ€” primary mitigation for stored / reflected XSS in generated articles
  • OWASP A05:2021 (Security Misconfiguration) โ€” eliminates the category of "forgot to escape one field"

Shell-Safety Filter Enforcement (Agentic Workflow Hardening)

GitHub Agentic Workflows execute AI-authored bash inside a sandboxed runner. To prevent prompt-injection-driven arbitrary code execution, the platform's shell-safety filter rejects a defined set of bash expansion patterns. Repository code, prompts, and helper scripts must avoid these patterns or the run fails โ€” sometimes after burning the 60-minute workflow budget. The repository enforces this at three layers:

Layer 1 โ€” Forbidden expansion patterns (matched by test/unit/shell-safety.test.js against every scripts/**.sh):

PatternExample (DO NOT USE)Risk
Nested parameter expansion${var#${other}}, ${A:-${B:-}}Inner expansion result becomes part of outer pattern
Indirect expansion${!var}, ${!prefix*}Reads arbitrary variables by name
Parameter transformation${var@P}, ${var@Q}, ${var@E}@P re-evaluates the string as a prompt
Nested command substitution$(cmd $(inner))Inner $() executes under the outer
Default-with-command-substitution${VAR:-$(cmd)}Default expression is a live command
Input redirection inside $()$(cmd < file)Smuggles arbitrary file reads into substitutions
evaleval "$str"Explicit arbitrary-code execution
Adjacent ${RANDOM}${RANDOM}suffix="${RANDOM}${RANDOM}"Adjacency heuristic trips nested-expansion detection

Layer 2 โ€” Drift-guard test (test/unit/shell-safety.test.js):

  • Recursively scans every scripts/**.sh file
  • Strips whole-line comments before applying regex rules (so the documented forbidden patterns in commentary do not trigger the guard)
  • Emits a precise file:line failure pointing at .github/prompts/00-scope-and-ground-rules.md ยง47 and .github/prompts/08-infrastructure.md ยง177-181
  • Runs as part of the standard npm run test Vitest suite โ€” every PR is gated on it

Layer 3 โ€” Prompt-level rules (read by every news-generation agent):

  • .github/prompts/00-scope-and-ground-rules.md ยง47 โ€” authoritative short-form forbidden-pattern list, imported by every news-<type>.md workflow body
  • .github/prompts/08-infrastructure.md ยง177-181 โ€” long-form explanations with safe replacement idioms (e.g. if/elif/else instead of ${A:-${B:-}}, two-step variable assignment instead of nested $())
  • .github/prompts/02-analysis-protocol.md ยง10 โ€” mandates that bash in agentic workflows delegates to repo-hosted, pre-audited helpers (e.g. scripts/checkpoint-analysis-to-memory.sh) rather than inlining expansion-heavy commands

Threat model linkage: see THREAT_MODEL.md Threat T-029 (Shell Expansion Injection in Agentic Workflows) for the STRIDE / MITRE ATT&CK mapping and residual risk rating.

ISMS Alignment:

  • Secure Development Policy โ€” secure CI/CD, command-injection prevention
  • AI Policy โ€” sandboxing AI-generated code
  • OWASP A03:2021 (Injection) โ€” command injection prevention
  • CIS Control 16.11 (Application Software Security) โ€” protect against runtime-generated commands

Data Classification & Handling

Data TypeClassificationStorageEncryptionRetention
News ArticlesPublicGit repositoryAt-rest (GitHub)Indefinite
EP API ResponsesPublicEphemeral (runtime only)In-transit (TLS 1.3)None
Generation MetadataPublicGit repositoryAt-rest (GitHub)Indefinite
GitHub TokensSecretGitHub SecretsEncryptedAuto-rotate
MCP CommunicationInternalLocalhost onlyN/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 TypePurposeManagementRotation
GitHub Actions GITHUB_TOKENCI/CD authenticationAuto-generated per jobPer-workflow run (ephemeral)
MCP PATEP MCP Server accessGitHub Secrets (encrypted at rest)Manual rotation, 90-day recommended
TLS CertificatesHTTPS for GitHub PagesGitHub-managed (Let's Encrypt)Auto-renewed every 90 days
GPG Signing KeysCommit verificationDeveloper-managedPer 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

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/aggregator/article-html.ts 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

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

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

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 15 news generation workflows (breaking, week-ahead, week-in-review, month-ahead, month-in-review, quarter-ahead, quarter-in-review, year-ahead, year-in-review, term-outlook, election-cycle, committee-reports, motions, propositions, 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

Change Tracking & Tamper-Evident Logging

ControlImplementationEvidence
Immutable Commit HistoryGit SHA-256 hash chain, signed commits via GPGEvery content change has traceable commit
Branch ProtectionRequired reviews, status checks, no force pushesMain branch protected against unauthorized changes
Build ProvenanceGitHub Actions workflow logs with SLSA Level 3Reproducible builds with attestation
Content ChecksumsGenerated HTML has deterministic output from same inputsBuild reproducibility verification
Dependency Lockpackage-lock.json ensures reproducible installsnpm 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

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/news-breaking.lock.yml (compiled from news-breaking.md)
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

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/news-breaking.lock.yml (example โ€” all news-*.lock.yml follow this pattern)
- 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 26)
  • 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

Vulnerability SLA Targets

SeverityCVSS RangeResponse TimeResolution TimeEscalation
๐Ÿ”ด Critical9.0-10.04 hours24 hoursImmediate CEO notification
๐ŸŸ  High7.0-8.924 hours7 daysWeekly security review
๐ŸŸก Medium4.0-6.948 hours30 daysMonthly maintenance
๐ŸŸข Low0.1-3.97 days90 daysQuarterly 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

ScannerTriggerFrequencyCoverage
CodeQLPush to main, PRPer-commitJavaScript/TypeScript SAST
DependabotScheduledWeekly (Monday)npm ecosystem
npm auditCI pipelineEvery buildDirect + transitive deps
Secret ScanningPushContinuousAll committed content
ESLint SecurityPre-commitEvery commitCode quality + security rules
REUSECI pipelineEvery buildLicense 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

ConfigurationSource of TruthValidationChange Process
GitHub Actions Workflows.github/workflows/*.ymlYAML lint, action SHA pinningPR review + required checks
TypeScript Configurationtsconfig.json (strict mode)tsc --noEmit type checkingPR review
ESLint Ruleseslint.config.jsnpm run lintPR review
Dependabot Config.github/dependabot.ymlGitHub validationPR review
Content Security Policyarticle-html.tsE2E tests verify CSP headersPR review + automated tests
Branch ProtectionGitHub Repository SettingsGitHub API auditAdmin-only changes
MCP Server Config.github/copilot-mcp.jsonSchema validationPR 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

FrameworkAutomated CheckFrequencyEvidence
REUSE (SPDX)reuse lint in CIEvery buildLicense compliance
OpenSSF ScorecardGitHub-integratedWeeklySupply chain security
SLSAGitHub attestationPer-releaseBuild provenance
HTMLHintnpm run htmlhintEvery buildContent standards
TypeScript Stricttsc --noEmitEvery buildType safety
Prettiernpm run format:checkEvery buildCode 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

Key Security Indicators

MetricTargetMeasurementCurrent
Mean Time to Detect (MTTD)< 1 hourAutomated scanning detectionโœ… Real-time (CI/CD)
Mean Time to Remediate (MTTR)< 48 hours (high)Alert to fix mergeโœ… < 48 hours
Vulnerability Backlog0 critical/highOpen findings countโœ… 0
Dependency Currency< 30 days behindPackage age analysisโœ… Weekly updates
Build Success Rate> 95%CI/CD pipeline metricsโœ… > 98%
Security Test Coverage> 80% lineVitest 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

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

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

ScenarioDetection TimeRecovery ActionTotal RTOImpact
GitHub Pages Outage<5 minutesWait for GitHub or deploy to alternative CDN<1 hourLow (GitHub SLA: 99.9%)
Build Failure<5 minutesFix issue + re-run workflow<1 hourLow (daily updates acceptable)
Repository Compromise<1 hourRevert commits + rotate secrets<4 hoursMedium (requires investigation)
MCP Server Outage<5 minutesAutomatic fallback to cached data0 (automatic)None (transparent failover)

Recovery Point Objective (RPO): 1 day

Data TypeBackup FrequencyMax Data LossRecovery Source
Source CodeEvery commit0 (Git-backed)GitHub repository, local clones
Generated ContentDaily build1 dayRegenerate from MCP data
Build ConfigurationEvery commit0 (Git-backed).github/workflows/
DependenciesWeekly scans0 (npm lockfile)package-lock.json

Build Pipeline Resilience

Build Failure Handling:

  1. ๐Ÿ”„ Automatic Retry:

    # Agentic workflows use gh-aw safe-outputs with single PR per run
    # Retry is handled at the MCP client level via callToolWithRetry()
    # and at the workflow level via manual re-dispatch
    
  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: S3 sync + CloudFront invalidation deploys all files atomically
  • Rollback Capability: Revert commit + re-deploy previous version via deploy-s3.yml
  • Zero-Downtime: Old content served from CloudFront cache until invalidation completes
  • Immutable URLs: Versioned vendor assets never change once deployed

Operational Readiness Procedures

Runbooks:

  1. [RUNBOOK-001] Build Failure Response:

    • Check GitHub Actions logs for the failed news-*.lock.yml workflow
    • Review error messages in agentic workflow output
    • Test locally: npm run generate-article -- --run <dir>
    • 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 to 26.x LTS
  • 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

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:

SeverityResponse TimeActionAuto-Merge
Critical24 hoursImmediate review + mergeโŒ No (breaking changes risk)
High7 daysPriority review + mergeโŒ No
Medium30 daysStandard reviewโš ๏ธ If dev dependency
Low90 daysBatch 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:

EventNotification ChannelResponse Time
Dependabot AlertEmail + GitHub UI24h (Critical), 7d (High)
CodeQL FindingPR Comment + EmailImmediate (blocks merge)
Workflow FailureEmail<1 hour (during business hours)
Secret ScanningEmail + Security TabImmediate

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

LayerControlImplementation
Schema ValidationJSON structure verificationMCP response schema validation before processing
Type EnforcementTypeScript strict modeCompile-time type safety with strict: true
Range CheckingBounds validationDate ranges, string lengths, numeric bounds
HTML SanitizationXSS preventionhtml-sanitize.ts strips dangerous HTML tags and attributes
Content ValidationArticle quality scoringarticle-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-html.ts uses safe template patterns with escapeHTML() for all dynamic content
  • โœ… 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

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

AssetValueConfidentialityIntegrityAvailability
Generated News ArticlesHighPublicHighMedium
European Parliament Data AccuracyHighPublicHighMedium
Website AvailabilityMediumN/AN/AMedium
Repository CodeMediumPublicHighMedium
Git HistoryMediumPublicHighLow

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

ThreatCategoryLikelihoodImpactResidual RiskPriority
XSS via Parliamentary DataInjectionLowHighLowP3
Supply Chain AttackPrivilege EscalationLowHighLowP2
Data Integrity IssuesTamperingMediumHighMediumP1
GitHub Actions DowntimeDenial of ServiceLowMediumLowP4
Repository CompromiseTamperingLowHighLowP2
MCP Server CompromiseSpoofingVery LowHighVery LowP5

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

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 ControlSafeguardDescriptionImplementationIG LevelStatus
11.1Establish and maintain detailed enterprise asset inventorySBOM (sbom.json), package.jsonIG1โœ…
22.1Establish and maintain software inventorynpm dependency tree, TypeScript sourceIG1โœ…
22.2Ensure authorized software is supportedDependabot updates, Node.js 26 LTS in productionIG1โœ…
44.1Establish and maintain secure configuration processESLint, Prettier, htmlhint rulesIG1โœ…
44.7Manage default accountsNo default accounts (static site)IG1N/A
55.1Establish and maintain inventory of accountsGitHub organization accountsIG1โœ…
55.3Disable dormant accountsGitHub access review processIG1โœ…
66.1Establish access control foundationGitHub MFA, branch protection rulesIG1โœ…
66.2Establish access grants for least privilegecontents:write only for GitHub ActionsIG1โœ…
77.1Establish vulnerability management processDependabot automated PRs, npm auditIG1โœ…
77.4Perform automated vulnerability scanningCodeQL SAST weekly scansIG2โœ…
77.5Perform automated patch managementDependabot auto-updatesIG2โœ…
88.2Collect audit logsGitHub Actions logs 90-day retentionIG1โœ…
88.5Collect detailed audit logsGit commit history (immutable)IG2โœ…
99.1Ensure use of only fully supported browsersStatic HTML/CSS/JS, no custom browser codeIG1N/A
1111.2Perform automated backupsGit distributed backup (all clones)IG1โœ…
1111.3Protect recovery dataGitHub repository integrityIG1โœ…
1212.2Establish network infrastructure managementNo server infrastructure (static site)IG1N/A
1414.1Establish/maintain security awarenessCONTRIBUTING.md, SECURITY.mdIG1โœ…
1616.1Establish secure application development processCodeQL, ESLint security, branch protectionIG1โœ…
1616.2Establish secure coding trainingSecure coding guidelines documentedIG2โœ…
1616.6Remediate detected software vulnerabilities7-day SLA for high CVEs, DependabotIG2โœ…
1818.1Establish penetration testing programFuture DAST implementation (Q3 2026)IG3๐Ÿ”ฎ

GDPR Compliance

Data Protection Principles:

PrincipleImplementationArticle
Lawfulness, Fairness, TransparencyPublic data, no user trackingArt. 5(1)(a)
Purpose LimitationSingle purpose: EU Parliament newsArt. 5(1)(b)
Data MinimisationNo PII collected, public data onlyArt. 5(1)(c)
AccuracyEuropean Parliament authoritative sourceArt. 5(1)(d)
Storage LimitationNo persistent user data storedArt. 5(1)(e)
Integrity & ConfidentialityHTTPS, TLS 1.3, CSP headersArt. 5(1)(f)
AccountabilityISMS policies, audit trailArt. 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:

RequirementImplementationAnnex I Reference
Secure by DefaultHTTPS-only, CSP, minimal attack surfacePart I, ยง1
Vulnerability HandlingCoordinated disclosure, 90-day embargoPart I, ยง2
Security UpdatesDependabot automated PRs, weekly scansPart I, ยง2
Software Bill of Materialsnpm list --json > sbom.jsonPart I, ยง2(3)
Secure DevelopmentCodeQL SAST, secure coding guidelinesPart II, ยง1
Incident ReportingSECURITY.md, GitHub Security AdvisoriesPart 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

FrameworkEvidence DocumentsRepository Locations
ISO 27001SECURITY_ARCHITECTURE.md, ISMS-PUBLICThis document, ISMS-PUBLIC
NIST CSFTHREAT_MODEL.md, WORKFLOWS.mdTHREAT_MODEL.md, WORKFLOWS.md
CIS ControlsSecurity controls documentationThis document (Security Controls section)
GDPRPrivacy policy (no data collection)This document (Data Protection section)
NIS2Incident response planSECURITY.md
EU CRASBOM, vulnerability disclosuresbom.json, SECURITY.md

โœ… Compliance Matrix

ISO 27001:2022 Annex A Controls Mapping

Theme 5 โ€” Organizational Controls (5.1โ€“5.37)

ControlRequirementImplementationStatusEvidence
5.1Information security policiesISMS-PUBLIC policy referenceโœ…This document, ISMS-PUBLIC repo
5.2Information security roles and responsibilitiesCEO as document ownerโœ…Document header
5.9Inventory of information and other assetsAsset inventory in threat modelโœ…Threat Model section
5.12Classification of informationPublic data classificationโœ…Executive Summary, Classification Framework
5.14Information transferTLS 1.3 in transitโœ…Network Security section
5.15Access controlMinimal GitHub Actions permissionsโœ…Authentication & Authorization section
5.16Identity managementGitHub account MFAโœ…GitHub organization settings
5.17Authentication informationCode review requirementsโœ…Branch protection rules
5.24Information security incident management planning and preparationGitHub Issues for incidentsโœ…CONTRIBUTING.md
5.29Information security during disruptionManual trigger, cached contentโœ…Infrastructure Security section
5.36Compliance with policies, rules and standardsThis documentโœ…Compliance Matrix section
5.37Documented operating proceduresCI/CD workflows documentedโœ….github/workflows/

Theme 6 โ€” People Controls (6.1โ€“6.8)

ControlRequirementImplementationStatusEvidence
6.3Information security awareness, education and trainingCONTRIBUTING.md security guidanceโœ…CONTRIBUTING.md

Theme 7 โ€” Physical Controls (7.1โ€“7.14)

ControlRequirementImplementationStatusEvidence
7.10Storage mediaGit-based version controlโœ…GitHub repository

Theme 8 โ€” Technological Controls (8.1โ€“8.34)

ControlRequirementImplementationStatusEvidence
8.3Information access restrictionGITHUB_TOKEN auto-expiryโœ…GitHub Actions configuration
8.7Protection against malwareCodeQL, ESLint securityโœ…Application Security section
8.8Management of technical vulnerabilitiesDependabot, npm auditโœ…Dependency Security section
8.13Information backupGit version controlโœ…GitHub repository
8.15LoggingGitHub Actions logsโœ…GitHub Actions audit logs
8.16Monitoring activitiesDependabot & CodeQL continuous scansโœ…Security Operations section
8.20Networks securityHTTPS only, localhost MCPโœ…Network Security section
8.24Use of cryptographyTLS 1.3, GitHub Pages HTTPSโœ…Network Security section
8.25Secure development lifecycleSAST, dependency scanningโœ…Application Security section
8.27Secure system architecture and engineering principlesCode review, branch protectionโœ…Security Operations section
8.33Test informationNo 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

SubcategoryDescriptionImplementationStatus
GV.OC-01Organizational mission understood and informs cybersecurity risk managementDemocratic transparency mandateโœ…
GV.OC-05Outcomes, capabilities, and services that the organization depends on are understood and communicated to supply chainPublic ISMS documentationโœ…
GV.RM-01Risk management objectives are established and agreed to by organizational stakeholdersISMS risk frameworkโœ…
GV.RM-02Risk appetite and risk tolerance statements are established, communicated, and maintainedLow risk tolerance (public platform)โœ…
GV.PO-01Policy for managing cybersecurity risks is established based on organizational contextISMS-PUBLIC policiesโœ…
GV.RR-01Organizational leadership is responsible and accountable for cybersecurity riskCEO document ownershipโœ…
GV.SC-01A cybersecurity supply chain risk management program, strategy, objectives, policies, and processes are establishedDependabot, SHA-pinned actionsโœ…
GV.SC-06Planning and due diligence are performed to reduce risks before entering into formal supplier or other third-party relationshipsMinimal dependencies, SCA scanningโœ…
ID.AM-01Inventories of hardware managed by the organization are maintainedSBOM, package.json, GitHub repoโœ…
ID.AM-02Inventories of software, services, and systems managed by the organization are maintainednpm dependency tree, Dependabotโœ…
ID.AM-08Systems, hardware, software, services, and data are managed throughout their life cyclesARCHITECTURE.md C4 diagramsโœ…
ID.RA-01Vulnerabilities in assets are identified, validated, and recordedCodeQL SAST, Dependabot SCAโœ…
ID.RA-05Threats, vulnerabilities, likelihoods, and impacts are used to understand inherent risk and inform risk response prioritizationTHREAT_MODEL.md STRIDE analysisโœ…
ID.RA-06Risks are prioritized, responded to, and communicated to applicable stakeholdersRisk register, threat modelโœ…
ID.IM-01Improvements are identified from security assessmentsAnnual security review cycleโœ…
PR.AA-01Identities and credentials for authorized users, services, and hardware are managed by the organizationGitHub MFA, auto-expiring GITHUB_TOKENโœ…
PR.AA-05Access permissions, entitlements, and authorizations are defined in a policy, managed, enforced, and reviewedBranch protection, CODEOWNERS, least privilegeโœ…
PR.AT-01Personnel are provided with awareness and training so that they possess the knowledge and skills to perform general tasks with cybersecurity risks in mindCONTRIBUTING.md, SECURITY.mdโœ…
PR.DS-01The confidentiality, integrity, and availability of data-at-rest are protectedGit repository integrity, immutable historyโœ…
PR.DS-02The confidentiality, integrity, and availability of data-in-transit are protectedTLS 1.3 HTTPS-only, GitHub Pages enforcementโœ…
PR.DS-10The confidentiality, integrity, and availability of data-in-use are protectedNo PII processing, public data onlyโœ…
PR.IR-01Networks and environments are protected from unauthorized logical access and usageNo server network, localhost MCP onlyโœ…
PR.IR-02The organization's technology assets are protected from environmental threatsNo sensitive data collectedโœ…
PR.PS-01Configuration management practices are established and appliedESLint config, branch protection rulesโœ…
PR.PS-02Software is maintained, replaced, and removed commensurate with riskDependabot, npm audit, Node.js LTSโœ…
DE.AE-02Potentially adverse events are analyzed to better characterize them and detect cybersecurity incidentsGitHub Security Alerts, CodeQL findingsโœ…
DE.AE-06Information on adverse events is provided to authorized staff and toolsPublic SECURITY.md, GitHub Security Advisoriesโœ…
DE.CM-01Networks and network services are monitored to find potentially adverse eventsDependabot, CodeQL, npm audit continuous scanningโœ…
DE.CM-09Computing hardware and software, runtime environments, and their data are monitored to find potentially adverse eventsGitHub Actions logs, audit trailโœ…
RS.MA-01The incident response plan is executed in coordination with relevant third parties once an incident is declaredSECURITY.md incident proceduresโœ…
RS.AN-03Analysis is performed to establish what has taken place during an incident and the root cause of the incidentGit history, Actions logs forensicsโœ…
RS.CO-02Internal and external stakeholders are notified of incidents in a timely mannerGitHub Security Advisories, SECURITY.mdโœ…
RS.MI-02Incidents are containedRevert commits, disable workflowsโœ…
RC.RP-01The recovery portion of the incident response plan is executed once initiated from the incident response processBCPPlan.md recovery proceduresโœ…
RC.CO-03Recovery activities and progress in restoring operational capabilities are communicated to designated internal and external stakeholdersGitHub Issues, SECURITY.mdโœ…
RC.IM-01Recovery plans incorporate lessons learnedPost-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

ArticleRequirementImplementationStatusEvidence
Art. 5Principles of ProcessingNo PII collectedโœ…No tracking, no forms, static site
Art. 25Data Protection by DesignSecurity by design architectureโœ…Executive Summary, no PII by design
Art. 30Records of ProcessingNo processing of personal dataโœ…Static site, no user data
Art. 32Security of ProcessingDefense-in-depth controlsโœ…Security Controls section
Art. 33Breach NotificationIncident response via GitHub Issuesโœ…CONTRIBUTING.md
Art. 35DPIANot 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

ArticleRequirementImplementationStatusEvidence
Art. 20Cybersecurity Risk ManagementThreat modeling, risk assessmentโœ…Threat Model section
Art. 21Cybersecurity MeasuresDefense-in-depth controlsโœ…Security Controls section
Art. 21(2)(a)Risk Analysis & Security PoliciesISMS-PUBLIC policy frameworkโœ…ISMS alignment throughout
Art. 21(2)(b)Incident HandlingGitHub Issues, audit logsโœ…Security Operations section
Art. 21(2)(c)Business ContinuityRTO/RPO defined, manual triggerโœ…Executive Summary
Art. 21(2)(d)Supply Chain SecurityDependabot, SHA-pinned actionsโœ…Dependency Security section
Art. 21(2)(e)Effectiveness of MeasuresAnnual review, monitoringโœ…Document header (annual review)
Art. 23Incident Reporting24-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

RequirementImplementationStatusEvidence
SBOMGenerated for releasesโœ….github/workflows/release.yml
Vulnerability DisclosurePublic security advisoriesโœ…GitHub Security Advisories
Security UpdatesDependabot automated updatesโœ….github/dependabot.yml
Security by DesignThreat modeling, secure architectureโœ…This document
Conformity AssessmentAnnual 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

MetricTargetCurrentStatus
Known Vulnerabilities00โœ…
Dependabot Alert Response Time< 7 days< 48 hoursโœ…
Code Coverage> 80%82%+โœ…
CodeQL Findings0 critical/high0โœ…
Security Test Pass Rate100%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:

BadgeStatusScore/LevelDescription
OpenSSF Scorecardโœ… ImplementedTarget โ‰ฅ7.0Supply chain security assessment
CII Best Practices๐Ÿ“ Registration PendingTarget: PassingOpen source development best practices
SLSA Provenanceโœ… ImplementedLevel 3Build attestations and SBOM generation
SonarCloudโœ… ImplementedTarget: ACode quality and security analysis
FOSSA๐Ÿ“ Setup RequiredTarget: CleanLicense compliance scanning
REUSEโœ… ImplementedPassingFSFE 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]

Generated Documentation

Documentation TypeGeneratorSecurity Controls
API DocumentationJSDocInput sanitization, no script injection
Test CoverageVitest HTMLStatic HTML, no dynamic content
E2E Test ReportsPlaywrightScreenshots sanitized, no PII
Documentation IndexCustom scriptStatic 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

ControlImplementationPurpose
Static GenerationNo server-side executionEliminates injection attacks
Input SanitizationJSDoc, HTML encodingPrevents XSS in generated docs
Access ControlGitHub Pages authenticationPublic read, write via workflow only
Audit TrailGit commits for all changesComplete history and accountability
AttestationsSLSA Level 3 provenanceVerifiable 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:

RoleNameDateSignature
CEO (Document Owner)[Name]2026-05-03[Electronic]
CISO[Name]2026-05-03[Electronic]

Next Review Date: 2027-05-03


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