AYI-NEDJIMI commited on
Commit
ecbf601
·
verified ·
1 Parent(s): e08832d

Initial release: CyberSec-API gateway with REST endpoints for 3 cybersecurity models

Browse files
Files changed (3) hide show
  1. README.md +54 -7
  2. app.py +1051 -0
  3. requirements.txt +2 -0
README.md CHANGED
@@ -1,12 +1,59 @@
1
  ---
2
- title: CyberSec API
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: green
6
  sdk: gradio
7
- sdk_version: 6.6.0
8
  app_file: app.py
9
- pinned: false
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: CyberSec-API
3
+ emoji: "\U0001F6E1\uFE0F"
4
+ colorFrom: red
5
+ colorTo: gray
6
  sdk: gradio
7
+ sdk_version: 5.50.0
8
  app_file: app.py
9
+ pinned: true
10
+ license: apache-2.0
11
+ tags:
12
+ - api
13
+ - cybersecurity
14
+ - inference
15
+ - rest-api
16
+ - iso27001
17
+ - rgpd
18
+ - security
19
+ short_description: REST API gateway for CyberSec AI models
20
  ---
21
 
22
+ # CyberSec-API
23
+
24
+ REST API gateway providing unified access to three specialized cybersecurity AI models:
25
+
26
+ | Model | Specialty | Size |
27
+ |-------|-----------|------|
28
+ | **ISO27001-Expert** | ISO 27001 compliance and ISMS guidance | 1.5B |
29
+ | **RGPD-Expert** | GDPR/RGPD data protection regulation | 1.5B |
30
+ | **CyberSec-Assistant** | General cybersecurity operations | 3B |
31
+
32
+ ## API Endpoints
33
+
34
+ | Method | Endpoint | Description |
35
+ |--------|----------|-------------|
36
+ | `POST` | `/api/chat` | Send a message to a specific model |
37
+ | `POST` | `/api/compare` | Compare responses from all 3 models |
38
+ | `GET` | `/api/models` | List available models and their status |
39
+ | `GET` | `/api/health` | Health check endpoint |
40
+
41
+ ## Quick Start
42
+
43
+ ```python
44
+ from gradio_client import Client
45
+
46
+ client = Client("AYI-NEDJIMI/CyberSec-API")
47
+ result = client.predict(
48
+ message="What is ISO 27001?",
49
+ model_name="ISO27001-Expert",
50
+ api_name="/chat"
51
+ )
52
+ print(result)
53
+ ```
54
+
55
+ ## Links
56
+
57
+ - [ISO27001-Expert Model](https://huggingface.co/AYI-NEDJIMI/ISO27001-Expert-1.5B)
58
+ - [RGPD-Expert Model](https://huggingface.co/AYI-NEDJIMI/RGPD-Expert-1.5B)
59
+ - [CyberSec-Assistant Model](https://huggingface.co/AYI-NEDJIMI/CyberSec-Assistant-3B)
app.py ADDED
@@ -0,0 +1,1051 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ CyberSec-API: REST API Gateway for Cybersecurity AI Models
3
+ ===========================================================
4
+ Provides unified API access to three specialized cybersecurity models:
5
+ - ISO27001-Expert (1.5B) - ISO 27001 compliance guidance
6
+ - RGPD-Expert (1.5B) - GDPR/RGPD data protection
7
+ - CyberSec-Assistant (3B) - General cybersecurity operations
8
+ """
9
+
10
+ import os
11
+ import json
12
+ import time
13
+ import gradio as gr
14
+ from huggingface_hub import InferenceClient
15
+
16
+ # ---------------------------------------------------------------------------
17
+ # Configuration
18
+ # ---------------------------------------------------------------------------
19
+
20
+ MODELS = {
21
+ "ISO27001-Expert": {
22
+ "id": "AYI-NEDJIMI/ISO27001-Expert-1.5B",
23
+ "description": "Specialized in ISO 27001 standards, ISMS implementation, risk assessment, and compliance auditing.",
24
+ "parameters": "1.5B",
25
+ "specialty": "ISO 27001 Compliance",
26
+ },
27
+ "RGPD-Expert": {
28
+ "id": "AYI-NEDJIMI/RGPD-Expert-1.5B",
29
+ "description": "Specialized in GDPR/RGPD regulations, data protection, privacy impact assessments, and DPO guidance.",
30
+ "parameters": "1.5B",
31
+ "specialty": "GDPR/RGPD Data Protection",
32
+ },
33
+ "CyberSec-Assistant": {
34
+ "id": "AYI-NEDJIMI/CyberSec-Assistant-3B",
35
+ "description": "General-purpose cybersecurity assistant for incident response, threat analysis, vulnerability management, and security operations.",
36
+ "parameters": "3B",
37
+ "specialty": "General Cybersecurity",
38
+ },
39
+ }
40
+
41
+ MODEL_NAMES = list(MODELS.keys())
42
+
43
+ # System prompts per model
44
+ SYSTEM_PROMPTS = {
45
+ "ISO27001-Expert": (
46
+ "You are ISO27001-Expert, an AI assistant specialized in ISO 27001 information security management systems. "
47
+ "Provide accurate, professional guidance on ISMS implementation, risk assessment, control selection, "
48
+ "audit preparation, and compliance requirements. Reference specific ISO 27001 clauses and Annex A controls when relevant."
49
+ ),
50
+ "RGPD-Expert": (
51
+ "You are RGPD-Expert, an AI assistant specialized in GDPR (General Data Protection Regulation) / RGPD. "
52
+ "Provide accurate guidance on data protection principles, lawful bases for processing, data subject rights, "
53
+ "DPIA procedures, breach notification requirements, and DPO responsibilities. Reference specific GDPR articles when relevant."
54
+ ),
55
+ "CyberSec-Assistant": (
56
+ "You are CyberSec-Assistant, a general-purpose cybersecurity AI assistant. "
57
+ "Provide expert guidance on incident response, threat intelligence, vulnerability management, "
58
+ "penetration testing, SOC operations, network security, and security architecture. "
59
+ "Be practical and actionable in your recommendations."
60
+ ),
61
+ }
62
+
63
+ # Inference client
64
+ HF_TOKEN = os.getenv("HF_TOKEN", "")
65
+ client = InferenceClient(token=HF_TOKEN) if HF_TOKEN else None
66
+
67
+ # Rate limiting state
68
+ _request_log: list[float] = []
69
+ RATE_LIMIT_WINDOW = 60 # seconds
70
+ RATE_LIMIT_MAX = 30 # requests per window
71
+
72
+
73
+ # ---------------------------------------------------------------------------
74
+ # Core functions
75
+ # ---------------------------------------------------------------------------
76
+
77
+ def _check_rate_limit() -> bool:
78
+ """Return True if within rate limit."""
79
+ now = time.time()
80
+ _request_log[:] = [t for t in _request_log if now - t < RATE_LIMIT_WINDOW]
81
+ if len(_request_log) >= RATE_LIMIT_MAX:
82
+ return False
83
+ _request_log.append(now)
84
+ return True
85
+
86
+
87
+ def _query_model(message: str, model_name: str, max_tokens: int = 512) -> str:
88
+ """Send a prompt to the specified model via the HF Inference API."""
89
+ if not client:
90
+ return "[Error] HF_TOKEN is not configured. The API is unavailable."
91
+
92
+ if model_name not in MODELS:
93
+ return f"[Error] Unknown model '{model_name}'. Available: {', '.join(MODEL_NAMES)}"
94
+
95
+ if not _check_rate_limit():
96
+ return "[Error] Rate limit exceeded. Please wait before sending more requests."
97
+
98
+ model_id = MODELS[model_name]["id"]
99
+ system_prompt = SYSTEM_PROMPTS[model_name]
100
+
101
+ try:
102
+ messages = [
103
+ {"role": "system", "content": system_prompt},
104
+ {"role": "user", "content": message},
105
+ ]
106
+ response = client.chat_completion(
107
+ model=model_id,
108
+ messages=messages,
109
+ max_tokens=max_tokens,
110
+ temperature=0.7,
111
+ )
112
+ return response.choices[0].message.content
113
+
114
+ except Exception as e:
115
+ error_str = str(e)
116
+ # Fallback to text_generation if chat_completion is not supported
117
+ if "not supported" in error_str.lower() or "chat" in error_str.lower():
118
+ try:
119
+ prompt = f"### System:\n{system_prompt}\n\n### User:\n{message}\n\n### Assistant:\n"
120
+ response = client.text_generation(
121
+ prompt=prompt,
122
+ model=model_id,
123
+ max_new_tokens=max_tokens,
124
+ temperature=0.7,
125
+ do_sample=True,
126
+ )
127
+ return response
128
+ except Exception as fallback_err:
129
+ return f"[Error] Model query failed: {fallback_err}"
130
+ return f"[Error] Model query failed: {e}"
131
+
132
+
133
+ # ---------------------------------------------------------------------------
134
+ # API endpoint functions (exposed via Gradio)
135
+ # ---------------------------------------------------------------------------
136
+
137
+ def chat(message: str, model_name: str) -> str:
138
+ """Send a message to a specific cybersecurity model and get a response.
139
+
140
+ Args:
141
+ message: The question or prompt to send to the model.
142
+ model_name: One of 'ISO27001-Expert', 'RGPD-Expert', or 'CyberSec-Assistant'.
143
+
144
+ Returns:
145
+ The model's response text.
146
+ """
147
+ if not message or not message.strip():
148
+ return "[Error] Message cannot be empty."
149
+ return _query_model(message.strip(), model_name)
150
+
151
+
152
+ def compare(message: str) -> str:
153
+ """Send a message to all 3 models and compare their responses side by side.
154
+
155
+ Args:
156
+ message: The question or prompt to send to all models.
157
+
158
+ Returns:
159
+ JSON string with responses from each model.
160
+ """
161
+ if not message or not message.strip():
162
+ return json.dumps({"error": "Message cannot be empty."}, indent=2)
163
+
164
+ results = {}
165
+ for name in MODEL_NAMES:
166
+ results[name] = {
167
+ "model_id": MODELS[name]["id"],
168
+ "specialty": MODELS[name]["specialty"],
169
+ "response": _query_model(message.strip(), name),
170
+ }
171
+
172
+ return json.dumps(results, indent=2, ensure_ascii=False)
173
+
174
+
175
+ def list_models() -> str:
176
+ """List all available cybersecurity models and their details.
177
+
178
+ Returns:
179
+ JSON string with model information.
180
+ """
181
+ model_list = []
182
+ for name, info in MODELS.items():
183
+ model_list.append({
184
+ "name": name,
185
+ "model_id": info["id"],
186
+ "description": info["description"],
187
+ "parameters": info["parameters"],
188
+ "specialty": info["specialty"],
189
+ "endpoint": f"/api/chat with model_name='{name}'",
190
+ })
191
+ return json.dumps({"models": model_list, "count": len(model_list)}, indent=2)
192
+
193
+
194
+ def health_check() -> str:
195
+ """Check the health status of the API and its dependencies.
196
+
197
+ Returns:
198
+ JSON string with health status information.
199
+ """
200
+ status = {
201
+ "status": "healthy" if client else "degraded",
202
+ "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
203
+ "version": "1.0.0",
204
+ "hf_token_configured": bool(HF_TOKEN),
205
+ "models_available": MODEL_NAMES,
206
+ "rate_limit": {
207
+ "window_seconds": RATE_LIMIT_WINDOW,
208
+ "max_requests": RATE_LIMIT_MAX,
209
+ "current_usage": len([t for t in _request_log if time.time() - t < RATE_LIMIT_WINDOW]),
210
+ },
211
+ }
212
+ return json.dumps(status, indent=2)
213
+
214
+
215
+ # ---------------------------------------------------------------------------
216
+ # Tab content builders
217
+ # ---------------------------------------------------------------------------
218
+
219
+ API_DOCS_MD = """
220
+ # CyberSec-API Documentation
221
+
222
+ A REST API gateway providing unified access to three specialized cybersecurity AI models hosted on Hugging Face.
223
+
224
+ ---
225
+
226
+ ## Available Models
227
+
228
+ | Model | Specialty | Parameters | Model ID |
229
+ |-------|-----------|------------|----------|
230
+ | **ISO27001-Expert** | ISO 27001 compliance, ISMS, risk assessment | 1.5B | `AYI-NEDJIMI/ISO27001-Expert-1.5B` |
231
+ | **RGPD-Expert** | GDPR/RGPD, data protection, privacy | 1.5B | `AYI-NEDJIMI/RGPD-Expert-1.5B` |
232
+ | **CyberSec-Assistant** | Incident response, threat analysis, SOC | 3B | `AYI-NEDJIMI/CyberSec-Assistant-3B` |
233
+
234
+ ---
235
+
236
+ ## Endpoints
237
+
238
+ ### POST `/api/chat`
239
+ Send a message to a specific cybersecurity model.
240
+
241
+ **Parameters:**
242
+ | Parameter | Type | Required | Description |
243
+ |-----------|------|----------|-------------|
244
+ | `message` | string | Yes | The question or prompt |
245
+ | `model_name` | string | Yes | One of: `ISO27001-Expert`, `RGPD-Expert`, `CyberSec-Assistant` |
246
+
247
+ **Response:** Plain text response from the model.
248
+
249
+ ---
250
+
251
+ ### POST `/api/compare`
252
+ Send the same message to all 3 models and compare their responses.
253
+
254
+ **Parameters:**
255
+ | Parameter | Type | Required | Description |
256
+ |-----------|------|----------|-------------|
257
+ | `message` | string | Yes | The question or prompt |
258
+
259
+ **Response:** JSON object with each model's response.
260
+
261
+ ---
262
+
263
+ ### GET `/api/models`
264
+ List all available models and their details.
265
+
266
+ **Parameters:** None
267
+
268
+ **Response:** JSON object with model information.
269
+
270
+ ---
271
+
272
+ ### GET `/api/health`
273
+ Health check endpoint for monitoring.
274
+
275
+ **Parameters:** None
276
+
277
+ **Response:** JSON object with API status, version, and rate limit info.
278
+
279
+ ---
280
+
281
+ ## Rate Limits
282
+
283
+ | Limit | Value |
284
+ |-------|-------|
285
+ | Requests per minute | 30 |
286
+ | Max tokens per request | 512 |
287
+ | Concurrent requests | 5 |
288
+
289
+ ---
290
+
291
+ ## Code Examples
292
+
293
+ ### Python (using `gradio_client`)
294
+
295
+ ```python
296
+ from gradio_client import Client
297
+
298
+ # Connect to the API
299
+ client = Client("AYI-NEDJIMI/CyberSec-API")
300
+
301
+ # Chat with a specific model
302
+ result = client.predict(
303
+ message="What are the key requirements of ISO 27001 Clause 6?",
304
+ model_name="ISO27001-Expert",
305
+ api_name="/chat"
306
+ )
307
+ print(result)
308
+
309
+ # Compare all models
310
+ result = client.predict(
311
+ message="How should we handle a data breach?",
312
+ api_name="/compare"
313
+ )
314
+ print(result)
315
+
316
+ # List available models
317
+ models = client.predict(api_name="/models")
318
+ print(models)
319
+
320
+ # Health check
321
+ status = client.predict(api_name="/health")
322
+ print(status)
323
+ ```
324
+
325
+ ### Python (using `requests`)
326
+
327
+ ```python
328
+ import requests
329
+
330
+ SPACE_URL = "https://ayi-nedjimi-cybersec-api.hf.space"
331
+
332
+ # Chat endpoint
333
+ response = requests.post(
334
+ f"{SPACE_URL}/api/chat",
335
+ json={
336
+ "data": [
337
+ "What controls does ISO 27001 Annex A recommend for access management?",
338
+ "ISO27001-Expert"
339
+ ]
340
+ }
341
+ )
342
+ print(response.json()["data"][0])
343
+
344
+ # Compare endpoint
345
+ response = requests.post(
346
+ f"{SPACE_URL}/api/compare",
347
+ json={
348
+ "data": ["How do you perform a risk assessment?"]
349
+ }
350
+ )
351
+ print(response.json()["data"][0])
352
+ ```
353
+
354
+ ### cURL
355
+
356
+ ```bash
357
+ # Chat with a model
358
+ curl -X POST "https://ayi-nedjimi-cybersec-api.hf.space/api/chat" \\
359
+ -H "Content-Type: application/json" \\
360
+ -d '{"data": ["What is ISO 27001?", "ISO27001-Expert"]}'
361
+
362
+ # Compare all models
363
+ curl -X POST "https://ayi-nedjimi-cybersec-api.hf.space/api/compare" \\
364
+ -H "Content-Type: application/json" \\
365
+ -d '{"data": ["Explain the principle of least privilege"]}'
366
+
367
+ # List models
368
+ curl -X POST "https://ayi-nedjimi-cybersec-api.hf.space/api/models" \\
369
+ -H "Content-Type: application/json" \\
370
+ -d '{"data": []}'
371
+
372
+ # Health check
373
+ curl -X POST "https://ayi-nedjimi-cybersec-api.hf.space/api/health" \\
374
+ -H "Content-Type: application/json" \\
375
+ -d '{"data": []}'
376
+ ```
377
+
378
+ ### JavaScript
379
+
380
+ ```javascript
381
+ import { Client } from "@gradio/client";
382
+
383
+ const client = await Client.connect("AYI-NEDJIMI/CyberSec-API");
384
+
385
+ // Chat with a model
386
+ const chatResult = await client.predict("/chat", {
387
+ message: "What are GDPR data subject rights?",
388
+ model_name: "RGPD-Expert",
389
+ });
390
+ console.log(chatResult.data[0]);
391
+
392
+ // Compare all models
393
+ const compareResult = await client.predict("/compare", {
394
+ message: "How to respond to a ransomware attack?",
395
+ });
396
+ console.log(JSON.parse(compareResult.data[0]));
397
+
398
+ // List models
399
+ const models = await client.predict("/models", {});
400
+ console.log(JSON.parse(models.data[0]));
401
+ ```
402
+
403
+ ---
404
+
405
+ ## Authentication
406
+
407
+ This API is publicly accessible. No authentication token is required to call the endpoints.
408
+ The API uses an internal HF token (configured as a Space secret) to communicate with the
409
+ Hugging Face Inference API on your behalf.
410
+
411
+ ---
412
+
413
+ ## Error Handling
414
+
415
+ All endpoints return error messages in a consistent format:
416
+
417
+ | Error | Description |
418
+ |-------|-------------|
419
+ | `[Error] Message cannot be empty.` | The message parameter was empty or missing |
420
+ | `[Error] Unknown model '...'` | Invalid model_name provided |
421
+ | `[Error] Rate limit exceeded.` | Too many requests -- wait and retry |
422
+ | `[Error] Model query failed: ...` | Upstream inference error |
423
+ """
424
+
425
+ INTEGRATION_GUIDE_MD = """
426
+ # Integration Guide
427
+
428
+ Integrate CyberSec-API into your security infrastructure, automation pipelines, and communication tools.
429
+
430
+ ---
431
+
432
+ ## 1. SIEM Integration
433
+
434
+ ### Splunk Integration
435
+
436
+ Create a custom Splunk alert action that queries CyberSec-API for incident analysis:
437
+
438
+ ```python
439
+ # splunk_cybersec_action.py
440
+ # Place in $SPLUNK_HOME/etc/apps/your_app/bin/
441
+
442
+ import sys
443
+ import json
444
+ import requests
445
+
446
+ CYBERSEC_API = "https://ayi-nedjimi-cybersec-api.hf.space"
447
+
448
+ def analyze_alert(alert_data):
449
+ \"\"\"Send Splunk alert data to CyberSec-Assistant for analysis.\"\"\"
450
+ prompt = f\"\"\"Analyze this security alert and provide:
451
+ 1. Severity assessment
452
+ 2. Recommended immediate actions
453
+ 3. Investigation steps
454
+
455
+ Alert Data:
456
+ {json.dumps(alert_data, indent=2)}
457
+ \"\"\"
458
+ response = requests.post(
459
+ f"{CYBERSEC_API}/api/chat",
460
+ json={"data": [prompt, "CyberSec-Assistant"]},
461
+ timeout=60
462
+ )
463
+ return response.json()["data"][0]
464
+
465
+ if __name__ == "__main__":
466
+ # Read alert payload from Splunk
467
+ alert_payload = json.loads(sys.stdin.read())
468
+ analysis = analyze_alert(alert_payload)
469
+ print(analysis)
470
+ ```
471
+
472
+ **Splunk `alert_actions.conf`:**
473
+ ```ini
474
+ [cybersec_analyze]
475
+ label = CyberSec AI Analysis
476
+ description = Analyze security alerts using CyberSec-API
477
+ command = python3 $SPLUNK_HOME/etc/apps/cybersec/bin/splunk_cybersec_action.py
478
+ is_custom = 1
479
+ ```
480
+
481
+ ### Microsoft Sentinel Integration
482
+
483
+ Use an Azure Logic App or Function to call CyberSec-API from Sentinel playbooks:
484
+
485
+ ```python
486
+ # azure_function/cybersec_sentinel/__init__.py
487
+ import json
488
+ import logging
489
+ import requests
490
+ import azure.functions as func
491
+
492
+ CYBERSEC_API = "https://ayi-nedjimi-cybersec-api.hf.space"
493
+
494
+ def main(req: func.HttpRequest) -> func.HttpResponse:
495
+ \"\"\"Azure Function triggered by Sentinel incident.\"\"\"
496
+ incident = req.get_json()
497
+
498
+ prompt = f\"\"\"Analyze this Microsoft Sentinel security incident:
499
+ Title: {incident.get('title', 'N/A')}
500
+ Severity: {incident.get('severity', 'N/A')}
501
+ Description: {incident.get('description', 'N/A')}
502
+ Entities: {json.dumps(incident.get('entities', []))}
503
+
504
+ Provide: severity validation, recommended response actions, and investigation queries.
505
+ \"\"\"
506
+ # Check if it is compliance-related
507
+ model = "CyberSec-Assistant"
508
+ title_lower = incident.get("title", "").lower()
509
+ if "gdpr" in title_lower or "data protection" in title_lower:
510
+ model = "RGPD-Expert"
511
+ elif "compliance" in title_lower or "audit" in title_lower:
512
+ model = "ISO27001-Expert"
513
+
514
+ response = requests.post(
515
+ f"{CYBERSEC_API}/api/chat",
516
+ json={"data": [prompt, model]},
517
+ timeout=60
518
+ )
519
+
520
+ return func.HttpResponse(
521
+ json.dumps({"analysis": response.json()["data"][0], "model_used": model}),
522
+ mimetype="application/json"
523
+ )
524
+ ```
525
+
526
+ ---
527
+
528
+ ## 2. Chat Bot Integration
529
+
530
+ ### Slack Bot
531
+
532
+ ```python
533
+ # slack_cybersec_bot.py
534
+ import os
535
+ import json
536
+ import requests
537
+ from slack_bolt import App
538
+ from slack_bolt.adapter.socket_mode import SocketModeHandler
539
+
540
+ CYBERSEC_API = "https://ayi-nedjimi-cybersec-api.hf.space"
541
+
542
+ app = App(token=os.environ["SLACK_BOT_TOKEN"])
543
+
544
+ MODEL_MAP = {
545
+ "iso": "ISO27001-Expert",
546
+ "gdpr": "RGPD-Expert",
547
+ "rgpd": "RGPD-Expert",
548
+ "sec": "CyberSec-Assistant",
549
+ "cyber": "CyberSec-Assistant",
550
+ }
551
+
552
+ def detect_model(text):
553
+ \"\"\"Auto-detect the best model based on keywords.\"\"\"
554
+ text_lower = text.lower()
555
+ for keyword, model in MODEL_MAP.items():
556
+ if keyword in text_lower:
557
+ return model
558
+ return "CyberSec-Assistant" # default
559
+
560
+ @app.message("!ask")
561
+ def handle_ask(message, say):
562
+ \"\"\"Handle '!ask <question>' messages.\"\"\"
563
+ query = message["text"].replace("!ask", "").strip()
564
+ if not query:
565
+ say("Usage: `!ask <your cybersecurity question>`")
566
+ return
567
+
568
+ model = detect_model(query)
569
+ say(f"Asking *{model}*... :hourglass:")
570
+
571
+ response = requests.post(
572
+ f"{CYBERSEC_API}/api/chat",
573
+ json={"data": [query, model]},
574
+ timeout=60
575
+ )
576
+ answer = response.json()["data"][0]
577
+ say(f"*{model}:*\\n{answer}")
578
+
579
+ @app.message("!compare")
580
+ def handle_compare(message, say):
581
+ \"\"\"Handle '!compare <question>' to get all 3 model responses.\"\"\"
582
+ query = message["text"].replace("!compare", "").strip()
583
+ if not query:
584
+ say("Usage: `!compare <your cybersecurity question>`")
585
+ return
586
+
587
+ say("Comparing all 3 models... :hourglass:")
588
+ response = requests.post(
589
+ f"{CYBERSEC_API}/api/compare",
590
+ json={"data": [query]},
591
+ timeout=120
592
+ )
593
+ results = json.loads(response.json()["data"][0])
594
+
595
+ for model_name, data in results.items():
596
+ say(f"*{model_name}* ({data['specialty']}):\\n{data['response']}")
597
+
598
+ if __name__ == "__main__":
599
+ handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
600
+ handler.start()
601
+ ```
602
+
603
+ ### Discord Bot
604
+
605
+ ```python
606
+ # discord_cybersec_bot.py
607
+ import os
608
+ import json
609
+ import discord
610
+ import requests
611
+ from discord.ext import commands
612
+
613
+ CYBERSEC_API = "https://ayi-nedjimi-cybersec-api.hf.space"
614
+
615
+ bot = commands.Bot(command_prefix="!", intents=discord.Intents.default())
616
+
617
+ @bot.command(name="ask")
618
+ async def ask(ctx, model: str = "CyberSec-Assistant", *, question: str):
619
+ \"\"\"Ask a cybersecurity question. Usage: !ask [model] <question>\"\"\"
620
+ valid_models = ["ISO27001-Expert", "RGPD-Expert", "CyberSec-Assistant"]
621
+ if model not in valid_models:
622
+ question = f"{model} {question}"
623
+ model = "CyberSec-Assistant"
624
+
625
+ await ctx.send(f"Querying **{model}**...")
626
+
627
+ response = requests.post(
628
+ f"{CYBERSEC_API}/api/chat",
629
+ json={"data": [question, model]},
630
+ timeout=60
631
+ )
632
+ answer = response.json()["data"][0]
633
+
634
+ # Discord has a 2000 char limit
635
+ if len(answer) > 1900:
636
+ for i in range(0, len(answer), 1900):
637
+ await ctx.send(answer[i:i+1900])
638
+ else:
639
+ await ctx.send(f"**{model}:**\\n{answer}")
640
+
641
+ bot.run(os.environ["DISCORD_TOKEN"])
642
+ ```
643
+
644
+ ---
645
+
646
+ ## 3. CI/CD Pipeline Integration
647
+
648
+ ### GitHub Actions
649
+
650
+ ```yaml
651
+ # .github/workflows/security-review.yml
652
+ name: AI Security Review
653
+ on:
654
+ pull_request:
655
+ paths:
656
+ - '**.py'
657
+ - '**.js'
658
+ - '**.yml'
659
+ - 'Dockerfile'
660
+
661
+ jobs:
662
+ security-review:
663
+ runs-on: ubuntu-latest
664
+ steps:
665
+ - uses: actions/checkout@v4
666
+
667
+ - name: Get changed files
668
+ id: changed
669
+ run: |
670
+ FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD)
671
+ echo "files=$FILES" >> $GITHUB_OUTPUT
672
+
673
+ - name: AI Security Review
674
+ run: |
675
+ pip install requests
676
+ python - <<'SCRIPT'
677
+ import requests, os, json
678
+
679
+ API = "https://ayi-nedjimi-cybersec-api.hf.space"
680
+ files = "${{ steps.changed.outputs.files }}".split("\\n")
681
+
682
+ prompt = f\"\"\"Review these changed files for security vulnerabilities,
683
+ hardcoded secrets, and compliance issues:
684
+
685
+ Changed files: {', '.join(files)}
686
+
687
+ Provide a security assessment with:
688
+ 1. Critical issues found
689
+ 2. Recommendations
690
+ 3. Compliance notes (ISO 27001 / GDPR if applicable)
691
+ \"\"\"
692
+
693
+ resp = requests.post(
694
+ f"{API}/api/compare",
695
+ json={"data": [prompt]},
696
+ timeout=120
697
+ )
698
+ results = json.loads(resp.json()["data"][0])
699
+ for model, data in results.items():
700
+ print(f"\\n{'='*60}")
701
+ print(f"Model: {model} ({data['specialty']})")
702
+ print(f"{'='*60}")
703
+ print(data["response"])
704
+ SCRIPT
705
+ ```
706
+
707
+ ### GitLab CI
708
+
709
+ ```yaml
710
+ # .gitlab-ci.yml
711
+ security-ai-scan:
712
+ stage: test
713
+ image: python:3.11-slim
714
+ script:
715
+ - pip install requests
716
+ - |
717
+ python3 -c "
718
+ import requests, json
719
+
720
+ API = 'https://ayi-nedjimi-cybersec-api.hf.space'
721
+ resp = requests.post(
722
+ f'{API}/api/chat',
723
+ json={'data': [
724
+ 'Review this CI/CD pipeline for security best practices and suggest improvements.',
725
+ 'CyberSec-Assistant'
726
+ ]},
727
+ timeout=60
728
+ )
729
+ print(resp.json()['data'][0])
730
+ "
731
+ only:
732
+ changes:
733
+ - .gitlab-ci.yml
734
+ - Dockerfile
735
+ - docker-compose*.yml
736
+ ```
737
+
738
+ ---
739
+
740
+ ## 4. Python SDK Example
741
+
742
+ Create a reusable Python SDK wrapper for clean integration:
743
+
744
+ ```python
745
+ # cybersec_sdk.py
746
+ \"\"\"CyberSec-API Python SDK\"\"\"
747
+
748
+ import json
749
+ from typing import Optional
750
+ from gradio_client import Client
751
+
752
+
753
+ class CyberSecAPI:
754
+ \"\"\"Client for the CyberSec-API gateway.\"\"\"
755
+
756
+ MODELS = ["ISO27001-Expert", "RGPD-Expert", "CyberSec-Assistant"]
757
+
758
+ def __init__(self, space_id: str = "AYI-NEDJIMI/CyberSec-API"):
759
+ self.client = Client(space_id)
760
+
761
+ def chat(self, message: str, model: str = "CyberSec-Assistant") -> str:
762
+ \"\"\"Send a question to a specific model.\"\"\"
763
+ if model not in self.MODELS:
764
+ raise ValueError(f"Unknown model '{model}'. Choose from: {self.MODELS}")
765
+ return self.client.predict(
766
+ message=message,
767
+ model_name=model,
768
+ api_name="/chat"
769
+ )
770
+
771
+ def compare(self, message: str) -> dict:
772
+ \"\"\"Get responses from all 3 models for comparison.\"\"\"
773
+ result = self.client.predict(message=message, api_name="/compare")
774
+ return json.loads(result)
775
+
776
+ def models(self) -> dict:
777
+ \"\"\"List available models.\"\"\"
778
+ result = self.client.predict(api_name="/models")
779
+ return json.loads(result)
780
+
781
+ def health(self) -> dict:
782
+ \"\"\"Check API health status.\"\"\"
783
+ result = self.client.predict(api_name="/health")
784
+ return json.loads(result)
785
+
786
+ def ask_iso27001(self, question: str) -> str:
787
+ \"\"\"Shortcut to query the ISO 27001 expert.\"\"\"
788
+ return self.chat(question, model="ISO27001-Expert")
789
+
790
+ def ask_rgpd(self, question: str) -> str:
791
+ \"\"\"Shortcut to query the RGPD/GDPR expert.\"\"\"
792
+ return self.chat(question, model="RGPD-Expert")
793
+
794
+ def ask_cybersec(self, question: str) -> str:
795
+ \"\"\"Shortcut to query the general cybersecurity assistant.\"\"\"
796
+ return self.chat(question, model="CyberSec-Assistant")
797
+
798
+
799
+ # Usage example
800
+ if __name__ == "__main__":
801
+ api = CyberSecAPI()
802
+
803
+ # Check health
804
+ print("Health:", api.health())
805
+
806
+ # Ask a question
807
+ answer = api.ask_iso27001("What are the mandatory documents for ISO 27001 certification?")
808
+ print("Answer:", answer)
809
+
810
+ # Compare models
811
+ comparison = api.compare("What is the best approach to incident response?")
812
+ for model, data in comparison.items():
813
+ print(f"\\n{model}: {data['response'][:200]}...")
814
+ ```
815
+
816
+ ---
817
+
818
+ ## 5. Webhook Integration
819
+
820
+ For event-driven architectures, set up a webhook relay:
821
+
822
+ ```python
823
+ # webhook_relay.py
824
+ from flask import Flask, request, jsonify
825
+ import requests
826
+
827
+ app = Flask(__name__)
828
+ CYBERSEC_API = "https://ayi-nedjimi-cybersec-api.hf.space"
829
+
830
+ @app.route("/webhook/security-alert", methods=["POST"])
831
+ def security_alert_webhook():
832
+ \"\"\"Receive security alerts and auto-analyze with CyberSec-API.\"\"\"
833
+ alert = request.json
834
+ prompt = f"Analyze this security alert: {json.dumps(alert)}"
835
+
836
+ response = requests.post(
837
+ f"{CYBERSEC_API}/api/chat",
838
+ json={"data": [prompt, "CyberSec-Assistant"]},
839
+ timeout=60
840
+ )
841
+
842
+ return jsonify({
843
+ "alert_id": alert.get("id"),
844
+ "ai_analysis": response.json()["data"][0]
845
+ })
846
+ ```
847
+ """
848
+
849
+ # ---------------------------------------------------------------------------
850
+ # CSS
851
+ # ---------------------------------------------------------------------------
852
+
853
+ CUSTOM_CSS = """
854
+ .api-docs {
855
+ max-width: 900px;
856
+ margin: 0 auto;
857
+ }
858
+ .model-card {
859
+ border: 1px solid #374151;
860
+ border-radius: 8px;
861
+ padding: 16px;
862
+ margin: 8px 0;
863
+ background: #1a1a2e;
864
+ }
865
+ .header-banner {
866
+ background: linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%);
867
+ padding: 24px;
868
+ border-radius: 12px;
869
+ margin-bottom: 16px;
870
+ border: 1px solid #333;
871
+ text-align: center;
872
+ }
873
+ .status-badge {
874
+ display: inline-block;
875
+ padding: 4px 12px;
876
+ border-radius: 12px;
877
+ font-size: 0.85em;
878
+ font-weight: 600;
879
+ }
880
+ .status-healthy { background: #064e3b; color: #6ee7b7; }
881
+ .status-degraded { background: #78350f; color: #fcd34d; }
882
+ footer { display: none !important; }
883
+ """
884
+
885
+ # ---------------------------------------------------------------------------
886
+ # Gradio UI
887
+ # ---------------------------------------------------------------------------
888
+
889
+ with gr.Blocks(
890
+ title="CyberSec-API",
891
+ css=CUSTOM_CSS,
892
+ theme=gr.themes.Base(
893
+ primary_hue="blue",
894
+ secondary_hue="gray",
895
+ neutral_hue="gray",
896
+ ),
897
+ ) as demo:
898
+
899
+ # Header
900
+ gr.HTML("""
901
+ <div class="header-banner">
902
+ <h1 style="margin:0; font-size:2em; color:#60a5fa;">CyberSec-API</h1>
903
+ <p style="margin:4px 0 0; color:#9ca3af; font-size:1.1em;">
904
+ REST API Gateway for Cybersecurity AI Models
905
+ </p>
906
+ <p style="margin:8px 0 0; color:#6b7280; font-size:0.9em;">
907
+ ISO 27001 &bull; GDPR/RGPD &bull; General Cybersecurity
908
+ </p>
909
+ </div>
910
+ """)
911
+
912
+ with gr.Tabs():
913
+ # ===== Tab 1: API Documentation =====
914
+ with gr.Tab("API Documentation", id="docs"):
915
+ gr.Markdown(API_DOCS_MD, elem_classes=["api-docs"])
916
+
917
+ # ===== Tab 2: Try It =====
918
+ with gr.Tab("Try It", id="try-it"):
919
+ gr.Markdown("## Interactive API Tester")
920
+ gr.Markdown("Select a model, type your cybersecurity question, and get a response.")
921
+
922
+ with gr.Row():
923
+ with gr.Column(scale=2):
924
+ model_selector = gr.Dropdown(
925
+ choices=MODEL_NAMES,
926
+ value="CyberSec-Assistant",
927
+ label="Select Model",
928
+ info="Choose which cybersecurity expert to query",
929
+ )
930
+ user_input = gr.Textbox(
931
+ label="Your Question",
932
+ placeholder="e.g., What are the key steps for implementing an ISMS according to ISO 27001?",
933
+ lines=4,
934
+ )
935
+ with gr.Row():
936
+ submit_btn = gr.Button("Submit", variant="primary", scale=2)
937
+ clear_btn = gr.Button("Clear", variant="secondary", scale=1)
938
+
939
+ with gr.Column(scale=3):
940
+ response_output = gr.Textbox(
941
+ label="Model Response",
942
+ lines=16,
943
+ interactive=False,
944
+ show_copy_button=True,
945
+ )
946
+
947
+ gr.Markdown("---")
948
+ gr.Markdown("### Quick Examples")
949
+ gr.Examples(
950
+ examples=[
951
+ ["What are the mandatory documents required for ISO 27001 certification?", "ISO27001-Expert"],
952
+ ["Explain the GDPR right to data portability under Article 20.", "RGPD-Expert"],
953
+ ["How should a SOC team respond to a ransomware incident?", "CyberSec-Assistant"],
954
+ ["What is the difference between ISO 27001 and ISO 27002?", "ISO27001-Expert"],
955
+ ["What are the lawful bases for processing personal data under GDPR?", "RGPD-Expert"],
956
+ ["Explain the MITRE ATT&CK framework and its use in threat hunting.", "CyberSec-Assistant"],
957
+ ],
958
+ inputs=[user_input, model_selector],
959
+ label="Click an example to populate the form",
960
+ )
961
+
962
+ # Compare section
963
+ gr.Markdown("---")
964
+ gr.Markdown("### Compare All Models")
965
+ gr.Markdown("Send the same question to all 3 models and see how each expert responds.")
966
+ compare_input = gr.Textbox(
967
+ label="Question for All Models",
968
+ placeholder="e.g., How do you perform a security risk assessment?",
969
+ lines=2,
970
+ )
971
+ compare_btn = gr.Button("Compare All Models", variant="primary")
972
+ compare_output = gr.Textbox(
973
+ label="Comparison Results (JSON)",
974
+ lines=20,
975
+ interactive=False,
976
+ show_copy_button=True,
977
+ )
978
+
979
+ # Status section
980
+ gr.Markdown("---")
981
+ gr.Markdown("### API Status")
982
+ with gr.Row():
983
+ models_btn = gr.Button("List Models", variant="secondary")
984
+ health_btn = gr.Button("Health Check", variant="secondary")
985
+ status_output = gr.Textbox(
986
+ label="Status Output",
987
+ lines=10,
988
+ interactive=False,
989
+ show_copy_button=True,
990
+ )
991
+
992
+ # Wire up events with api_name for clean API URLs
993
+ submit_btn.click(
994
+ fn=chat,
995
+ inputs=[user_input, model_selector],
996
+ outputs=response_output,
997
+ api_name="chat",
998
+ )
999
+
1000
+ clear_btn.click(
1001
+ fn=lambda: ("", ""),
1002
+ inputs=None,
1003
+ outputs=[user_input, response_output],
1004
+ api_name=False,
1005
+ )
1006
+
1007
+ compare_btn.click(
1008
+ fn=compare,
1009
+ inputs=compare_input,
1010
+ outputs=compare_output,
1011
+ api_name="compare",
1012
+ )
1013
+
1014
+ models_btn.click(
1015
+ fn=list_models,
1016
+ inputs=None,
1017
+ outputs=status_output,
1018
+ api_name="models",
1019
+ )
1020
+
1021
+ health_btn.click(
1022
+ fn=health_check,
1023
+ inputs=None,
1024
+ outputs=status_output,
1025
+ api_name="health",
1026
+ )
1027
+
1028
+ # ===== Tab 3: Integration Guide =====
1029
+ with gr.Tab("Integration Guide", id="integration"):
1030
+ gr.Markdown(INTEGRATION_GUIDE_MD, elem_classes=["api-docs"])
1031
+
1032
+ # Footer
1033
+ gr.Markdown(
1034
+ "<center style='color:#6b7280; margin-top:16px;'>"
1035
+ "CyberSec-API v1.0.0 | "
1036
+ "<a href='https://huggingface.co/AYI-NEDJIMI' target='_blank'>AYI-NEDJIMI</a> | "
1037
+ "Powered by Hugging Face Inference API"
1038
+ "</center>"
1039
+ )
1040
+
1041
+
1042
+ # ---------------------------------------------------------------------------
1043
+ # Launch
1044
+ # ---------------------------------------------------------------------------
1045
+
1046
+ if __name__ == "__main__":
1047
+ demo.launch(
1048
+ server_name="0.0.0.0",
1049
+ server_port=7860,
1050
+ show_api=True,
1051
+ )
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio==5.50.0
2
+ huggingface_hub>=0.20.0