ai_root_shield 0.5.0 → 1.0.0

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.
@@ -0,0 +1,438 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AI Root Shield Python Bindings
4
+ Enterprise-grade mobile security analysis library
5
+ """
6
+
7
+ import json
8
+ import subprocess
9
+ import tempfile
10
+ import os
11
+ from typing import Dict, List, Optional, Union
12
+ from dataclasses import dataclass
13
+ from enum import Enum
14
+
15
+ class SecurityLevel(Enum):
16
+ LOW = "low"
17
+ MEDIUM = "medium"
18
+ HIGH = "high"
19
+ CRITICAL = "critical"
20
+
21
+ class Platform(Enum):
22
+ ANDROID = "android"
23
+ IOS = "ios"
24
+ CROSS_PLATFORM = "cross_platform"
25
+
26
+ @dataclass
27
+ class AnalysisResult:
28
+ risk_score: int
29
+ factors: List[str]
30
+ timestamp: str
31
+ version: str
32
+ platform: Optional[str] = None
33
+ compliance: Optional[Dict] = None
34
+ recommendations: Optional[List[str]] = None
35
+
36
+ @dataclass
37
+ class PolicyConfig:
38
+ industry_type: str
39
+ compliance_frameworks: List[str]
40
+ risk_thresholds: Dict[str, int]
41
+ requirements: Dict[str, Dict]
42
+
43
+ class AIRootShield:
44
+ """Main AI Root Shield Python interface"""
45
+
46
+ def __init__(self, config: Optional[Dict] = None):
47
+ self.config = config or {}
48
+ self.gem_available = self._check_gem_availability()
49
+ if not self.gem_available:
50
+ raise RuntimeError("AI Root Shield Ruby gem not found. Please install: gem install ai_root_shield")
51
+
52
+ def _check_gem_availability(self) -> bool:
53
+ """Check if AI Root Shield gem is available"""
54
+ try:
55
+ result = subprocess.run(['gem', 'list', 'ai_root_shield'],
56
+ capture_output=True, text=True, timeout=10)
57
+ return 'ai_root_shield' in result.stdout
58
+ except (subprocess.TimeoutExpired, FileNotFoundError):
59
+ return False
60
+
61
+ def analyze_device(self, device_logs: Union[str, Dict],
62
+ platform: Optional[Platform] = None,
63
+ config: Optional[Dict] = None) -> AnalysisResult:
64
+ """Analyze device security using AI Root Shield"""
65
+
66
+ # Prepare device logs
67
+ if isinstance(device_logs, dict):
68
+ logs_file = self._write_temp_json(device_logs)
69
+ else:
70
+ logs_file = device_logs
71
+
72
+ try:
73
+ # Build command
74
+ cmd = ['ai_root_shield']
75
+
76
+ if platform:
77
+ cmd.extend(['--platform', platform.value])
78
+
79
+ if config:
80
+ if config.get('verbose'):
81
+ cmd.append('--verbose')
82
+ if config.get('format'):
83
+ cmd.extend(['--format', config['format']])
84
+ if config.get('unified_report'):
85
+ cmd.append('--unified-report')
86
+
87
+ cmd.append(logs_file)
88
+
89
+ # Execute analysis
90
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
91
+
92
+ if result.returncode != 0:
93
+ raise RuntimeError(f"Analysis failed: {result.stderr}")
94
+
95
+ # Parse result
96
+ analysis_data = json.loads(result.stdout)
97
+ return self._parse_analysis_result(analysis_data)
98
+
99
+ finally:
100
+ # Clean up temp file if created
101
+ if isinstance(device_logs, dict) and os.path.exists(logs_file):
102
+ os.unlink(logs_file)
103
+
104
+ def analyze_android_device(self, device_logs: Union[str, Dict],
105
+ safetynet_api_key: Optional[str] = None,
106
+ package_name: Optional[str] = None) -> AnalysisResult:
107
+ """Analyze Android device with SafetyNet integration"""
108
+ config = {}
109
+ if safetynet_api_key:
110
+ config['safetynet_api_key'] = safetynet_api_key
111
+ if package_name:
112
+ config['package_name'] = package_name
113
+
114
+ return self.analyze_device(device_logs, Platform.ANDROID, config)
115
+
116
+ def analyze_ios_device(self, device_logs: Union[str, Dict]) -> AnalysisResult:
117
+ """Analyze iOS device with jailbreak detection"""
118
+ return self.analyze_device(device_logs, Platform.IOS)
119
+
120
+ def run_ci_cd_analysis(self, device_logs: Union[str, Dict],
121
+ artifacts_path: str = './security_test_artifacts') -> Dict:
122
+ """Run CI/CD security analysis"""
123
+
124
+ if isinstance(device_logs, dict):
125
+ logs_file = self._write_temp_json(device_logs)
126
+ else:
127
+ logs_file = device_logs
128
+
129
+ try:
130
+ cmd = ['ai_root_shield', '--ci-mode', '--artifacts-path', artifacts_path, logs_file]
131
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
132
+
133
+ if result.returncode != 0:
134
+ raise RuntimeError(f"CI/CD analysis failed: {result.stderr}")
135
+
136
+ return json.loads(result.stdout)
137
+
138
+ finally:
139
+ if isinstance(device_logs, dict) and os.path.exists(logs_file):
140
+ os.unlink(logs_file)
141
+
142
+ def generate_unified_report(self, android_results: Optional[Dict] = None,
143
+ ios_results: Optional[Dict] = None) -> Dict:
144
+ """Generate unified cross-platform report"""
145
+ # This would require more complex integration with Ruby gem
146
+ # For now, use the CLI unified report feature
147
+ if android_results:
148
+ logs_file = self._write_temp_json(android_results)
149
+ try:
150
+ cmd = ['ai_root_shield', '--platform', 'android', '--unified-report', logs_file]
151
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
152
+
153
+ if result.returncode == 0:
154
+ return json.loads(result.stdout)
155
+ finally:
156
+ os.unlink(logs_file)
157
+
158
+ return {}
159
+
160
+ def start_dashboard(self, port: int = 4567) -> bool:
161
+ """Start web dashboard server"""
162
+ try:
163
+ cmd = ['ai_root_shield', '--start-dashboard', '--dashboard-port', str(port)]
164
+ subprocess.Popen(cmd)
165
+ return True
166
+ except Exception:
167
+ return False
168
+
169
+ def generate_ci_config(self, platform: str, output_path: Optional[str] = None) -> str:
170
+ """Generate CI/CD configuration"""
171
+ try:
172
+ cmd = ['ai_root_shield', '--generate-ci-config', platform]
173
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
174
+
175
+ if result.returncode == 0:
176
+ return result.stdout
177
+ else:
178
+ raise RuntimeError(f"CI config generation failed: {result.stderr}")
179
+ except Exception as e:
180
+ raise RuntimeError(f"Failed to generate CI config: {str(e)}")
181
+
182
+ def _write_temp_json(self, data: Dict) -> str:
183
+ """Write data to temporary JSON file"""
184
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
185
+ json.dump(data, f, indent=2)
186
+ return f.name
187
+
188
+ def _parse_analysis_result(self, data: Dict) -> AnalysisResult:
189
+ """Parse analysis result from JSON"""
190
+ return AnalysisResult(
191
+ risk_score=data.get('risk_score', 0),
192
+ factors=data.get('factors', []),
193
+ timestamp=data.get('timestamp', ''),
194
+ version=data.get('version', ''),
195
+ platform=data.get('platform'),
196
+ compliance=data.get('compliance'),
197
+ recommendations=data.get('recommendations', [])
198
+ )
199
+
200
+ class EnterprisePolicy:
201
+ """Enterprise policy management"""
202
+
203
+ def __init__(self, industry_type: str):
204
+ self.industry_type = industry_type
205
+ self.policy_config = self._load_policy_config()
206
+
207
+ def _load_policy_config(self) -> PolicyConfig:
208
+ """Load policy configuration for industry"""
209
+ # This would integrate with the Ruby PolicyManager
210
+ # For now, return basic config
211
+ configs = {
212
+ 'fintech': PolicyConfig(
213
+ industry_type='fintech',
214
+ compliance_frameworks=['pci_dss', 'sox', 'ffiec'],
215
+ risk_thresholds={'critical': 0, 'high': 10, 'medium': 30, 'low': 50},
216
+ requirements={}
217
+ ),
218
+ 'healthcare': PolicyConfig(
219
+ industry_type='healthcare',
220
+ compliance_frameworks=['hipaa', 'hitech', 'gdpr'],
221
+ risk_thresholds={'critical': 0, 'high': 15, 'medium': 35, 'low': 60},
222
+ requirements={}
223
+ ),
224
+ 'government': PolicyConfig(
225
+ industry_type='government',
226
+ compliance_frameworks=['fisma', 'nist_800_53', 'fedramp'],
227
+ risk_thresholds={'critical': 0, 'high': 5, 'medium': 20, 'low': 40},
228
+ requirements={}
229
+ ),
230
+ 'corporate': PolicyConfig(
231
+ industry_type='corporate',
232
+ compliance_frameworks=['iso27001', 'gdpr', 'ccpa'],
233
+ risk_thresholds={'critical': 5, 'high': 25, 'medium': 50, 'low': 75},
234
+ requirements={}
235
+ )
236
+ }
237
+
238
+ return configs.get(self.industry_type, configs['corporate'])
239
+
240
+ def evaluate_compliance(self, analysis_result: AnalysisResult) -> Dict:
241
+ """Evaluate compliance against policy"""
242
+ violations = []
243
+
244
+ # Basic compliance evaluation
245
+ if analysis_result.risk_score > self.policy_config.risk_thresholds['critical']:
246
+ violations.append({
247
+ 'severity': 'critical',
248
+ 'message': f'Risk score {analysis_result.risk_score} exceeds critical threshold'
249
+ })
250
+
251
+ return {
252
+ 'compliant': len(violations) == 0,
253
+ 'violations': violations,
254
+ 'policy_version': '1.0',
255
+ 'industry_type': self.industry_type,
256
+ 'compliance_score': max(0, 100 - len(violations) * 25)
257
+ }
258
+
259
+ class AlertManager:
260
+ """Alert and notification management"""
261
+
262
+ def __init__(self, config: Optional[Dict] = None):
263
+ self.config = config or {}
264
+ self.channels = []
265
+
266
+ def add_webhook_channel(self, url: str, headers: Optional[Dict] = None):
267
+ """Add webhook notification channel"""
268
+ self.channels.append({
269
+ 'type': 'webhook',
270
+ 'url': url,
271
+ 'headers': headers or {}
272
+ })
273
+
274
+ def add_slack_channel(self, webhook_url: str):
275
+ """Add Slack notification channel"""
276
+ self.channels.append({
277
+ 'type': 'slack',
278
+ 'webhook_url': webhook_url
279
+ })
280
+
281
+ def send_security_alert(self, analysis_result: AnalysisResult, severity: str = 'warning'):
282
+ """Send security alert"""
283
+ alert_data = {
284
+ 'type': 'security_incident',
285
+ 'severity': severity,
286
+ 'title': 'Security Threat Detected',
287
+ 'message': f'Risk score: {analysis_result.risk_score}/100',
288
+ 'data': {
289
+ 'risk_score': analysis_result.risk_score,
290
+ 'factors': analysis_result.factors,
291
+ 'timestamp': analysis_result.timestamp
292
+ }
293
+ }
294
+
295
+ return self._send_alert(alert_data)
296
+
297
+ def send_compliance_alert(self, compliance_result: Dict, policy_type: str):
298
+ """Send compliance alert"""
299
+ severity = 'info' if compliance_result['compliant'] else 'critical'
300
+
301
+ alert_data = {
302
+ 'type': 'compliance_violation',
303
+ 'severity': severity,
304
+ 'title': 'Compliance Status Update',
305
+ 'message': f"Policy: {policy_type}, Status: {'COMPLIANT' if compliance_result['compliant'] else 'NON-COMPLIANT'}",
306
+ 'data': compliance_result
307
+ }
308
+
309
+ return self._send_alert(alert_data)
310
+
311
+ def _send_alert(self, alert_data: Dict) -> Dict:
312
+ """Send alert through configured channels"""
313
+ results = {}
314
+
315
+ for channel in self.channels:
316
+ try:
317
+ if channel['type'] == 'webhook':
318
+ result = self._send_webhook(channel, alert_data)
319
+ elif channel['type'] == 'slack':
320
+ result = self._send_slack(channel, alert_data)
321
+ else:
322
+ result = {'success': False, 'error': 'Unknown channel type'}
323
+
324
+ results[f"{channel['type']}_{len(results)}"] = result
325
+
326
+ except Exception as e:
327
+ results[f"{channel['type']}_{len(results)}"] = {
328
+ 'success': False,
329
+ 'error': str(e)
330
+ }
331
+
332
+ return results
333
+
334
+ def _send_webhook(self, channel: Dict, alert_data: Dict) -> Dict:
335
+ """Send webhook notification"""
336
+ import requests
337
+
338
+ try:
339
+ response = requests.post(
340
+ channel['url'],
341
+ json=alert_data,
342
+ headers=channel.get('headers', {}),
343
+ timeout=30
344
+ )
345
+
346
+ return {
347
+ 'success': response.status_code < 400,
348
+ 'status_code': response.status_code,
349
+ 'response': response.text[:200] # Truncate response
350
+ }
351
+ except Exception as e:
352
+ return {'success': False, 'error': str(e)}
353
+
354
+ def _send_slack(self, channel: Dict, alert_data: Dict) -> Dict:
355
+ """Send Slack notification"""
356
+ import requests
357
+
358
+ # Format for Slack
359
+ color = {
360
+ 'info': 'good',
361
+ 'warning': 'warning',
362
+ 'critical': 'danger',
363
+ 'emergency': 'danger'
364
+ }.get(alert_data['severity'], 'good')
365
+
366
+ payload = {
367
+ 'text': alert_data['title'],
368
+ 'attachments': [{
369
+ 'color': color,
370
+ 'fields': [
371
+ {'title': 'Severity', 'value': alert_data['severity'].upper(), 'short': True},
372
+ {'title': 'Type', 'value': alert_data['type'], 'short': True},
373
+ {'title': 'Message', 'value': alert_data['message'], 'short': False}
374
+ ]
375
+ }]
376
+ }
377
+
378
+ try:
379
+ response = requests.post(channel['webhook_url'], json=payload, timeout=30)
380
+ return {
381
+ 'success': response.status_code == 200,
382
+ 'status_code': response.status_code
383
+ }
384
+ except Exception as e:
385
+ return {'success': False, 'error': str(e)}
386
+
387
+ # Example usage and testing functions
388
+ def example_usage():
389
+ """Example usage of AI Root Shield Python bindings"""
390
+
391
+ # Initialize AI Root Shield
392
+ ars = AIRootShield()
393
+
394
+ # Example device logs
395
+ android_logs = {
396
+ "device_info": {
397
+ "platform": "Android",
398
+ "version": "11",
399
+ "model": "Pixel 5"
400
+ },
401
+ "security_checks": {
402
+ "root_detected": False,
403
+ "emulator_detected": False,
404
+ "debugging_enabled": False
405
+ },
406
+ "safetynet": {
407
+ "basicIntegrity": True,
408
+ "ctsProfileMatch": True
409
+ }
410
+ }
411
+
412
+ try:
413
+ # Analyze Android device
414
+ result = ars.analyze_android_device(android_logs)
415
+ print(f"Risk Score: {result.risk_score}/100")
416
+ print(f"Factors: {result.factors}")
417
+
418
+ # Enterprise policy evaluation
419
+ policy = EnterprisePolicy('fintech')
420
+ compliance = policy.evaluate_compliance(result)
421
+ print(f"Compliant: {compliance['compliant']}")
422
+
423
+ # Alert management
424
+ alert_manager = AlertManager()
425
+ alert_manager.add_webhook_channel('https://example.com/webhook')
426
+
427
+ if result.risk_score > 50:
428
+ alert_results = alert_manager.send_security_alert(result, 'warning')
429
+ print(f"Alert sent: {alert_results}")
430
+
431
+ return True
432
+
433
+ except Exception as e:
434
+ print(f"Error: {e}")
435
+ return False
436
+
437
+ if __name__ == "__main__":
438
+ example_usage()
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Setup script for AI Root Shield Python bindings
4
+ """
5
+
6
+ from setuptools import setup, find_packages
7
+ import os
8
+
9
+ # Read README for long description
10
+ def read_readme():
11
+ readme_path = os.path.join(os.path.dirname(__file__), 'README.md')
12
+ if os.path.exists(readme_path):
13
+ with open(readme_path, 'r', encoding='utf-8') as f:
14
+ return f.read()
15
+ return "AI Root Shield Python bindings for enterprise mobile security analysis"
16
+
17
+ setup(
18
+ name="ai-root-shield",
19
+ version="1.0.0",
20
+ author="AI Root Shield Team",
21
+ author_email="support@airootshield.com",
22
+ description="Enterprise-grade mobile security analysis library - Python bindings",
23
+ long_description=read_readme(),
24
+ long_description_content_type="text/markdown",
25
+ url="https://github.com/ahmetxhero/ai-root-shield",
26
+ py_modules=["ai_root_shield"],
27
+ classifiers=[
28
+ "Development Status :: 5 - Production/Stable",
29
+ "Intended Audience :: Developers",
30
+ "Intended Audience :: Information Technology",
31
+ "License :: OSI Approved :: MIT License",
32
+ "Operating System :: OS Independent",
33
+ "Programming Language :: Python :: 3",
34
+ "Programming Language :: Python :: 3.7",
35
+ "Programming Language :: Python :: 3.8",
36
+ "Programming Language :: Python :: 3.9",
37
+ "Programming Language :: Python :: 3.10",
38
+ "Programming Language :: Python :: 3.11",
39
+ "Topic :: Security",
40
+ "Topic :: Software Development :: Libraries :: Python Modules",
41
+ ],
42
+ python_requires=">=3.7",
43
+ install_requires=[
44
+ "requests>=2.25.0",
45
+ ],
46
+ extras_require={
47
+ "dev": [
48
+ "pytest>=6.0",
49
+ "pytest-cov>=2.0",
50
+ "black>=21.0",
51
+ "flake8>=3.8",
52
+ ],
53
+ },
54
+ entry_points={
55
+ "console_scripts": [
56
+ "ai-root-shield=ai_root_shield:main",
57
+ ],
58
+ },
59
+ keywords="security mobile android ios enterprise compliance fintech healthcare",
60
+ project_urls={
61
+ "Bug Reports": "https://github.com/ahmetxhero/ai-root-shield/issues",
62
+ "Source": "https://github.com/ahmetxhero/ai-root-shield",
63
+ "Documentation": "https://github.com/ahmetxhero/ai-root-shield/blob/main/README.md",
64
+ },
65
+ )
@@ -0,0 +1,148 @@
1
+ {
2
+ "platform": "android",
3
+ "timestamp": 1640995200,
4
+ "device_info": {
5
+ "model": "Pixel 6",
6
+ "manufacturer": "Google",
7
+ "os_version": "13",
8
+ "api_level": 33,
9
+ "build_fingerprint": "google/raven/raven:13/TQ3A.230805.001/10316531:user/release-keys"
10
+ },
11
+ "safetynet": {
12
+ "basicIntegrity": true,
13
+ "ctsProfileMatch": true,
14
+ "evaluationType": "BASIC",
15
+ "nonce": "R2Rra24fVm5xa2Mg",
16
+ "timestampMs": 1640995200000,
17
+ "advice": ["LOCK_SCREEN_SECURED"]
18
+ },
19
+ "play_integrity": {
20
+ "deviceIntegrity": {
21
+ "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY", "MEETS_BASIC_INTEGRITY"]
22
+ },
23
+ "appIntegrity": {
24
+ "verdict": "PLAY_RECOGNIZED",
25
+ "appLicensingVerdict": "LICENSED"
26
+ },
27
+ "accountDetails": {
28
+ "verdict": "LICENSED"
29
+ },
30
+ "environmentDetails": {
31
+ "verdict": "MEETS_BASIC_INTEGRITY"
32
+ }
33
+ },
34
+ "hardware_security": {
35
+ "tee": {
36
+ "available": true,
37
+ "implementation": "trustzone",
38
+ "version": "1.1",
39
+ "secureStorage": true,
40
+ "keyAttestation": true,
41
+ "biometricSupport": true,
42
+ "strongboxAvailable": true,
43
+ "secureBootVerified": true,
44
+ "attestationKeys": ["rsa2048", "ec256"]
45
+ },
46
+ "secure_element": {
47
+ "available": true,
48
+ "type": "embedded_se",
49
+ "appletsInstalled": ["payment", "identity"],
50
+ "nfcSecureElement": true,
51
+ "embeddedSecureElement": true,
52
+ "tamperResistance": true,
53
+ "certificationLevel": "cc_eal5_plus"
54
+ },
55
+ "biometrics": {
56
+ "fingerprintAvailable": true,
57
+ "faceAvailable": false,
58
+ "fingerprintEnrolled": true,
59
+ "hardwareLevel": "strong",
60
+ "template_security": {
61
+ "hardwareProtected": true,
62
+ "encryptedStorage": true,
63
+ "templateIsolation": true,
64
+ "secureMatching": true
65
+ },
66
+ "liveness_detection": {
67
+ "activeLiveness": true,
68
+ "passiveLiveness": true,
69
+ "depthSensing": false
70
+ },
71
+ "consistency": {
72
+ "enrollmentChangesDetected": false,
73
+ "templateModifications": false
74
+ }
75
+ },
76
+ "crypto": {
77
+ "hardwareRng": true,
78
+ "aesHardwareAcceleration": true,
79
+ "eccSupport": true,
80
+ "rsaSupport": true,
81
+ "keyDerivationHardware": true,
82
+ "secureKeyStorage": true,
83
+ "cryptoCoprocessor": true,
84
+ "supportedAlgorithms": ["AES-256", "RSA-2048", "ECDSA-P256", "SHA-256"]
85
+ },
86
+ "attestation": {
87
+ "keyAttestationSupported": true,
88
+ "attestationSecurityLevel": "trusted_environment",
89
+ "deviceIdAttestation": true,
90
+ "verifiedBootKey": "308201a2300d06092a864886f70d01010105000382018f003082018a0282018100...",
91
+ "rootOfTrust": {
92
+ "verifiedBootKey": "308201a2300d06092a864886f70d01010105000382018f003082018a0282018100...",
93
+ "deviceLocked": true,
94
+ "verifiedBootState": "verified",
95
+ "verifiedBootHash": "4f4adce36cf2e9c51349d1e77b067b2b8b5c5b5c5b5c5b5c5b5c5b5c5b5c5b5c"
96
+ }
97
+ }
98
+ },
99
+ "system_integrity": {
100
+ "selinuxEnforcing": true,
101
+ "verifiedBootState": "green",
102
+ "bootloaderLocked": true,
103
+ "systemPartitionVerified": true,
104
+ "vendorPartitionVerified": true,
105
+ "buildTags": "release-keys",
106
+ "adbEnabled": false,
107
+ "developerOptionsEnabled": false,
108
+ "dmVerityEnabled": true
109
+ },
110
+ "file_system": {
111
+ "files": [
112
+ {
113
+ "path": "/system/bin/sh",
114
+ "permissions": "755",
115
+ "owner": "root",
116
+ "exists": true
117
+ },
118
+ {
119
+ "path": "/system/xbin/su",
120
+ "exists": false
121
+ },
122
+ {
123
+ "path": "/system/bin/su",
124
+ "exists": false
125
+ }
126
+ ]
127
+ },
128
+ "running_processes": [
129
+ {
130
+ "name": "system_server",
131
+ "pid": 1234,
132
+ "uid": 1000
133
+ },
134
+ {
135
+ "name": "zygote64",
136
+ "pid": 567,
137
+ "uid": 0
138
+ }
139
+ ],
140
+ "network": {
141
+ "proxy_enabled": false,
142
+ "vpn_active": false,
143
+ "custom_certificates": [],
144
+ "tls_version": "1.3"
145
+ },
146
+ "risk_score": 15,
147
+ "factors": []
148
+ }