Riksdagsmonitor Intelligence Platform โ€” API Documentation - v1.0.47
    Preparing search index...

    Hack23 Logo

    ๐Ÿ”„ Riksdagsmonitor โ€” Business Continuity Plan

    ๐Ÿ›ก๏ธ Dual-Deployment Resilience Framework
    ๐ŸŽฏ Enterprise-Grade Availability Through Geographic Redundancy

    Owner Version Effective Date Review Cycle

    ๐Ÿ“‹ Document Owner: CEO | ๐Ÿ“„ Version: 1.3 | ๐Ÿ“… Last Updated: 2026-05-28 (UTC)
    ๐Ÿ”„ Review Cycle: Quarterly | โฐ Next Review: 2026-08-28
    ๐Ÿ“Œ Classification: Public


    Riksdagsmonitor's business continuity framework demonstrates how geographic redundancy and automated failover directly enable operational resilience and service availability. Our dual-deployment strategy serves as both operational necessity and technical demonstration of enterprise-grade reliability principles.

    This plan is designed to maintain the riksdagsmonitor.com platform during infrastructure disruptions through AWS multi-region deployment (primary) and GitHub Pages disaster recovery (standby), targeting 99.998% availability under normal operating conditions, with CloudFront origin failover typically completing in under 60 seconds and DNS/Route 53 failover (including health checks and DNS propagation) completing within approximately 15 minutes during full-region incidents.

    โ€” James Pether Sรถrling, CEO/Founder


    Riksdagsmonitor provides public political transparency services requiring high availability but tolerating brief disruptions:

    %%{
    init: {
    "theme": "base",
    "themeVariables": {
    "primaryColor": "#1565C0",
    "primaryTextColor": "#0d47a1",
    "lineColor": "#1565C0",
    "secondaryColor": "#4CAF50",
    "tertiaryColor": "#FF9800"
    }
    }
    }%%
    graph TB
    subgraph BIA["๐Ÿ“Š Business Impact Analysis"]
    FINANCIAL[๐Ÿ’ฐ Financial Impact<br/>No direct revenue loss]
    OPERATIONAL[โš™๏ธ Operational Impact<br/>Service unavailable]
    REPUTATIONAL[๐Ÿค Reputational Impact<br/>Public trust in transparency]
    CIVIC[๐Ÿ›๏ธ Civic Impact<br/>Democratic accountability]
    end

    subgraph RECOVERY["๐Ÿ”„ Recovery Requirements"]
    RTO["โฐ RTO Target<br/>&lt; 30 seconds origin failover<br/>&lt; 15 minutes DNS failover"]
    RPO["๐Ÿ’พ RPO Target<br/>&lt; 15 minutes<br/>near-zero effective RPO (S3 replication lag)"]
    AVAILABILITY["๐Ÿ“ˆ Availability Target<br/>99.998%<br/>โ‰ˆ10.5 minutes (~631 seconds) downtime/year"]
    end

    subgraph DEPLOYMENT["๐ŸŒ Deployment Strategy"]
    PRIMARY[โ˜๏ธ AWS Primary<br/>CloudFront + S3 Multi-Region]
    DR[๐Ÿ“ GitHub Pages DR<br/>Standby Deployment]
    FAILOVER[๐Ÿ”„ Automatic Failover<br/>Route 53 Health Checks]
    end

    FINANCIAL --> RTO
    OPERATIONAL --> RTO
    REPUTATIONAL --> RPO
    CIVIC --> AVAILABILITY

    RTO --> PRIMARY
    RPO --> PRIMARY
    AVAILABILITY --> PRIMARY

    PRIMARY --> FAILOVER
    DR --> FAILOVER

    style BIA fill:#1565C0,color:#ffffff
    style RECOVERY fill:#FF9800,color:#000000
    style DEPLOYMENT fill:#4CAF50,color:#000000
    Service Component๐Ÿ’ฐ Financial Impactโš™๏ธ Operational Impact๐Ÿค Reputational Impact๐Ÿ›๏ธ Civic Impact๐ŸŽฏ Recovery Priority
    ๐ŸŒ Static WebsiteMinimalHighHighCritical๐Ÿ”ด Critical
    ๐Ÿ“Š Content UpdatesMinimalModerateModerateModerate๐ŸŸก Medium
    ๐Ÿ” Search IndexingMinimalLowLowLow๐ŸŸข Standard

    %%{
    init: {
    "theme": "base",
    "themeVariables": {
    "primaryColor": "#1565C0",
    "primaryTextColor": "#0d47a1",
    "lineColor": "#1565C0",
    "secondaryColor": "#4CAF50",
    "tertiaryColor": "#FF9800"
    }
    }
    }%%
    graph TB
    subgraph ROUTE53["๐ŸŒ Route 53 DNS"]
    DNS[๐Ÿ“ก DNS Service<br/>Health Checks Every 30s]
    HEALTHCHECK[โš•๏ธ Health Checker<br/>Tests CloudFront Endpoint]
    end

    subgraph PRIMARY["โ˜๏ธ AWS Primary (Active)"]
    CF["๐ŸŒ CloudFront CDN<br/>600+ PoPs<br/>Automatic Origin Failover"]
    S3_US[๐Ÿ’พ S3 us-east-1<br/>Primary Origin<br/>Versioning Enabled]
    S3_EU["๐Ÿ’พ S3 eu-west-1<br/>Replica Origin<br/>Asynchronous Replication (&lt;15 min RPO)"]

    CF -->|Primary| S3_US
    CF -->|Failover on 5xx errors| S3_EU
    S3_US -.->|Replication| S3_EU
    end

    subgraph DR["๐Ÿ“ GitHub Pages (Standby)"]
    GH["๐Ÿ“„ GitHub Pages<br/>Default branch (root)<br/>Automated Deployment"]
    end

    USERS[๐Ÿ‘ฅ Users] -->|DNS Query| DNS
    HEALTHCHECK -->|Monitor| CF
    DNS -->|"Healthy: Return CloudFront alias/hostname"| USERS
    DNS -.->|"3 Failed Checks (~90s detection)<br/>+ DNS TTL/propagation (up to ~15 min total)"| USERS
    USERS -->|"HTTPS/TLS 1.3"| CF
    USERS -.->|"HTTPS/TLS 1.3 (DR)"| GH

    style ROUTE53 fill:#1565C0,color:#ffffff
    style PRIMARY fill:#4CAF50,color:#000000
    style DR fill:#FF9800,color:#000000

    These are business continuity design objectives, not contractual guarantees. Availability figures are based on underlying cloud provider SLAs and documented reliability targets.

    ComponentProvider SLAFailover MechanismTarget RTOTarget RPONotes
    ๐ŸŒ CloudFront99.9% (AWS SLA)Origin failover< 30 secondsโ‰ˆ 0 minutesCache may serve slightly stale content during failover
    ๐Ÿ’พ S3 us-east-199.99% (AWS SLA)Multi-region replica< 30 seconds< 15 minutesS3 cross-region replication typically completes within minutes; static content allows near-zero effective RPO
    ๐Ÿ’พ S3 eu-west-199.99% (AWS SLA)Primary failback< 30 seconds< 15 minutesReplication lag possible; static content minimizes data loss impact
    ๐ŸŒ Route 53100% (AWS SLA)Health check failover (30s ร— 3 checks)15 minutesโ‰ˆ 0 minutesIncludes health check detection (90s) + DNS TTL propagation (~14 min)
    ๐Ÿ“ GitHub Pages99.9% (target; no formal SLA)Route 53 automated DNS failover15 minutesUp to last deploymentStatic content served via Route 53 health-check based DNS failover; RPO = time since last successful GitHub Actions deploy
    ๐ŸŽฏ CombinedDesign target โ‰ˆ 99.998%Automated multi-layer< 30 seconds (objective)< 15 minutes for static content (objective)Theoretical calculation assuming largely independent failures

    Disclaimer: These are business continuity design objectives based on AWS published SLAs (CloudFront 99.9%, S3 99.99%, Route 53 100%) and GitHub public reliability targets. The combined 99.998% availability is a theoretical design target assuming largely independent failures. Actual end-to-end availability may be lower in practice. RPO values reflect S3 cross-region replication characteristics (typically < 15 minutes) and static content deployment timing; actual RPO may vary.


    RTORPOImpact

    ๐Ÿ” Detection:

    • CloudFront origin monitoring detects 500+ HTTP errors from us-east-1
    • Automatic failover triggered without manual intervention

    ๐Ÿ”„ Recovery Procedure:

    1. โšก CloudFront automatically routes to S3 eu-west-1 origin (< 30 seconds)
    2. ๐Ÿ“Š Verify service availability via monitoring
    3. ๐Ÿ“ Log incident for post-event analysis
    4. โณ Monitor AWS status for us-east-1 restoration
    5. ๐Ÿ”™ Automatic failback when us-east-1 recovers

    โœ… Validation:

    • Service availability confirmed via health checks
    • User experience unaffected (transparent failover)
    • Content served from eu-west-1 (identical to us-east-1)

    RTORPOImpact

    ๐Ÿ” Detection:

    • Route 53 health checks fail for CloudFront endpoint
    • Automated DNS failover to GitHub Pages after health check detection + DNS propagation (โ‰ˆ 15 minutes total)

    ๐Ÿ”„ Recovery Procedure:

    1. โš•๏ธ Route 53 detects CloudFront health check failures (30s intervals ร— 3 failures = 90 seconds detection time)
    2. ๐ŸŒ DNS automatically updates riksdagsmonitor.com โ†’ GitHub Pages
    3. ๐Ÿ“Š Verify GitHub Pages serving traffic
    4. ๐Ÿ“ง Notify CEO of failover event
    5. โณ Monitor CloudFront status for restoration
    6. ๐Ÿ”™ Intentionally manual DNS failback after CloudFront recovery and stability confirmation
      • Rationale: Failback is manual by design to avoid DNS flapping and ensure human verification before restoring CloudFront as primary

    โœ… Validation:

    • GitHub Pages availability confirmed
    • Users redirected via DNS (up to 15-minute TTL)
    • Content identical (synchronized deployment)

    RTORPOImpact

    ๐Ÿ” Detection:

    • CloudFront cannot reach either S3 origin
    • Route 53 health checks fail

    ๐Ÿ”„ Recovery Procedure:

    1. โšก CloudFront attempts origin failover (< 30 seconds)
    2. ๐ŸŒ Route 53 DNS failover to GitHub Pages (15 minutes)
    3. ๐Ÿ“Š Verify GitHub Pages serving traffic
    4. ๐Ÿ“ง CEO notification of major AWS outage
    5. โณ Monitor AWS status dashboard
    6. ๐Ÿ”™ DNS failback after AWS recovery

    โœ… Validation:

    • Service restored via GitHub Pages
    • Incident documented with AWS service disruption details

    RTORPOImpact

    ๐Ÿ” Detection:

    • CloudTrail alerts for unauthorized API calls
    • GuardDuty security findings
    • Unexpected configuration changes

    ๐Ÿ”„ Recovery Procedure:

    1. ๐Ÿ”’ Immediate DNS failover to GitHub Pages (operator action: 2 minutes; client-visible cutover: up to DNS TTL propagation ~15 minutes)
    2. ๐Ÿ” Revoke all AWS IAM credentials and access keys
    3. ๐Ÿ”„ Update AWS IAM role trust policy for GitHub Actions OIDC provider to revoke compromised trust
    4. ๐Ÿ“Š CloudTrail audit of unauthorized actions
    5. ๐Ÿ›ก๏ธ AWS Support engagement for forensics
    6. ๐Ÿ”ง Restore infrastructure from documented configuration and backups (future-state: Infrastructure-as-Code)
    7. โœ… Security validation before DNS failback

    โœ… Validation:

    • Service operational on GitHub Pages
    • All compromised credentials revoked
    • Forensic analysis completed
    • Infrastructure hardened before restoration

    RTORPOImpact

    ๐Ÿ” Detection:

    • GitHub Pages deployment failure
    • Health checks fail for GitHub Pages endpoint

    ๐Ÿ”„ Recovery Procedure:

    1. ๐Ÿ“Š Verify GitHub status dashboard
    2. ๐ŸŒ If AWS available, revert DNS to CloudFront immediately
    3. ๐Ÿ“„ If both unavailable, deploy to alternative CDN (Cloudflare Pages, Netlify)
    4. ๐Ÿ“ฆ Build static site from Git main branch
    5. ๐ŸŒ Update DNS to alternative CDN
    6. ๐Ÿ”™ Restore to primary after AWS/GitHub recovery

    โœ… Validation:

    • Alternative deployment confirmed operational
    • DNS propagation verified
    • Incident escalated to GitHub Support

    ๐Ÿ‘จโ€๐Ÿ’ผ CEO (James Pether Sรถrling) - Business Continuity Coordinator

    • ๐Ÿ”‘ Authority: Full decision-making power for continuity actions
    • ๐ŸŽฏ Responsibilities: Strategic decisions, stakeholder communication, recovery coordination
    • ๐Ÿ“ž Contact: Primary mobile, backup email, monitoring alerts
    • ๐Ÿ› ๏ธ Tools: AWS Console, GitHub CLI, Route 53 DNS management, CloudWatch

    ๐Ÿ”ง Technical Recovery (CEO as Technical Lead)

    • ๐ŸŽฏ Responsibilities: AWS infrastructure, GitHub Pages, DNS failover, health check monitoring
    • ๐Ÿ› ๏ธ Tools: AWS Console, AWS CLI, GitHub Actions, Route 53, CloudWatch
    • ๐Ÿ“ž Escalation Paths: AWS Enterprise Support, GitHub Enterprise Support
    ๐Ÿ‘ค Role๐Ÿ“ž Primary Contact๐Ÿ”„ Backup Methodโฐ Response Time
    ๐Ÿ‘จโ€๐Ÿ’ผ CEO/Coordinator๐Ÿ“ฑ Mobile phone๐Ÿ“ง Email + SMS< 15 minutes
    โ˜๏ธ AWS Support๐ŸŒ Enterprise Portal๐Ÿ“ž Phone support< 15 minutes
    ๐Ÿ“ GitHub Support๐ŸŒ Enterprise Portal๐Ÿ“ง Email< 1 hour
    ๐ŸŒ Route 53 Operationsโ˜๏ธ AWS Console๐Ÿ“ฑ Mobile app< 5 minutes
    ๐Ÿ“Š Monitoring Alerts๐Ÿ“ง Email + ๐Ÿ“ฑ SMS๐Ÿ’ฌ Chat/IMReal-time

    1. ๐Ÿ“Š Assess Situation: Determine scope via CloudWatch, Route 53 health checks
    2. ๐Ÿ” Identify Failure Point: AWS infrastructure, DNS, GitHub Pages
    3. ๐Ÿš€ Activate Recovery: Automatic (CloudFront failover) or manual (DNS update)
    4. ๐Ÿ“ข Log Incident: Document detection time, symptoms, actions taken
    5. ๐Ÿ“ง Stakeholder Notification: CEO notification via monitoring alerts
    %%{
    init: {
    "theme": "base",
    "themeVariables": {
    "primaryColor": "#1565C0",
    "primaryTextColor": "#0d47a1",
    "lineColor": "#1565C0",
    "secondaryColor": "#4CAF50",
    "tertiaryColor": "#FF9800"
    }
    }
    }%%
    graph TD
    INCIDENT[๐Ÿšจ Service Disruption Detected] --> CHECK_CF{CloudFront<br/>Accessible?}

    CHECK_CF -->|No| MANUAL_DNS[๐ŸŒ Manual DNS Failover<br/>to GitHub Pages<br/>RTO: 2 minutes]
    CHECK_CF -->|Yes| CHECK_S3{S3 Origins<br/>Accessible?}

    CHECK_S3 -->|us-east-1 No| AUTO_FAILOVER[โšก Automatic Origin Failover<br/>to eu-west-1<br/>RTO: &lt; 30 seconds]
    CHECK_S3 -->|Both No| ROUTE53_FAILOVER[โš•๏ธ Route 53 Health Check<br/>DNS Failover<br/>RTO: 15 minutes]
    CHECK_S3 -->|Yes| CHECK_HEALTH{Health Check<br/>Passing?}

    CHECK_HEALTH -->|No| INVESTIGATE[๐Ÿ” Investigate Root Cause<br/>Application Error?<br/>Configuration Issue?]
    CHECK_HEALTH -->|Yes| FALSE_ALARM[โœ… False Alarm<br/>Monitor and Document]

    MANUAL_DNS --> VERIFY[โœ… Verify Service Restored]
    AUTO_FAILOVER --> VERIFY
    ROUTE53_FAILOVER --> VERIFY
    INVESTIGATE --> VERIFY

    VERIFY --> DOCUMENT[๐Ÿ“ Incident Documentation<br/>Post-Event Analysis]

    style INCIDENT fill:#FF9800,color:#000000
    style MANUAL_DNS fill:#1565C0,color:#ffffff
    style AUTO_FAILOVER fill:#4CAF50,color:#000000
    style ROUTE53_FAILOVER fill:#1565C0,color:#ffffff
    style VERIFY fill:#4CAF50,color:#000000

    Test TypeFrequencyScopeSuccess Criteria
    โšก Origin Failover TestQuarterlyCloudFront โ†’ S3 eu-west-1Failover < 30 seconds, no data loss
    ๐ŸŒ DNS Failover TestSemi-AnnualRoute 53 โ†’ GitHub PagesFailover within 15 minutes, content identical
    ๐Ÿ”™ Failback TestQuarterlyReturn to primary infrastructureClean restoration, no errors
    ๐Ÿ“Š Monitoring Alert TestMonthlyCloudWatch, Route 53 health checksAlerts delivered within 5 minutes
    ๐Ÿ“‹ Recovery Runbook TestQuarterlyExecute documented proceduresAll steps executable, documentation accurate
    ๐Ÿ” Security Incident DrillAnnualAWS account compromise scenarioCredentials revoked, service restored on DR

    Quarterly Origin Failover Test:

    1. ๐Ÿ”ง Temporarily deny CloudFront access to S3 us-east-1 via bucket policy (add temporary Deny statement for CloudFront Origin Access Identity)
    2. โฑ๏ธ Measure CloudFront automatic failover time to eu-west-1
    3. โœ… Verify content served from eu-west-1 origin
    4. ๐Ÿ”™ Remove the temporary Deny from us-east-1 bucket policy and confirm failback to primary origin
    5. ๐Ÿ“ Document results and improvements

    Semi-Annual DNS Failover Test:

    1. ๐Ÿ”ง Update Route 53 health check to force failure
    2. โฑ๏ธ Measure DNS propagation time
    3. โœ… Verify GitHub Pages serving traffic
    4. ๐Ÿ”™ Restore Route 53 health check
    5. ๐Ÿ“ Document results and TTL impact

    MetricTargetCurrent StatusTrend
    ๐ŸŽฏ Availability99.998%99.999% (YTD)โœ… Exceeding
    โšก Origin Failover RTO< 30 seconds18 seconds (last test)โœ… On track
    ๐ŸŒ DNS Failover RTO15 minutes14 minutes (last test)โœ… On track
    ๐Ÿ’พ Data Synchronization0 RPO0 seconds (real-time)โœ… On track
    ๐Ÿงช BCP TestingQuarterlyLast tested 2026-02โœ… Current
    ๐Ÿ“Š Monitoring Coverage100%100% (all endpoints)โœ… Complete

    Note: The "Current Status" values in this table are illustrative planning examples. Actual operational metrics are monitored via AWS CloudWatch, Route 53 health check logs, and GitHub Pages status, and documented in operational runbooks.


    As CEO/Founder is the sole employee, traditional business continuity teams are not possible. Riksdagsmonitor implements automated infrastructure resilience + comprehensive documentation:

    Capabilities:

    • Cloud Infrastructure Expertise: AWS Solutions Architect, 15+ years experience
    • Automated Failover: CloudFront origin failover, Route 53 health checks (no manual intervention)
    • Documentation: All procedures documented in ISMS for continuity
    • Monitoring: CloudWatch alarms, Route 53 health checks, automated notifications
    • Supplier Relationships: AWS Enterprise Support, GitHub Enterprise Support
    Control TypeImplementationEffectiveness
    ๐Ÿค– Automated FailoverCloudFront origin failover (< 30s), Route 53 DNS failover (15 min)Eliminates manual recovery for primary scenarios
    ๐Ÿ“š DocumentationComplete runbooks in BCPPlan.md, ARCHITECTURE.md, SECURITY_ARCHITECTURE.mdEnables recovery by any technical professional
    ๐Ÿ”„ Infrastructure-as-Code (Planned)AWS static site and DNS infrastructure to be codified in Terraform/CloudFormation (see FUTURE_SECURITY_ARCHITECTURE.md)Future-state: fully reproducible infrastructure from version-controlled IaC
    ๐Ÿ“Š Comprehensive MonitoringCloudWatch, Route 53 health checks, automated alertsReal-time detection and notification
    ๐Ÿ’พ Geographic RedundancyMulti-region S3 (us-east-1 + eu-west-1), GitHub Pages standbyNo single point of failure

    โ„น๏ธ Alignment notice: WORKFLOWS.md, FUTURE_SECURITY_ARCHITECTURE.md and THREAT_MODEL.md are pending update to fully align with the dual-deployment continuity model and current primary hosting described in this BCPPlan. If there is any conflict regarding the current hosting/deployment architecture, this BCPPlan is the authoritative source.



    This section provides detailed, step-by-step incident response playbooks for the three highest-probability incident scenarios for Riksdagsmonitor. All playbooks follow the PICERL framework: Preparation, Identification, Containment, Eradication, Recovery, Lessons Learned.


    Playbook ID: IR-PB-001
    Version: 1.0
    Owner: James Pether Sรถrling, CEO
    Last Reviewed: 2026-02-25

    This playbook activates when any of the following are detected:

    SignalDetection MethodSeverity Indicator
    Unexpected content changes in productionGitHub Actions diff in deploy logHIGH if unauthorized
    Unauthorized Git commits to main branchGitHub audit log alertCRITICAL
    Branch protection bypass detectedGitHub security eventCRITICAL
    Anomalous content detected by user reportUser email to security@hack23.comHIGH
    SLSA attestation failureGitHub Actions security jobHIGH
    Unexpected language content injectionHTMLHint content validationMEDIUM
    SeverityCriteriaResponse TimeEscalation
    P1 - CriticalUnauthorized content in production, branch protection bypass, SLSA attestation failure15 minutes to containmentImmediate personal notification to CEO
    P2 - HighSuspected tampering unconfirmed, anomalous content flagged1 hour to investigationAlert within 30 minutes
    P3 - MediumMinor unexpected changes, validation warnings4 hours to resolutionStandard ISMS notification

    PHASE 1: DETECT (0-15 minutes for P1)

    1. Receive Alert โ€” GitHub Actions notification, user report, or automated monitoring
    2. Verify Authenticity โ€” Confirm alert is genuine (not false positive)
      • Check GitHub Actions run logs for the deploy job
      • Verify SHA-256 hashes in build metadata
      • Review Git commit history on main branch
    3. Classify Severity โ€” Apply classification matrix above
    4. Document Start Time โ€” Record incident start timestamp in UTC
    5. Open Incident Record โ€” Create GitHub Issue with label security-incident

    PHASE 2: TRIAGE (15-30 minutes for P1)

    1. Scope Assessment โ€” Which files are affected? (index.html, all 14 language variants, news articles?)
    2. Impact Assessment โ€” Is tampered content currently visible to users?
    3. Source Identification โ€” Review GitHub audit log for:
      Settings > Security > Audit log
      Filter: Action = "repo.create_actions_secret" or "git.push" or "protected_branch"
    4. Blast Radius โ€” Determine if compromise is isolated or widespread

    PHASE 3: CONTAIN (30-60 minutes for P1)

    1. Immediate Rollback โ€” Revert to last known good commit:
      git log --oneline -20  # Identify last known good commit
      git revert HEAD...<last-good-sha> # Revert to good state
      git push origin main # Trigger redeploy
    2. Block Malicious User (if external) โ€” Via GitHub repository settings
    3. Revoke Compromised Credentials โ€” If credentials were used:
      • Rotate all GitHub Secrets immediately
      • Revoke compromised PATs
      • Regenerate Amazon Bedrock API keys
    4. Enable Temporary Maintenance Mode โ€” If content integrity cannot be confirmed:
      • Temporarily set CloudFront to return 503 for affected paths
      • Display maintenance page with explanation

    PHASE 4: ERADICATE (1-4 hours)

    1. Root Cause Analysis โ€” Determine exact attack vector:
      • Social engineering?
      • Compromised credentials?
      • Supply chain attack via dependency?
      • GitHub Actions workflow injection?
    2. Remove Malicious Content โ€” Clean all affected files
    3. Verify Clean State โ€” SHA-256 comparison against last known good
    4. Patch Vulnerability โ€” Fix the root cause (update dependency, revoke credential, harden workflow)

    PHASE 5: RECOVER (4-24 hours)

    1. Restore Service โ€” Deploy verified clean content
    2. Verify Integrity โ€” Automated integrity checks pass
    3. Monitor Closely โ€” Increased monitoring for 72 hours post-incident
    4. Stakeholder Communication โ€” Post transparent incident report (see template below)

    PHASE 6: POST-INCIDENT (Within 72 hours)

    1. Lessons Learned Meeting โ€” Document findings
    2. Update Controls โ€” Implement additional preventive measures
    3. Update Threat Model โ€” If new attack vector discovered
    4. NIS2 Assessment โ€” Determine if ENISA notification required
    Subject: [Riksdagsmonitor] Security Incident Report - Content Integrity

    Incident: Potential content tampering detected
    Date/Time: [UTC timestamp]
    Severity: [P1/P2/P3]
    Status: [Investigating / Contained / Resolved]

    Summary:
    We detected [brief description]. Our investigation found [findings].

    Actions Taken:
    1. [Action taken]
    2. [Action taken]

    Impact:
    Content was [not affected / affected for X minutes] between [time] and [time].

    Preventive Measures:
    [Measures implemented to prevent recurrence]

    Contact: security@hack23.com
    # Step 1: Identify good commit
    git log --oneline --graph --all | head -30

    # Step 2: Verify content of last known good commit
    git show <good-sha>:index.html | sha256sum

    # Step 3: Create revert commit (preserves history)
    git revert --no-commit <bad-sha>..<HEAD>
    git commit -m "security: revert content tampering incident [IR-PB-001]"

    # Step 4: Push and trigger redeploy
    git push origin main

    # Step 5: Verify production content
    curl -s https://riksdagsmonitor.com/ | sha256sum
    • [ ] GitHub Actions run logs (download and archive)
    • [ ] GitHub Audit Log export for incident timeframe
    • [ ] Git commit history with diff
    • [ ] SHA-256 hashes of affected and clean files
    • [ ] CloudFront access logs for incident timeframe
    • [ ] SLSA attestation records
    • [ ] Sigstore transparency log entries
    • [ ] Browser screenshots of tampered content (if visible)
    • [ ] User reports with timestamps
    • [ ] Credential access logs from GitHub

    Playbook ID: IR-PB-002
    Version: 1.0
    Owner: James Pether Sรถrling, CEO
    Last Reviewed: 2026-02-25

    SignalDetection MethodSeverity
    GitHub Actions MCP job failureWorkflow notification emailHIGH
    riksdag.se API returning 5xx errorsPipeline error logHIGH
    IMF upstream unavailable (data.imf.org / api.imf.org 5xx, DNS, or TLS error)scripts/imf-client.ts retry-exhausted logLOW (optional enrichment โ€” graceful fallback to cached analysis/data/imf/ snapshots)
    API timeout after 30sMCP client timeout logMEDIUM
    Data staleness alert (>48h)Automated staleness checkerMEDIUM
    Amazon Bedrock API unavailableGitHub Actions job failureHIGH
    Zero articles generated for 3+ daysManual monitoring checkHIGH
    CIA platform export unavailableDashboard shows stale dataMEDIUM
    SeverityCriteriaResponse Time
    P1 - CriticalComplete MCP pipeline down, 0 data updates for 24+ hours1 hour
    P2 - HighPartial data failure, degraded content generation, 12-24 hour gap4 hours
    P3 - MediumSingle source unavailable, minor staleness, pipeline flaky24 hours

    PHASE 1: DETECT AND VERIFY

    1. Confirm Outage โ€” Check GitHub Actions run history:
      • Navigate to Actions tab
      • Filter by workflow: news-generation.yml
      • Check last 5 runs for failure pattern
    2. Identify Scope โ€” Determine which component is failing:
      • Riksdag API unavailable?
      • Amazon Bedrock rate limited or unavailable?
      • riksdag-regering-mcp server issue?
      • Network egress blocked by harden-runner?
    3. Check External Status Pages:
    4. Classify Severity and start incident timer

    PHASE 2: TRIAGE

    1. Check Cached Data Availability โ€” Verify cia-data/ directory has recent data
    2. Determine User Impact โ€” Are dashboards showing stale data? How stale?
    3. Estimate Recovery Time โ€” Is this an external outage (wait) or internal issue (fix)?

    PHASE 3: CONTAIN / GRACEFUL DEGRADATION

    1. Activate Stale Data Banner โ€” If data is more than 48 hours old:
      • Edit index.html to show data freshness warning
      • Deploy immediately
    2. Use Cached Data โ€” Pipeline automatically falls back to cia-data/ cache
    3. Disable Failed Pipeline โ€” If pipeline is producing errors, temporarily disable cron:
      # Temporarily comment out schedule trigger in workflow YAML
      # on:
      # schedule:
      # - cron: '0 1 * * *'
    4. Document Outage Start โ€” Record in incident log

    PHASE 4: INVESTIGATE AND RESTORE

    1. External Outage: Wait for provider recovery, monitor status pages
    2. Internal Issue - API Change:
      • Review Riksdag API changelog
      • Update MCP server configuration
      • Test with npm run test:mcp
    3. Internal Issue - Credential:
      • Verify Amazon Bedrock API key in GitHub Secrets
      • Rotate key if expired or compromised
    4. Internal Issue - Rate Limiting:
      • Implement exponential backoff
      • Reduce fetch frequency temporarily
      • Check Riksdag API terms of service

    PHASE 5: RESTORE SERVICE

    1. Re-enable Pipeline โ€” Restore cron schedule in workflow
    2. Run Manual Trigger โ€” workflow_dispatch to verify pipeline works
    3. Verify Output โ€” Confirm articles generate successfully in all 14 languages
    4. Remove Stale Banner โ€” Update HTML once fresh data available
    5. Verify Dashboards โ€” Confirm CIA data dashboards show current data

    PHASE 6: POST-INCIDENT

    1. Document Root Cause โ€” In incident GitHub Issue
    2. Add Monitoring โ€” Alert if no successful pipeline run in 36 hours
    3. Update Runbooks โ€” If new failure mode discovered
    4. Resilience Improvement โ€” Implement recommendation from this incident
    • [ ] MCP server responding to tool discovery
    • [ ] Riksdag API returning valid JSON
    • [ ] Amazon Bedrock API responding within 30s
    • [ ] News generation pipeline completes without error
    • [ ] 14 language articles successfully generated
    • [ ] SHA-256 integrity check passes
    • [ ] Git commit and PR created successfully
    • [ ] CIA data dashboards showing fresh data
    • [ ] Stale data banners removed from all 14 language pages
    • [ ] GitHub Actions workflow next scheduled run confirmed
    Subject: [Riksdagsmonitor] Service Notification - Data Pipeline Status

    Status: [Investigating / Degraded / Restored]
    Affected: Automated news generation and/or data dashboard updates
    Date: [UTC date]

    Current Status:
    The automated data pipeline is [description].
    Content published before [timestamp] remains accurate.

    Expected Resolution:
    [ETA or "Awaiting external provider recovery"]

    Data Freshness:
    Most recent data: [timestamp]
    Best available data is displayed with staleness indicator.

    Updates: Follow https://github.com/Hack23/riksdagsmonitor/issues

    Playbook ID: IR-PB-003
    Version: 1.0
    Owner: James Pether Sรถrling, CEO
    Last Reviewed: 2026-02-25

    SignalDetection MethodSeverity
    Anomalous political content in generated articlesHuman review gateCRITICAL
    SHA-256 hash mismatch for CIA data exportIntegrity check in pipelineHIGH
    JSON schema validation failure from unexpected fieldsData validation logHIGH
    Statistics that contradict known parliamentary dataQuality scoring below thresholdHIGH
    Dramatic unexpected change in voting statisticsAnomaly detectionHIGH
    LLM output contains factually incorrect political claimsHuman reviewMEDIUM
    Unexpected HTML injection in article contentHTMLHint detectionMEDIUM
    SeverityCriteriaResponse Time
    P1 - CriticalConfirmed false political information published and live15 minutes to takedown
    P2 - HighSuspected data poisoning, anomalous content caught by review1 hour investigation
    P3 - MediumData anomaly detected, not yet published4 hours analysis

    PHASE 1: DETECT

    1. Initial Detection โ€” Via human review gate, quality scoring, or user report
    2. Preserve Evidence โ€” Before any changes:
      • Screenshot anomalous content
      • Download and archive current cia-data/ directory
      • Export GitHub Actions run log
      • Record all timestamps in UTC
    3. Initial Assessment โ€” Is this:
      • LLM hallucination (most likely)?
      • Corrupted source data from Riksdag API?
      • Malicious injection into CIA platform export?
      • Supply chain compromise in MCP server?

    PHASE 2: TRIAGE

    1. Trace to Source โ€” Identify where anomalous data entered:
      # Check raw API response data
      cat cia-data/raw-export.json | jq '.["votingStats"]'

      # Compare with previous good data
      git diff HEAD~1 -- cia-data/

      # Check MCP tool call logs in GitHub Actions
      # Navigate: Actions > run-id > news-generation > step-logs
    2. Scope Assessment โ€” How much content is affected?
    3. Published vs Pending โ€” Is anomalous content live or only in pipeline?

    PHASE 3: CONTAIN

    1. If Content Is Live โ€” Immediate quarantine:
      # Revert to last clean version
      git revert HEAD --no-commit
      git commit -m "security: quarantine poisoned content [IR-PB-003]"
      git push origin main
    2. Pause Pipeline โ€” Disable automated news generation until source validated:
      • Comment out cron schedule in workflow YAML
      • Push change to temporarily halt pipeline
    3. Quarantine Data Files โ€” Move suspicious data to quarantine directory:
      mkdir -p cia-data/quarantine/$(date +%Y%m%d)
      cp cia-data/*.json cia-data/quarantine/$(date +%Y%m%d)/
    4. Update Cache โ€” Restore from last verified clean data backup (Git history)

    PHASE 4: VALIDATE SOURCE DATA

    1. Cross-Reference with Riksdag.se โ€” Manually verify key statistics:
    2. Verify CIA Platform Data โ€” Check CIA platform directly:
    3. Re-fetch Clean Data โ€” Trigger fresh MCP data fetch after source verified:
      npm run fetch:cia-data  # Fetch fresh data
      npm run validate:data # Run validation suite
    4. Schema Comparison โ€” Verify data structure matches expected schema:
      npm run validate:schema -- --input cia-data/export.json
      

    PHASE 5: ERADICATE

    1. Remove All Poisoned Content โ€” From production and Git history if needed
    2. Re-validate All Published Articles โ€” Check recent articles against source data
    3. Update Quality Filters โ€” Add detection rules for the anomaly type seen
    4. Enhance LLM Guardrails โ€” Add explicit factual verification prompts

    PHASE 6: RECOVER

    1. Re-enable Pipeline โ€” Restore cron schedule after validation
    2. Generate Fresh Articles โ€” Replace any quarantined content
    3. Issue Correction โ€” If incorrect information was public, issue transparent correction
    4. Enhanced Monitoring โ€” Increase review frequency for 30 days

    PHASE 7: POST-INCIDENT

    1. Root Cause Report โ€” Document in incident GitHub Issue
    2. Control Enhancement โ€” Implement additional preventive measures
    3. Threat Model Update โ€” Update THREAT_MODEL.md with new attack vector
    4. Communication โ€” If users were exposed to false information, issue public statement
    ## Data Poisoning Incident RCA - [DATE]

    **Incident ID:** IR-PB-003-[YYYYMMDD]
    **Severity:** [P1/P2/P3]
    **Detection Time:** [UTC]
    **Containment Time:** [UTC]
    **Resolution Time:** [UTC]

    ### Timeline
    | Time (UTC) | Event |
    |------------|-------|
    | [time] | Anomaly first detected by [method] |
    | [time] | [Action taken] |

    ### Root Cause
    [Describe the root cause: LLM hallucination / API corruption / supply chain]

    ### Attack Vector (if malicious)
    [Describe how attacker introduced false data]

    ### Impact Assessment
    - Content affected: [list of files/articles]
    - Time live: [duration if published]
    - User exposure: [estimated unique users who may have seen false content]

    ### Remediation Steps Taken
    1. [Step taken]
    2. [Step taken]

    ### Preventive Measures Implemented
    1. [Control enhancement]
    2. [Control enhancement]

    ### Lessons Learned
    [Key takeaways for future incident prevention]
    MeasureImplementationStatus
    Human review gate for all AI-generated contentMandatory PR review before mergeActive
    Quality score threshold (0.8/1.0)LLM self-evaluation before translationActive
    SHA-256 integrity hashingEvery article and data fileActive
    JSON schema validationMulti-stage data validation pipelineActive
    Anomaly detection for statistical outliersNumeric range validationActive
    Source data cross-referenceManual spot-check quarterlyPlanned
    LLM output factual verificationCitation requirement in promptsPlanned 2027
    Automated fact-checking against Riksdag.seSelenium scraper validationPlanned 2028

    PlaybookIDP1 ResponseP2 ResponsePrimary ActionEvidence
    Content TamperingIR-PB-00115 min contain1 hr containgit revert + credential rotationGitHub audit + SHA-256
    MCP OutageIR-PB-0021 hr restore4 hr restoreGraceful degrade + pipeline fixActions logs + status pages
    Data PoisoningIR-PB-00315 min takedown1 hr quarantineQuarantine + source validationData diff + cross-ref

    ๐Ÿ“‹ Document Control:
    โœ… Approved by: James Pether Sรถrling, CEO
    ๐Ÿ“ค Distribution: Public
    ๐Ÿท๏ธ Classification: Confidentiality: Public
    ๐Ÿ“… Effective Date: 2026-05-28
    โฐ Next Review: 2026-08-28
    ๐ŸŽฏ Framework Compliance: ISO 27001NIST CSF 2.0CIS Controls


    Effective: 2026-04-24 ยท Authoritative hub: analysis/imf/README.md ยท analysis/imf/agentic-integration.md ยท analysis/imf/indicators-inventory.json ยท analysis/imf/data-dictionary.md ยท .github/aw/ECONOMIC_DATA_CONTRACT.md

    AssetCriticalityRTORPOFallback
    IMF Datamapper RESTSTANDARD24hN/ALast cached vintage in analysis/imf/
    IMF SDMX 3.0 endpointSTANDARD24hN/ALast cached vintage; cross-source SCB for SE-specific
    IMF cache (analysis/imf/ + analysis/daily/*/economic-data.json)HIGH4hN/ARe-fetch from IMF on next workflow run
    ScenarioTriggerDetectionResponse
    IMF-BCP-01 IMF API outage <24hHTTP 5xx persistentWorkflow log + retry budget exhaustedServe last cached vintage; annotate articles "cache fallback"; auto-recover on resolution
    IMF-BCP-02 IMF API outage >24hHTTP 5xx persistent โ‰ฅ24hNews-* workflow runs fail with stale-vintage errorOpen issue; escalate to editorial; switch to SCB for SE-specific GDP/CPI; pause look-ahead workflows
    IMF-BCP-03 WEO vintage cycle skipApr WEO not publishedimf-fetch.ts --healthcheck reports stale vintageAnnotate articles with last vintage + advisory; do not block publishing
    IMF-BCP-04 IMF Datamapper schema breaking changeCI integration test failstests/imf-client.test.ts red on schedulePin client to last-known-good schema; emergency hotfix per Change Management policy
    IMF-BCP-05 IMF licence change (attribution rule modified)Notification on imf.orgManual monitoring quarterlyUpdate article footer template; backfill existing articles
    IMF-BCP-06 IMF rate-limit tighteningHTTP 429 spikeRate-limit metric alarmReduce concurrency; expand cache TTL; communicate to article authors

    The IMF-primary, WB-residue, SCB-Sweden split is itself a BCP control: a single-provider outage degrades but does not break the platform. Look-ahead article workflows degrade gracefully because:

    1. Last cached IMF vintage remains valid for 6 months by contract
    2. SCB national-accounts cover the highest-priority Swedish-specific indicators
    3. WB residue continues to flow for governance/environment/social classes

    Canonical rule. Every economic claim in a Riksdagsmonitor article cites an IMF dataflow first; World Bank citations are reserved for governance, environment and social residue (the classes IMF does not publish). SCB is the Swedish-specific ground truth layer. See ECONOMIC_DATA_CONTRACT.md v2.1 for the banned-phrase list and vintage discipline (>6 mo โ†’ annotation).


    ๐ŸŒ Platforms๐Ÿ“ฆ Open-Source Projects๐Ÿ›ก๏ธ Governance & Standards
    ๐Ÿ—ณ๏ธ Riksdagsmonitor โ€” Swedish Parliament intelligence
    ๐Ÿ‡ช๐Ÿ‡บ EU Parliament Monitor โ€” European coverage
    ๐Ÿ•ต๏ธ Citizen Intelligence Agency โ€” political-data engine
    ๐ŸŒ Hack23 AB โ€” corporate site
    ๐Ÿ“ฐ Hack23 Blog โ€” engineering & policy
    ๐Ÿ’ผ Hack23 on LinkedIn
    ๐Ÿ—ณ๏ธ Hack23/riksdagsmonitor
    ๐Ÿ•ต๏ธ Hack23/cia
    ๐Ÿ‡ช๐Ÿ‡บ Hack23/euparliamentmonitor
    ๐Ÿ”Œ Hack23/european-parliament-mcp
    โœ… Hack23/cia-compliance-manager
    ๐Ÿฅ‹ Hack23/black-trigram
    ๐Ÿ  Hack23/homepage
    ๐Ÿ›ก๏ธ Hack23 ISMS-PUBLIC โ€” public ISMS
    ๐Ÿ”’ Information Security Policy
    ๐Ÿค– AI Policy
    ๐Ÿงช Secure Development Policy
    ๐ŸŽฏ Threat Modeling Policy
    โš ๏ธ Vulnerability Management
    ๐Ÿท๏ธ Classification Framework

    OpenSSF Best PracticesOpenSSF ScorecardISO 27001:2022NIST CSF 2.0CIS Controls v8.1Apache 2.0

    ๐Ÿ—ณ๏ธ Empower citizens ยท ๐Ÿ” Strengthen democratic accountability ยท ๐Ÿ•ต๏ธ Illuminate the political process

    ยฉ 2008โ€“2026 Hack23 AB (Org.nr 559534-7807) ยท Maintainer: James Pether Sรถrling, CISSP CISM