# Security-Feed-Storage-Canary

Security-Feed-Storage-Canary ist definiert, aber noch nicht erfolgreich gespeichert oder durch Freigabe-Gates blockiert.

> Der Canary ist ein synthetischer privater Storage-Test. Er ersetzt keine produktiven Feed-Credentials und behauptet keinen echten Malware-, Blacklist- oder DAST-Treffer.

## Gate
- Status: not_run_yet
- Ready to run: nein
- Storage approved: nein
- Externe Feeds: nein
- Oeffentlicher Treffer: nein

## Synthetische Observation
- domain: canary.saferpage.test
- source_id: security_feed_storage_canary
- verdict: inconclusive
- severity: info
- matched_url: https://canary.saferpage.test/.well-known/saferpage-security-feed-canary
- reference_id_pattern: saferpage-storage-canary-YYYY-MM-DD
- review_status: private_evidence
- publish_decision: not_public
- result_meta_flags: {"synthetic_canary":true,"configured":true,"run_requested":true}

## Erwartete DB-Effekte
- security_feed_observations: Eine upsertbare synthetische Observation mit source_id=security_feed_storage_canary, verdict=inconclusive, publish_decision=not_public.
- security_feed_audit_log: Ein Auditlog-Eintrag runner_observation_upsert mit after_hash ueber die normalisierten Metadaten.
- security_feed_alert_links: Kein Alert-Link und kein Ticket, weil der Canary kein echter Treffer ist.
- dedupe: Dedupe-Key aus Domain, Source, matched_url und reference_id verhindert doppelte Tages-Observations.
- retention: Inconclusive-Canary laeuft nach 14 Tagen ab, sofern er nicht durch den naechsten Canary-Lauf aktualisiert wird.

## Verbotene Effekte
- Keine externen URLhaus-, Safe-Browsing-, Malware-, Phishing- oder DAST-Abfragen.
- Keine Feed-Rohpayloads, Malware-Samples, Seiteninhalte, Secret-Werte, IP-Adressen oder personenbezogene Logs speichern.
- Keine oeffentliche Trefferanzeige, kein Badge-Claim und keine automatische Betreiberwarnung ausloesen.

## Operator-Kommandos
- dry_run_without_write: `python3 scripts/run-security-feed-schedule.py anrufer.info --base-url http://127.0.0.1 --max 1 --timeout 15`
- blocked_canary_check: `python3 scripts/run-security-feed-schedule.py anrufer.info --base-url http://127.0.0.1 --max 1 --timeout 15 --storage-canary`
- approved_canary_write: `SAFERPAGE_SECURITY_FEED_STORAGE_APPROVED=yes python3 scripts/run-security-feed-schedule.py anrufer.info --base-url http://127.0.0.1 --max 1 --timeout 15 --storage-canary`
- systemd_canary_status: `systemctl status saferpage-security-feed-canary.timer saferpage-security-feed-canary.service --no-pager`
- systemd_canary_start: `systemctl start saferpage-security-feed-canary.service`
- verify_last_state: `curl -fsS https://saferpage.de/sicherheit/feed-runner-json | python3 -m json.tool`

## systemd
- service: saferpage-security-feed-canary.service
- timer: saferpage-security-feed-canary.timer
- cadence: weekly Tuesday
- window: 04:15-04:35 Europe/Berlin plus RandomizedDelaySec 20min
- exec_mode: --storage-canary without --execute-ready
- environment_file: /etc/saferpage/security-feed.env
- safe_without_env_file: true

## Abnahme
- Ohne SAFERPAGE_SECURITY_FEED_STORAGE_APPROVED bleibt status=blocked_without_storage_approval.
- Mit Storage-Freigabe wird genau eine synthetische Observation gespeichert und storage_canary_stored_observation_count=1 gemeldet.
- stored_observation_count fuer echte externe Feeds bleibt unveraendert, solange --execute-ready nicht aktiv ist.
- result_meta enthaelt synthetic_canary=true und keine verbotenen Felder.
- Launch-Board und Approval-Dossier zeigen weiterhin keine produktive Feed-Aktivierung, solange Credentials/Freigaben fehlen.

## Letzter Runner-State
- available: true
- job_id: security-feed-runner-2026-06-09T033901z0000
- finished_at: 2026-06-09T03:39:02+00:00
- execute_ready: true
- external_stored_observation_count: 0
- canary_enabled: false
- canary_status: 
- canary_stored_observation_count: 0
- canary_dedupe_key: 
- canary_error: 
