cyberflage 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. cyberflage-0.1.0/PKG-INFO +37 -0
  2. cyberflage-0.1.0/README.md +26 -0
  3. cyberflage-0.1.0/cyberflage/__init__.py +6 -0
  4. cyberflage-0.1.0/cyberflage/__main__.py +54 -0
  5. cyberflage-0.1.0/cyberflage/alerts/__init__.py +1 -0
  6. cyberflage-0.1.0/cyberflage/alerts/manager.py +26 -0
  7. cyberflage-0.1.0/cyberflage/app.py +45 -0
  8. cyberflage-0.1.0/cyberflage/config.py +31 -0
  9. cyberflage-0.1.0/cyberflage/core/__init__.py +1 -0
  10. cyberflage-0.1.0/cyberflage/core/decision_engine.py +39 -0
  11. cyberflage-0.1.0/cyberflage/core/risk_manager.py +28 -0
  12. cyberflage-0.1.0/cyberflage/core/signals.py +15 -0
  13. cyberflage-0.1.0/cyberflage/dashboard/__init__.py +1 -0
  14. cyberflage-0.1.0/cyberflage/dashboard/server.py +32 -0
  15. cyberflage-0.1.0/cyberflage/deception/__init__.py +1 -0
  16. cyberflage-0.1.0/cyberflage/deception/engine.py +22 -0
  17. cyberflage-0.1.0/cyberflage/network/__init__.py +1 -0
  18. cyberflage-0.1.0/cyberflage/network/monitor.py +30 -0
  19. cyberflage-0.1.0/cyberflage/persistence/__init__.py +1 -0
  20. cyberflage-0.1.0/cyberflage/persistence/manager.py +20 -0
  21. cyberflage-0.1.0/cyberflage/utils/__init__.py +1 -0
  22. cyberflage-0.1.0/cyberflage.egg-info/PKG-INFO +37 -0
  23. cyberflage-0.1.0/cyberflage.egg-info/SOURCES.txt +27 -0
  24. cyberflage-0.1.0/cyberflage.egg-info/dependency_links.txt +1 -0
  25. cyberflage-0.1.0/cyberflage.egg-info/entry_points.txt +2 -0
  26. cyberflage-0.1.0/cyberflage.egg-info/requires.txt +4 -0
  27. cyberflage-0.1.0/cyberflage.egg-info/top_level.txt +1 -0
  28. cyberflage-0.1.0/pyproject.toml +23 -0
  29. cyberflage-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: cyberflage
3
+ Version: 0.1.0
4
+ Summary: Modular CyberFlage package
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: psutil
8
+ Requires-Dist: watchdog
9
+ Requires-Dist: flask
10
+ Requires-Dist: requests
11
+
12
+ # CyberFlage
13
+
14
+ Modular, production-ready Python package for cybersecurity signal processing and deception orchestration.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install -e .
20
+ ```
21
+
22
+ ## Public API
23
+
24
+ ```python
25
+ from cyberflage import CyberFlage, build_config
26
+
27
+ app = CyberFlage(build_config(None))
28
+ result = app.run_once()
29
+ print(result)
30
+ ```
31
+
32
+ ## CLI
33
+
34
+ ```bash
35
+ python -m cyberflage --run-once
36
+ python -m cyberflage --config "{\"thresholds\":{\"HIGH\":55,\"CRITICAL\":80}}" --run-once
37
+ ```
@@ -0,0 +1,26 @@
1
+ # CyberFlage
2
+
3
+ Modular, production-ready Python package for cybersecurity signal processing and deception orchestration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install -e .
9
+ ```
10
+
11
+ ## Public API
12
+
13
+ ```python
14
+ from cyberflage import CyberFlage, build_config
15
+
16
+ app = CyberFlage(build_config(None))
17
+ result = app.run_once()
18
+ print(result)
19
+ ```
20
+
21
+ ## CLI
22
+
23
+ ```bash
24
+ python -m cyberflage --run-once
25
+ python -m cyberflage --config "{\"thresholds\":{\"HIGH\":55,\"CRITICAL\":80}}" --run-once
26
+ ```
@@ -0,0 +1,6 @@
1
+ """CyberFlage public package exports."""
2
+
3
+ from .app import CyberFlage
4
+ from .config import build_config
5
+
6
+ __all__ = ["CyberFlage", "build_config"]
@@ -0,0 +1,54 @@
1
+ """CLI entrypoint for the cyberflage package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ from typing import Any
8
+
9
+ from .app import CyberFlage
10
+ from .config import build_config
11
+
12
+
13
+ def parse_args() -> argparse.Namespace:
14
+ """Parse command-line arguments."""
15
+ parser = argparse.ArgumentParser(description="Run CyberFlage.")
16
+ parser.add_argument(
17
+ "--config",
18
+ type=str,
19
+ default=None,
20
+ help="JSON string with configuration overrides.",
21
+ )
22
+ parser.add_argument(
23
+ "--run-once",
24
+ action="store_true",
25
+ help="Run a single detection cycle and exit.",
26
+ )
27
+ return parser.parse_args()
28
+
29
+
30
+ def main() -> int:
31
+ """Run CyberFlage from CLI."""
32
+ args = parse_args()
33
+ overrides: dict[str, Any] | None = None
34
+
35
+ if args.config:
36
+ try:
37
+ parsed = json.loads(args.config)
38
+ except json.JSONDecodeError as exc:
39
+ raise SystemExit(f"Invalid JSON for --config: {exc}") from exc
40
+ if not isinstance(parsed, dict):
41
+ raise SystemExit("--config must be a JSON object.")
42
+ overrides = parsed
43
+
44
+ app = CyberFlage(build_config(overrides))
45
+ if args.run_once:
46
+ app.run_once()
47
+ else:
48
+ app.start_dashboard()
49
+ app.run_once()
50
+ return 0
51
+
52
+
53
+ if __name__ == "__main__":
54
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ """Alerting components."""
@@ -0,0 +1,26 @@
1
+ """Alert dispatch manager."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from typing import Any
7
+
8
+
9
+ class AlertManager:
10
+ """Dispatches alert messages using logging."""
11
+
12
+ def __init__(self, config: dict[str, Any]) -> None:
13
+ self.config = config
14
+ self.logger = logging.getLogger("cyberflage.alerts")
15
+ if not self.logger.handlers:
16
+ logging.basicConfig(level=logging.INFO)
17
+
18
+ def dispatch(self, level: str, message: str) -> None:
19
+ """Log alert with severity mapped from level."""
20
+ level_map = {
21
+ "LOW": logging.INFO,
22
+ "MEDIUM": logging.WARNING,
23
+ "HIGH": logging.ERROR,
24
+ "CRITICAL": logging.CRITICAL,
25
+ }
26
+ self.logger.log(level_map.get(level, logging.INFO), "[%s] %s", level, message)
@@ -0,0 +1,45 @@
1
+ """Main CyberFlage orchestration class."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from .alerts.manager import AlertManager
8
+ from .core.decision_engine import DecisionEngine
9
+ from .dashboard.server import DashboardServer
10
+ from .deception.engine import DeceptionEngine
11
+ from .network.monitor import NetworkMonitor
12
+ from .persistence.manager import PersistenceManager
13
+
14
+
15
+ class CyberFlage:
16
+ """Orchestrates scanning, decisioning, deception, alerts, and persistence."""
17
+
18
+ def __init__(self, config: dict[str, Any]) -> None:
19
+ self.config = config
20
+ self.decision_engine = DecisionEngine(config)
21
+ self.network_monitor = NetworkMonitor(config)
22
+ self.deception_engine = DeceptionEngine(config)
23
+ self.alert_manager = AlertManager(config)
24
+ self.persistence_manager = PersistenceManager(config)
25
+ self.dashboard_server = DashboardServer(config)
26
+
27
+ def start_dashboard(self) -> None:
28
+ """Start optional dashboard when enabled."""
29
+ self.dashboard_server.start()
30
+
31
+ def run_once(self) -> dict[str, Any]:
32
+ """Run one complete processing cycle."""
33
+ signals = self.network_monitor.scan()
34
+ level = self.decision_engine.ingest_signals(signals)
35
+ action = self.deception_engine.evaluate(level)
36
+ self.alert_manager.dispatch(level, action)
37
+
38
+ state = {
39
+ "signals": [signal.name for signal in signals],
40
+ "risk_score": self.decision_engine.risk_manager.score,
41
+ "level": level,
42
+ "action": action,
43
+ }
44
+ self.persistence_manager.save(state)
45
+ return state
@@ -0,0 +1,31 @@
1
+ """Configuration helpers for CyberFlage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from copy import deepcopy
6
+ from typing import Any
7
+
8
+ DEFAULT_CONFIG: dict[str, Any] = {
9
+ "thresholds": {"MEDIUM": 30.0, "HIGH": 60.0, "CRITICAL": 85.0},
10
+ "risk": {"decay_factor": 0.98},
11
+ "persistence": {"state_file": "cyberflage_state.json"},
12
+ "dashboard": {"enabled": False, "host": "127.0.0.1", "port": 5000},
13
+ "alerts": {"channel": "logging"},
14
+ }
15
+
16
+
17
+ def _merge(base: dict[str, Any], overrides: dict[str, Any]) -> dict[str, Any]:
18
+ merged = deepcopy(base)
19
+ for key, value in overrides.items():
20
+ if isinstance(value, dict) and isinstance(merged.get(key), dict):
21
+ merged[key] = _merge(merged[key], value)
22
+ else:
23
+ merged[key] = value
24
+ return merged
25
+
26
+
27
+ def build_config(overrides: dict[str, Any] | None) -> dict[str, Any]:
28
+ """Build a runtime config from safe defaults and optional overrides."""
29
+ if overrides is None:
30
+ return deepcopy(DEFAULT_CONFIG)
31
+ return _merge(DEFAULT_CONFIG, overrides)
@@ -0,0 +1 @@
1
+ """Core decision and risk components."""
@@ -0,0 +1,39 @@
1
+ """Decision engine mapping score to action levels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterable
6
+ from typing import Any
7
+
8
+ from .risk_manager import RiskManager
9
+ from .signals import Signal
10
+
11
+
12
+ class DecisionEngine:
13
+ """Ingests signals and computes action level."""
14
+
15
+ def __init__(self, config: dict[str, Any]) -> None:
16
+ risk_cfg = config.get("risk", {})
17
+ self.risk_manager = RiskManager(decay_factor=float(risk_cfg.get("decay_factor", 1.0)))
18
+ self.thresholds = config.get("thresholds", {})
19
+
20
+ def ingest_signals(self, signals: Iterable[Signal]) -> str:
21
+ """Ingest signals, update score, and return current action level."""
22
+ self.risk_manager.decay()
23
+ for signal in signals:
24
+ self.risk_manager.add_signal(signal)
25
+ return self.action_level()
26
+
27
+ def action_level(self) -> str:
28
+ """Return LOW, MEDIUM, HIGH, or CRITICAL based on thresholds."""
29
+ score = self.risk_manager.score
30
+ medium = float(self.thresholds.get("MEDIUM", 30.0))
31
+ high = float(self.thresholds.get("HIGH", 60.0))
32
+ critical = float(self.thresholds.get("CRITICAL", 85.0))
33
+ if score >= critical:
34
+ return "CRITICAL"
35
+ if score >= high:
36
+ return "HIGH"
37
+ if score >= medium:
38
+ return "MEDIUM"
39
+ return "LOW"
@@ -0,0 +1,28 @@
1
+ """Risk score manager."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .signals import Signal
6
+
7
+
8
+ class RiskManager:
9
+ """Accumulates weighted signals and maintains a clamped score."""
10
+
11
+ def __init__(self, decay_factor: float = 1.0) -> None:
12
+ self._score = 0.0
13
+ self._decay_factor = max(0.0, min(1.0, decay_factor))
14
+
15
+ def add_signal(self, signal: Signal) -> None:
16
+ """Add a signal weight to current score."""
17
+ self._score += float(signal.weight)
18
+ self._score = max(0.0, min(100.0, self._score))
19
+
20
+ def decay(self) -> None:
21
+ """Apply configured decay to score."""
22
+ self._score *= self._decay_factor
23
+ self._score = max(0.0, min(100.0, self._score))
24
+
25
+ @property
26
+ def score(self) -> float:
27
+ """Current score clamped to 0-100."""
28
+ return max(0.0, min(100.0, self._score))
@@ -0,0 +1,15 @@
1
+ """Signal model for CyberFlage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any
7
+
8
+
9
+ @dataclass(slots=True)
10
+ class Signal:
11
+ """Signal generated by one subsystem."""
12
+
13
+ name: str
14
+ weight: float
15
+ metadata: dict[str, Any] = field(default_factory=dict)
@@ -0,0 +1 @@
1
+ """Dashboard components."""
@@ -0,0 +1,32 @@
1
+ """Optional dashboard server."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ try:
8
+ from flask import Flask
9
+ except Exception: # pragma: no cover
10
+ Flask = None
11
+
12
+
13
+ class DashboardServer:
14
+ """Starts a simple dashboard only when enabled and Flask is available."""
15
+
16
+ def __init__(self, config: dict[str, Any]) -> None:
17
+ dashboard = config.get("dashboard", {})
18
+ self.enabled = bool(dashboard.get("enabled", False))
19
+ self.host = str(dashboard.get("host", "127.0.0.1"))
20
+ self.port = int(dashboard.get("port", 5000))
21
+ self.app = Flask(__name__) if self.enabled and Flask is not None else None
22
+
23
+ def start(self) -> None:
24
+ """Start dashboard server or no-op."""
25
+ if not self.enabled or self.app is None:
26
+ return
27
+
28
+ @self.app.get("/health")
29
+ def health() -> dict[str, str]:
30
+ return {"status": "ok"}
31
+
32
+ self.app.run(host=self.host, port=self.port)
@@ -0,0 +1 @@
1
+ """Deception engine components."""
@@ -0,0 +1,22 @@
1
+ """Deception response engine."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ class DeceptionEngine:
9
+ """Generates operational deception actions from risk level."""
10
+
11
+ def __init__(self, config: dict[str, Any]) -> None:
12
+ self.config = config
13
+
14
+ def evaluate(self, level: str) -> str:
15
+ """Return an action message for given level."""
16
+ messages = {
17
+ "LOW": "Continue passive monitoring.",
18
+ "MEDIUM": "Increase decoy visibility.",
19
+ "HIGH": "Deploy active deception traps.",
20
+ "CRITICAL": "Escalate to full deception protocol.",
21
+ }
22
+ return messages.get(level, messages["LOW"])
@@ -0,0 +1 @@
1
+ """Network monitoring components."""
@@ -0,0 +1,30 @@
1
+ """Network monitor with safe stub behavior."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from ..core.signals import Signal
8
+
9
+ try:
10
+ import psutil
11
+ except Exception: # pragma: no cover
12
+ psutil = None
13
+
14
+
15
+ class NetworkMonitor:
16
+ """Collects local telemetry and emits signals."""
17
+
18
+ def __init__(self, config: dict[str, Any]) -> None:
19
+ self.config = config
20
+
21
+ def scan(self) -> list[Signal]:
22
+ """Return current signals based on safe local checks."""
23
+ signals: list[Signal] = []
24
+ if psutil is None:
25
+ return signals
26
+
27
+ cpu_percent = float(psutil.cpu_percent(interval=0.0))
28
+ if cpu_percent > 90.0:
29
+ signals.append(Signal(name="high_cpu", weight=10.0, metadata={"cpu_percent": cpu_percent}))
30
+ return signals
@@ -0,0 +1 @@
1
+ """Persistence components."""
@@ -0,0 +1,20 @@
1
+ """JSON state persistence manager."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+
10
+ class PersistenceManager:
11
+ """Persists latest runtime state to a JSON file."""
12
+
13
+ def __init__(self, config: dict[str, Any]) -> None:
14
+ file_name = str(config.get("persistence", {}).get("state_file", "cyberflage_state.json"))
15
+ self.state_path = Path(file_name)
16
+
17
+ def save(self, state: dict[str, Any]) -> None:
18
+ """Persist provided state to disk."""
19
+ self.state_path.parent.mkdir(parents=True, exist_ok=True)
20
+ self.state_path.write_text(json.dumps(state, indent=2), encoding="utf-8")
@@ -0,0 +1 @@
1
+ """Utility helpers namespace."""
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: cyberflage
3
+ Version: 0.1.0
4
+ Summary: Modular CyberFlage package
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: psutil
8
+ Requires-Dist: watchdog
9
+ Requires-Dist: flask
10
+ Requires-Dist: requests
11
+
12
+ # CyberFlage
13
+
14
+ Modular, production-ready Python package for cybersecurity signal processing and deception orchestration.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install -e .
20
+ ```
21
+
22
+ ## Public API
23
+
24
+ ```python
25
+ from cyberflage import CyberFlage, build_config
26
+
27
+ app = CyberFlage(build_config(None))
28
+ result = app.run_once()
29
+ print(result)
30
+ ```
31
+
32
+ ## CLI
33
+
34
+ ```bash
35
+ python -m cyberflage --run-once
36
+ python -m cyberflage --config "{\"thresholds\":{\"HIGH\":55,\"CRITICAL\":80}}" --run-once
37
+ ```
@@ -0,0 +1,27 @@
1
+ README.md
2
+ pyproject.toml
3
+ cyberflage/__init__.py
4
+ cyberflage/__main__.py
5
+ cyberflage/app.py
6
+ cyberflage/config.py
7
+ cyberflage.egg-info/PKG-INFO
8
+ cyberflage.egg-info/SOURCES.txt
9
+ cyberflage.egg-info/dependency_links.txt
10
+ cyberflage.egg-info/entry_points.txt
11
+ cyberflage.egg-info/requires.txt
12
+ cyberflage.egg-info/top_level.txt
13
+ cyberflage/alerts/__init__.py
14
+ cyberflage/alerts/manager.py
15
+ cyberflage/core/__init__.py
16
+ cyberflage/core/decision_engine.py
17
+ cyberflage/core/risk_manager.py
18
+ cyberflage/core/signals.py
19
+ cyberflage/dashboard/__init__.py
20
+ cyberflage/dashboard/server.py
21
+ cyberflage/deception/__init__.py
22
+ cyberflage/deception/engine.py
23
+ cyberflage/network/__init__.py
24
+ cyberflage/network/monitor.py
25
+ cyberflage/persistence/__init__.py
26
+ cyberflage/persistence/manager.py
27
+ cyberflage/utils/__init__.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cyberflage = cyberflage.__main__:main
@@ -0,0 +1,4 @@
1
+ psutil
2
+ watchdog
3
+ flask
4
+ requests
@@ -0,0 +1 @@
1
+ cyberflage
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cyberflage"
7
+ version = "0.1.0"
8
+ description = "Modular CyberFlage package"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "psutil",
13
+ "watchdog",
14
+ "flask",
15
+ "requests",
16
+ ]
17
+
18
+ [project.scripts]
19
+ cyberflage = "cyberflage.__main__:main"
20
+
21
+ [tool.setuptools.packages.find]
22
+ where = ["."]
23
+ include = ["cyberflage*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+