ocean-basket-protocol 2.3.0__py3-none-any.whl
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.
- obp/__init__.py +292 -0
- obp/_rust_bridge.py +81 -0
- obp/cli.py +214 -0
- obp/config.py +139 -0
- obp/core.py +694 -0
- obp/exceptions.py +55 -0
- obp/honeypot.py +397 -0
- obp/input_sanitizer.py +346 -0
- obp/leakguard.py +425 -0
- obp/log_sanitizer.py +353 -0
- obp/middleware.py +183 -0
- obp/rate_limiter.py +351 -0
- obp/secrets_manager.py +240 -0
- obp/secure_audit.py +491 -0
- obp/session.py +653 -0
- obp/timeline.py +267 -0
- obp/tls_context.py +274 -0
- obp/tpm.py +255 -0
- obp/trap_engine.py +776 -0
- ocean_basket_protocol-2.3.0.dist-info/METADATA +566 -0
- ocean_basket_protocol-2.3.0.dist-info/RECORD +25 -0
- ocean_basket_protocol-2.3.0.dist-info/WHEEL +5 -0
- ocean_basket_protocol-2.3.0.dist-info/entry_points.txt +2 -0
- ocean_basket_protocol-2.3.0.dist-info/licenses/LICENSE +47 -0
- ocean_basket_protocol-2.3.0.dist-info/top_level.txt +1 -0
obp/__init__.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"""Ocean Basket Protocol (OBP)
|
|
2
|
+
|
|
3
|
+
Physics-inspired self-protecting security framework.
|
|
4
|
+
The ocean protects itself.
|
|
5
|
+
|
|
6
|
+
Quick Start:
|
|
7
|
+
>>> from obp import obp, OBPConfig, ProtectionMode
|
|
8
|
+
>>>
|
|
9
|
+
>>> config = OBPConfig(mode=ProtectionMode.DEFENSIVE)
|
|
10
|
+
>>>
|
|
11
|
+
>>> @obp.protect(config)
|
|
12
|
+
... def sensitive_operation(api_key: str):
|
|
13
|
+
... return {"status": "success"}
|
|
14
|
+
|
|
15
|
+
Core Components:
|
|
16
|
+
- obp: Global OBP singleton instance
|
|
17
|
+
- OBPConfig: Configuration dataclass
|
|
18
|
+
- ProtectionMode: Protection level enum
|
|
19
|
+
- OceanBasketError: Base exception
|
|
20
|
+
- LeakGuard: Secret detection engine
|
|
21
|
+
- render_timeline: Visual timeline renderer
|
|
22
|
+
|
|
23
|
+
Security Hardening:
|
|
24
|
+
- TPMManager: Hardware-backed cryptographic signing
|
|
25
|
+
- HoneypotManager: Active honeypot deception system
|
|
26
|
+
- SecureAuditLogger: Tamper-evident audit logging
|
|
27
|
+
- SessionHijackingProtection: Session security
|
|
28
|
+
|
|
29
|
+
Protection Modes:
|
|
30
|
+
- GRACEFUL: Returns decoy values on threat detection
|
|
31
|
+
- DEFENSIVE: Adds viscosity and steam burn penalties
|
|
32
|
+
- PARANOID: Raises exceptions and triggers reversion
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
from obp import obp, OBPConfig, ProtectionMode, render_timeline
|
|
36
|
+
|
|
37
|
+
config = OBPConfig(
|
|
38
|
+
viscosity=0.8,
|
|
39
|
+
max_temperature=0.9,
|
|
40
|
+
mode=ProtectionMode.DEFENSIVE,
|
|
41
|
+
enable_leakguard=True
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
@obp.protect(config)
|
|
45
|
+
def protected_function(secret_key: str, data: str):
|
|
46
|
+
# Protected execution
|
|
47
|
+
return {"processed": data}
|
|
48
|
+
|
|
49
|
+
# View audit timeline
|
|
50
|
+
render_timeline(obp.audit_log)
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
__version__ = "2.3.0"
|
|
55
|
+
__author__ = "OBP Authors"
|
|
56
|
+
__license__ = "PROPRIETARY - All Rights Reserved"
|
|
57
|
+
|
|
58
|
+
from .config import (
|
|
59
|
+
LeakGuardConfig,
|
|
60
|
+
LogSanitizationConfig,
|
|
61
|
+
OBPConfig,
|
|
62
|
+
ProtectionMode,
|
|
63
|
+
ReversionSpeed,
|
|
64
|
+
TimelineConfig,
|
|
65
|
+
)
|
|
66
|
+
from .core import OBP, AntiPatchProtection, MemoryProtection, obp, reset_obp
|
|
67
|
+
from .exceptions import (
|
|
68
|
+
ConfigurationError,
|
|
69
|
+
ContextViolationError,
|
|
70
|
+
LeakDetectedError,
|
|
71
|
+
OceanBasketError,
|
|
72
|
+
ProtectionModeError,
|
|
73
|
+
ResonanceError,
|
|
74
|
+
ReversionError,
|
|
75
|
+
)
|
|
76
|
+
from .honeypot import (
|
|
77
|
+
DecoyValue,
|
|
78
|
+
HoneypotAlertLevel,
|
|
79
|
+
HoneypotConfig,
|
|
80
|
+
HoneypotManager,
|
|
81
|
+
HoneypotType,
|
|
82
|
+
get_honeypot_manager,
|
|
83
|
+
)
|
|
84
|
+
from .leakguard import LeakGuard
|
|
85
|
+
from .log_sanitizer import (
|
|
86
|
+
LogSanitizer,
|
|
87
|
+
disable_log_sanitization,
|
|
88
|
+
enable_log_sanitization,
|
|
89
|
+
redact_secrets,
|
|
90
|
+
sanitize_output,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Rate limiting
|
|
94
|
+
from .rate_limiter import (
|
|
95
|
+
RateLimitConfig,
|
|
96
|
+
RateLimiter,
|
|
97
|
+
SlidingWindowLog,
|
|
98
|
+
TokenBucket,
|
|
99
|
+
get_rate_limiter,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Secrets manager integration
|
|
103
|
+
from .secrets_manager import SecretConfig, SecretManagerType, SecretsManager, get_secrets_manager
|
|
104
|
+
from .secure_audit import (
|
|
105
|
+
LogLevel,
|
|
106
|
+
SecureAuditConfig,
|
|
107
|
+
SecureAuditLogger,
|
|
108
|
+
SecureLogEntry,
|
|
109
|
+
TamperEvidence,
|
|
110
|
+
get_audit_logger,
|
|
111
|
+
)
|
|
112
|
+
from .session import (
|
|
113
|
+
Session,
|
|
114
|
+
SessionConfig,
|
|
115
|
+
SessionFingerprint,
|
|
116
|
+
SessionHijackingProtection,
|
|
117
|
+
SessionStatus,
|
|
118
|
+
get_session_protection,
|
|
119
|
+
)
|
|
120
|
+
from .timeline import get_timeline_stats, render_timeline
|
|
121
|
+
|
|
122
|
+
# Security hardening modules
|
|
123
|
+
from .tpm import TPMAvailability, TPMConfig, TPMManager, get_tpm_manager
|
|
124
|
+
|
|
125
|
+
# Trap Engine - Attribution & Deception
|
|
126
|
+
from .trap_engine import (
|
|
127
|
+
AlertChannel,
|
|
128
|
+
AttackerIntel,
|
|
129
|
+
ForensicEvidence,
|
|
130
|
+
ForensicLogger,
|
|
131
|
+
RealTimeReporter,
|
|
132
|
+
TrapEngine,
|
|
133
|
+
TrapLevel,
|
|
134
|
+
configure_trap_engine,
|
|
135
|
+
trap,
|
|
136
|
+
trap_access,
|
|
137
|
+
trap_engine,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# TLS Context Verification (NEW - v3.0)
|
|
141
|
+
from .tls_context import (
|
|
142
|
+
TLSContextVerifier,
|
|
143
|
+
TLSContextInfo,
|
|
144
|
+
TLSVerificationStatus,
|
|
145
|
+
get_tls_verifier,
|
|
146
|
+
verify_tls_context,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Input Sanitization (NEW - v3.0)
|
|
150
|
+
from .input_sanitizer import (
|
|
151
|
+
InputSanitizer,
|
|
152
|
+
InjectionType,
|
|
153
|
+
SanitizationResult,
|
|
154
|
+
sanitize_input,
|
|
155
|
+
get_input_sanitizer,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# CLI and Middleware - lazy imports for optional dependencies
|
|
160
|
+
def __getattr__(name: str):
|
|
161
|
+
"""Lazy import for optional dependencies."""
|
|
162
|
+
if name == "cli":
|
|
163
|
+
import rich # noqa: F401
|
|
164
|
+
|
|
165
|
+
from . import cli as cli_module
|
|
166
|
+
return cli_module
|
|
167
|
+
if name in ("OBPMiddleware", "create_fastapi_middleware"):
|
|
168
|
+
from .middleware import OBPMiddleware, create_fastapi_middleware
|
|
169
|
+
globals()["OBPMiddleware"] = OBPMiddleware
|
|
170
|
+
globals()["create_fastapi_middleware"] = create_fastapi_middleware
|
|
171
|
+
if name == "OBPMiddleware":
|
|
172
|
+
return OBPMiddleware
|
|
173
|
+
return create_fastapi_middleware
|
|
174
|
+
raise AttributeError(f"module 'obp' has no attribute '{name}'")
|
|
175
|
+
|
|
176
|
+
__all__ = [
|
|
177
|
+
# Version
|
|
178
|
+
"__version__",
|
|
179
|
+
"__author__",
|
|
180
|
+
"__license__",
|
|
181
|
+
|
|
182
|
+
# Core
|
|
183
|
+
"obp",
|
|
184
|
+
"OBP",
|
|
185
|
+
"reset_obp",
|
|
186
|
+
"AntiPatchProtection",
|
|
187
|
+
"MemoryProtection",
|
|
188
|
+
|
|
189
|
+
# Configuration
|
|
190
|
+
"OBPConfig",
|
|
191
|
+
"ProtectionMode",
|
|
192
|
+
"ReversionSpeed",
|
|
193
|
+
"LeakGuardConfig",
|
|
194
|
+
"TimelineConfig",
|
|
195
|
+
"LogSanitizationConfig",
|
|
196
|
+
|
|
197
|
+
# Exceptions
|
|
198
|
+
"OceanBasketError",
|
|
199
|
+
"ContextViolationError",
|
|
200
|
+
"LeakDetectedError",
|
|
201
|
+
"ProtectionModeError",
|
|
202
|
+
"ConfigurationError",
|
|
203
|
+
"ReversionError",
|
|
204
|
+
"ResonanceError",
|
|
205
|
+
|
|
206
|
+
# CLI
|
|
207
|
+
"cli",
|
|
208
|
+
|
|
209
|
+
# Middleware
|
|
210
|
+
"OBPMiddleware",
|
|
211
|
+
"create_fastapi_middleware",
|
|
212
|
+
|
|
213
|
+
# Components
|
|
214
|
+
"LeakGuard",
|
|
215
|
+
"render_timeline",
|
|
216
|
+
"get_timeline_stats",
|
|
217
|
+
"LogSanitizer",
|
|
218
|
+
"enable_log_sanitization",
|
|
219
|
+
"disable_log_sanitization",
|
|
220
|
+
"sanitize_output",
|
|
221
|
+
"redact_secrets",
|
|
222
|
+
|
|
223
|
+
# TPM Integration
|
|
224
|
+
"TPMManager",
|
|
225
|
+
"TPMConfig",
|
|
226
|
+
"TPMAvailability",
|
|
227
|
+
"get_tpm_manager",
|
|
228
|
+
|
|
229
|
+
# Active Honeypots
|
|
230
|
+
"HoneypotManager",
|
|
231
|
+
"HoneypotConfig",
|
|
232
|
+
"HoneypotType",
|
|
233
|
+
"HoneypotAlertLevel",
|
|
234
|
+
"DecoyValue",
|
|
235
|
+
"get_honeypot_manager",
|
|
236
|
+
|
|
237
|
+
# Secure Audit Logging
|
|
238
|
+
"SecureAuditLogger",
|
|
239
|
+
"SecureAuditConfig",
|
|
240
|
+
"SecureLogEntry",
|
|
241
|
+
"LogLevel",
|
|
242
|
+
"TamperEvidence",
|
|
243
|
+
"get_audit_logger",
|
|
244
|
+
|
|
245
|
+
# Session Security
|
|
246
|
+
"SessionHijackingProtection",
|
|
247
|
+
"SessionConfig",
|
|
248
|
+
"SessionFingerprint",
|
|
249
|
+
"Session",
|
|
250
|
+
"SessionStatus",
|
|
251
|
+
"get_session_protection",
|
|
252
|
+
|
|
253
|
+
# Secrets Manager Integration
|
|
254
|
+
"SecretsManager",
|
|
255
|
+
"SecretConfig",
|
|
256
|
+
"SecretManagerType",
|
|
257
|
+
"get_secrets_manager",
|
|
258
|
+
|
|
259
|
+
# Rate Limiting
|
|
260
|
+
"RateLimiter",
|
|
261
|
+
"RateLimitConfig",
|
|
262
|
+
"TokenBucket",
|
|
263
|
+
"SlidingWindowLog",
|
|
264
|
+
"get_rate_limiter",
|
|
265
|
+
|
|
266
|
+
# Trap Engine - Attribution & Deception
|
|
267
|
+
"TrapEngine",
|
|
268
|
+
"TrapLevel",
|
|
269
|
+
"AlertChannel",
|
|
270
|
+
"AttackerIntel",
|
|
271
|
+
"ForensicEvidence",
|
|
272
|
+
"RealTimeReporter",
|
|
273
|
+
"ForensicLogger",
|
|
274
|
+
"trap_engine",
|
|
275
|
+
"trap",
|
|
276
|
+
"trap_access",
|
|
277
|
+
"configure_trap_engine",
|
|
278
|
+
|
|
279
|
+
# TLS Context Verification (NEW - v3.0)
|
|
280
|
+
"TLSContextVerifier",
|
|
281
|
+
"TLSContextInfo",
|
|
282
|
+
"TLSVerificationStatus",
|
|
283
|
+
"get_tls_verifier",
|
|
284
|
+
"verify_tls_context",
|
|
285
|
+
|
|
286
|
+
# Input Sanitization (NEW - v3.0)
|
|
287
|
+
"InputSanitizer",
|
|
288
|
+
"InjectionType",
|
|
289
|
+
"SanitizationResult",
|
|
290
|
+
"sanitize_input",
|
|
291
|
+
"get_input_sanitizer",
|
|
292
|
+
]
|
obp/_rust_bridge.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Rust Bridge for OBP - Uses Rust core when available for performance.
|
|
2
|
+
|
|
3
|
+
This module provides a drop-in replacement for Python implementations
|
|
4
|
+
using the Rust core via PyO3 bindings.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
# Try to import Rust bindings
|
|
12
|
+
_RUST_AVAILABLE = False
|
|
13
|
+
_obp_core = None
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import obp_core
|
|
17
|
+
_RUST_AVAILABLE = True
|
|
18
|
+
logger.info("Rust core available - using high-performance implementation")
|
|
19
|
+
except ImportError:
|
|
20
|
+
logger.info("Rust core not available - using Python implementation")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RustCore:
|
|
24
|
+
"""Wrapper around Rust core for consistent API."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, entropy_threshold: float = 4.5):
|
|
27
|
+
if not _RUST_AVAILABLE:
|
|
28
|
+
raise ImportError("Rust core not available. Install with: pip install obp-core")
|
|
29
|
+
|
|
30
|
+
config = {"entropy_threshold": entropy_threshold}
|
|
31
|
+
self._engine = obp_core.PyOBPEngine(config)
|
|
32
|
+
|
|
33
|
+
def detect_leak(self, input_str: str) -> dict:
|
|
34
|
+
"""Detect secrets in input string."""
|
|
35
|
+
result = self._engine.detect_leak(input_str)
|
|
36
|
+
return {
|
|
37
|
+
"detected": result["detected"],
|
|
38
|
+
"pattern_matched": result.get("pattern_matched"),
|
|
39
|
+
"entropy": result.get("entropy", 0.0)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def sign(self, key: str, data: str) -> str:
|
|
43
|
+
"""Sign data with HMAC-SHA256."""
|
|
44
|
+
return self._engine.sign(key, data)
|
|
45
|
+
|
|
46
|
+
def verify(self, key: str, data: str, signature: str) -> bool:
|
|
47
|
+
"""Verify HMAC signature."""
|
|
48
|
+
return self._engine.verify(key, data, signature)
|
|
49
|
+
|
|
50
|
+
def steam_burn(self, intensity: float) -> int:
|
|
51
|
+
"""CPU-intensive work (fast in Rust)."""
|
|
52
|
+
return self._engine.steam_burn(intensity)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def calculate_entropy_rust(data: str) -> float:
|
|
56
|
+
"""Calculate entropy using Rust core."""
|
|
57
|
+
if not _RUST_AVAILABLE:
|
|
58
|
+
raise ImportError("Rust core not available")
|
|
59
|
+
|
|
60
|
+
return obp_core.calculate_entropy_fast(data)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def steam_burn_rust(intensity: float) -> int:
|
|
64
|
+
"""Steam burn using Rust core (much faster)."""
|
|
65
|
+
if not _RUST_AVAILABLE:
|
|
66
|
+
raise ImportError("Rust core not available")
|
|
67
|
+
|
|
68
|
+
return obp_core.steam_burn_fast(intensity)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def is_rust_available() -> bool:
|
|
72
|
+
"""Check if Rust core is available."""
|
|
73
|
+
return _RUST_AVAILABLE
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_rust_core(entropy_threshold: float = 4.5) -> RustCore | None:
|
|
77
|
+
"""Get Rust core instance if available."""
|
|
78
|
+
if not _RUST_AVAILABLE:
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
return RustCore(entropy_threshold)
|
obp/cli.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""OBP CLI - Command-line interface for Ocean Basket Protocol."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.table import Table
|
|
10
|
+
|
|
11
|
+
from . import obp
|
|
12
|
+
from .config import LeakGuardConfig, OBPConfig, ProtectionMode
|
|
13
|
+
from .core import AntiPatchProtection, MemoryProtection
|
|
14
|
+
from .leakguard import LeakGuard
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def cmd_status(args: argparse.Namespace) -> int:
|
|
20
|
+
"""Check OBP status."""
|
|
21
|
+
console.print("\n[bold cyan]🌊 Ocean Basket Protocol Status[/bold cyan]\n")
|
|
22
|
+
|
|
23
|
+
# OBP instance status
|
|
24
|
+
console.print("[green]✓[/green] OBP Instance: Active")
|
|
25
|
+
console.print(f" Config Mode: {obp._config.mode}")
|
|
26
|
+
console.print(f" LeakGuard: {'Enabled' if obp._config.enable_leakguard else 'Disabled'}")
|
|
27
|
+
console.print(f" Anti-Patch: {'Enabled' if obp._config.enable_anti_patch else 'Disabled'}")
|
|
28
|
+
console.print(f" Memory Warning: {'Enabled' if obp._config.enable_memory_warning else 'Disabled'}")
|
|
29
|
+
|
|
30
|
+
# Context fingerprint
|
|
31
|
+
console.print("\n[cyan]Context Fingerprint:[/cyan]")
|
|
32
|
+
console.print(f" {obp.context_fingerprint[:32]}...")
|
|
33
|
+
|
|
34
|
+
# Audit log count
|
|
35
|
+
console.print("\n[cyan]Audit Log:[/cyan]")
|
|
36
|
+
console.print(f" Events logged: {len(obp.audit_log)}")
|
|
37
|
+
|
|
38
|
+
return 0
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def cmd_integrity(args: argparse.Namespace) -> int:
|
|
42
|
+
"""Check OBP integrity."""
|
|
43
|
+
console.print("\n[bold cyan]🔒 OBP Integrity Check[/bold cyan]\n")
|
|
44
|
+
|
|
45
|
+
violations = AntiPatchProtection.check_integrity()
|
|
46
|
+
|
|
47
|
+
if violations:
|
|
48
|
+
console.print("[red]✗ INTEGRITY COMPROMISED[/red]")
|
|
49
|
+
for v in violations:
|
|
50
|
+
console.print(f" - {v}")
|
|
51
|
+
return 1
|
|
52
|
+
else:
|
|
53
|
+
console.print("[green]✓ OBP Integrity Verified[/green]")
|
|
54
|
+
return 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def cmd_memory(args: argparse.Namespace) -> int:
|
|
58
|
+
"""Check memory protection warnings."""
|
|
59
|
+
console.print("\n[bold cyan]💾 Memory Protection Check[/bold cyan]\n")
|
|
60
|
+
|
|
61
|
+
warnings = MemoryProtection.check_environment()
|
|
62
|
+
|
|
63
|
+
if warnings:
|
|
64
|
+
console.print("[yellow]⚠ Security Warnings:[/yellow]")
|
|
65
|
+
for w in warnings:
|
|
66
|
+
console.print(f" - {w}")
|
|
67
|
+
else:
|
|
68
|
+
console.print("[green]✓ No memory security issues detected[/green]")
|
|
69
|
+
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def cmd_audit(args: argparse.Namespace) -> int:
|
|
74
|
+
"""Display audit log."""
|
|
75
|
+
console.print("\n[bold cyan]📋 OBP Audit Log[/bold cyan]\n")
|
|
76
|
+
|
|
77
|
+
if not obp.audit_log:
|
|
78
|
+
console.print("[dim]No audit events logged.[/dim]")
|
|
79
|
+
return 0
|
|
80
|
+
|
|
81
|
+
table = Table(show_header=True)
|
|
82
|
+
table.add_column("Time", style="cyan")
|
|
83
|
+
table.add_column("Event", style="white")
|
|
84
|
+
table.add_column("Details", style="dim")
|
|
85
|
+
|
|
86
|
+
for event in obp.audit_log[-20:]: # Show last 20
|
|
87
|
+
timestamp = event.get("timestamp", "N/A")
|
|
88
|
+
event_type = event.get("event", "unknown")
|
|
89
|
+
details = event.get("details", "")
|
|
90
|
+
table.add_row(
|
|
91
|
+
timestamp[:19] if timestamp else "N/A",
|
|
92
|
+
event_type,
|
|
93
|
+
str(details)[:50]
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
console.print(table)
|
|
97
|
+
return 0
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def cmd_scan(args: argparse.Namespace) -> int:
|
|
101
|
+
"""Scan text for secrets."""
|
|
102
|
+
console.print("\n[bold cyan]🔍 Secret Scanner[/bold cyan]\n")
|
|
103
|
+
|
|
104
|
+
text = args.text
|
|
105
|
+
if args.file:
|
|
106
|
+
try:
|
|
107
|
+
with open(args.file) as f:
|
|
108
|
+
text = f.read()
|
|
109
|
+
except Exception as e:
|
|
110
|
+
console.print(f"[red]Error reading file: {e}[/red]")
|
|
111
|
+
return 1
|
|
112
|
+
|
|
113
|
+
if not text:
|
|
114
|
+
console.print("[yellow]No text to scan.[/yellow]")
|
|
115
|
+
return 1
|
|
116
|
+
|
|
117
|
+
config = LeakGuardConfig(enabled=True)
|
|
118
|
+
scanner = LeakGuard(config)
|
|
119
|
+
|
|
120
|
+
detected = scanner.scan(text)
|
|
121
|
+
|
|
122
|
+
if detected:
|
|
123
|
+
console.print(f"[red]✗ Secrets detected ({len(detected)}):[/red]")
|
|
124
|
+
for d in detected[:10]: # Show first 10
|
|
125
|
+
console.print(f" - {d[0]}: {d[1][:30]}...")
|
|
126
|
+
else:
|
|
127
|
+
console.print("[green]✓ No secrets detected[/green]")
|
|
128
|
+
|
|
129
|
+
return 0 if not detected else 1
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def cmd_protect(args: argparse.Namespace) -> int:
|
|
133
|
+
"""Test protection decorator."""
|
|
134
|
+
console.print("\n[bold cyan]🛡️ Testing Protection[/bold cyan]\n")
|
|
135
|
+
|
|
136
|
+
mode_map = {
|
|
137
|
+
"graceful": ProtectionMode.GRACEFUL,
|
|
138
|
+
"defensive": ProtectionMode.DEFENSIVE,
|
|
139
|
+
"paranoid": ProtectionMode.PARANOID,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
mode = mode_map.get(args.mode, ProtectionMode.DEFENSIVE)
|
|
143
|
+
config = OBPConfig(mode=mode, enable_leakguard=True)
|
|
144
|
+
|
|
145
|
+
@obp.protect(config)
|
|
146
|
+
def test_function(api_key: str, data: str) -> dict:
|
|
147
|
+
return {"status": "ok", "key": api_key}
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
result = test_function("sk_live_test123", "hello")
|
|
151
|
+
console.print("[green]✓ Protection working[/green]")
|
|
152
|
+
console.print(f" Result: {result}")
|
|
153
|
+
except Exception as e:
|
|
154
|
+
console.print(f"[red]✗ Error: {e}[/red]")
|
|
155
|
+
return 1
|
|
156
|
+
|
|
157
|
+
return 0
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def main(argv: list[str] | None = None) -> int:
|
|
161
|
+
"""Main CLI entry point."""
|
|
162
|
+
parser = argparse.ArgumentParser(
|
|
163
|
+
description="🌊 Ocean Basket Protocol CLI",
|
|
164
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
subparsers = parser.add_subparsers(dest="command", help="Commands")
|
|
168
|
+
|
|
169
|
+
# status
|
|
170
|
+
subparsers.add_parser("status", help="Check OBP status")
|
|
171
|
+
|
|
172
|
+
# integrity
|
|
173
|
+
subparsers.add_parser("integrity", help="Check OBP integrity")
|
|
174
|
+
|
|
175
|
+
# memory
|
|
176
|
+
subparsers.add_parser("memory", help="Check memory protection")
|
|
177
|
+
|
|
178
|
+
# audit
|
|
179
|
+
subparsers.add_parser("audit", help="Show audit log")
|
|
180
|
+
|
|
181
|
+
# scan
|
|
182
|
+
scan_parser = subparsers.add_parser("scan", help="Scan text for secrets")
|
|
183
|
+
scan_parser.add_argument("text", nargs="?", help="Text to scan")
|
|
184
|
+
scan_parser.add_argument("-f", "--file", help="File to scan")
|
|
185
|
+
|
|
186
|
+
# protect
|
|
187
|
+
protect_parser = subparsers.add_parser("protect", help="Test protection")
|
|
188
|
+
protect_parser.add_argument(
|
|
189
|
+
"-m", "--mode",
|
|
190
|
+
choices=["graceful", "defensive", "paranoid"],
|
|
191
|
+
default="defensive",
|
|
192
|
+
help="Protection mode"
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
args = parser.parse_args(argv)
|
|
196
|
+
|
|
197
|
+
commands = {
|
|
198
|
+
"status": cmd_status,
|
|
199
|
+
"integrity": cmd_integrity,
|
|
200
|
+
"memory": cmd_memory,
|
|
201
|
+
"audit": cmd_audit,
|
|
202
|
+
"scan": cmd_scan,
|
|
203
|
+
"protect": cmd_protect,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if args.command in commands:
|
|
207
|
+
return commands[args.command](args)
|
|
208
|
+
|
|
209
|
+
parser.print_help()
|
|
210
|
+
return 0
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
if __name__ == "__main__":
|
|
214
|
+
sys.exit(main())
|