Skip to content

Commit b22f7aa

Browse files
committed
feat(ai): migrate AI features from BYOK to XTM One agents
The extension previously embedded its own LLM integration: users had to bring their own API keys (OpenAI, Anthropic, Gemini, or a custom endpoint), and the extension handled prompt engineering, JSON parsing of raw LLM output, and model selection directly in the browser. This was fragile, hard to iterate on (prompt changes required extension releases), and put the burden of LLM configuration on end users. With XTM One now hosting dedicated agents for each AI feature, the extension becomes a thin client: it sends structured task payloads and receives structured JSON responses. Prompt management, model routing, and output parsing all move server-side. All 7 AI features (description generation, scenario generation, full scenario, atomic testing, email generation, entity discovery, relationship resolution) now call `POST /api/v1/extension/execute-task` with an agent slug. The `AIClient` class is reduced to a single `executeTask()` method that serializes the request into a `content` field and identifies the target agent via `XTM_ONE_AGENT_SLUGS`. Connection testing uses `GET /api/v1/auth/me`. - Deleted `AIProvider` type, `apiKey`, `model`, `customBaseUrl`, `availableModels` from `AISettings` — replaced with `xtmOneUrl` and `apiToken` - Settings UI (`AITab.tsx`) replaced provider/model dropdowns with XTM One URL + token fields; removed "Coming Soon" placeholder - Background handlers (`ai-handlers.ts`, `ai-utils.ts`) simplified to thin wrappers — removed prompt construction, JSON parsing, retry logic - Removed unused `getMaxContentLength()` export from `ai-utils.ts` - Removed dead `AIGenerationRequest`/`AIGenerationResponse` types - `ai/prompts.ts` — hardcoded prompt templates now managed as XTM One agent personas - `ai/json-parser.ts` — JSON extraction from raw LLM output no longer needed (XTM One returns structured data) - Corresponding test files: `prompts.test.ts`, `json-parser.test.ts` - Added `credentials: 'omit'` to OpenCTI client fetch calls - Fixed `credentials: 'omit'` ordering in OpenAEV client — moved after `...options` spread to prevent callers from overriding it - Added user-friendly 401/404 error messages to OpenCTI and OpenAEV clients - Fixed misleading JSDoc on `testConnection()` (claimed "execute-task" but actually calls `/auth/me`) All AI-gated UI surfaces now show "AI is not configured. Configure XTM One in extension settings." when XTM One is not set up. Previously, `ScenarioTypeSelector` and `ScenarioFormView` only showed a generic "AI not available" with no guidance. Enterprise-gate message standardized to "AI features require Enterprise Edition." across all views.
1 parent c6fe25f commit b22f7aa

46 files changed

Lines changed: 2503 additions & 5839 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ This extension integrates with [OpenCTI](https://filigran.io/solutions/open-cti/
4646
- **Atomic testing** - Generate command lines for security testing
4747
- **Entity discovery** - Find entities pattern matching might miss
4848
- **Relationship resolution** - Identify connections between entities
49-
- **Multiple LLM providers** - OpenAI, Anthropic, Google Gemini
49+
- **XTM One AI backend** - All AI features powered by XTM One
5050

5151
### 🎭 Scenario Themes (Table-Top Exercises)
5252

docs/architecture.md

Lines changed: 28 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ src/options/
194194
├── OpenCTITab.tsx # OpenCTI platform configuration
195195
├── OpenAEVTab.tsx # OpenAEV platform configuration
196196
├── DetectionTab.tsx # Detection settings
197-
├── AITab.tsx # AI provider configuration
197+
├── AITab.tsx # XTM One AI configuration
198198
├── AppearanceTab.tsx # Theme settings
199199
└── AboutTab.tsx # About and version info
200200
```
@@ -211,13 +211,11 @@ Common code shared across all components.
211211
```
212212
src/shared/
213213
├── api/ # API clients
214-
│ ├── ai-client.ts # AI provider client (unified interface)
214+
│ ├── ai-client.ts # XTM One agent invocation client
215215
│ ├── opencti-client.ts # OpenCTI GraphQL client
216216
│ ├── openaev-client.ts # OpenAEV REST client
217-
│ ├── ai/ # AI provider modules
218-
│ │ ├── types.ts # AI request/response types
219-
│ │ ├── prompts.ts # AI prompt templates (system prompts, theme configs, builders)
220-
│ │ └── json-parser.ts # AI response parsing utilities
217+
│ ├── ai/ # AI type definitions
218+
│ │ └── types.ts # AI request/response types
221219
│ ├── opencti/ # OpenCTI GraphQL modules
222220
│ │ ├── types.ts # OpenCTI-specific types (query responses)
223221
│ │ ├── fragments.ts # Reusable GraphQL fragments
@@ -237,7 +235,7 @@ src/shared/
237235
├── platform/ # Platform abstractions
238236
│ └── registry.ts # Platform type registry
239237
├── types/ # TypeScript definitions
240-
│ ├── ai.ts # AI provider types, model selection, affinities
238+
│ ├── ai.ts # AI settings types (XTM One URL, token)
241239
│ ├── common.ts # Common response types and utilities
242240
│ ├── messages.ts # Extension message types and payloads
243241
│ ├── observables.ts # Observable types (IoCs) and detection interfaces
@@ -829,9 +827,9 @@ User clicks "Generate with AI" for scenario
829827
│ - Inject count & duration │
830828
│ - Additional context │
831829
│ │
832-
│ 3. Call AI provider
830+
│ 3. Call XTM One agent
833831
│ │
834-
│ 4. Parse JSON response
832+
│ 4. Receive structured JSON
835833
└────────┬────────────────────────────┘
836834
837835
@@ -873,8 +871,8 @@ User clicks "Discover more with AI"
873871
│ - Page URL │
874872
│ - Page content │
875873
│ - Existing entities │
876-
│ - Call AI provider
877-
│ - Parse JSON response
874+
│ - Call XTM One agent
875+
│ - Receive structured JSON
878876
└────────┬────────────────────────┘
879877
880878
@@ -915,105 +913,34 @@ User clicks "Discover more with AI"
915913

916914
## AI Integration
917915

918-
### Module Architecture
916+
### Architecture
919917

920-
The AI client is modularized for maintainability:
918+
All AI features are routed through **XTM One** — the extension is a thin client that ships raw context to XTM One agents and receives structured JSON back. There is no BYOK (Bring Your Own Key) mode and no direct LLM provider integration. See `docs/features/xtm-one-integration-architecture.md` for the full design rationale.
921919

922920
```
923-
src/shared/api/ai/
924-
├── types.ts # AI request/response type definitions
925-
── prompts.ts # All prompt templates and builders (system prompts, themes, JSON schemas)
926-
└── json-parser.ts # Robust AI response parsing (code blocks, malformed JSON)
921+
src/shared/api/
922+
├── ai-client.ts # XTM One execute-task client (AIClient class)
923+
── ai/
924+
└── types.ts # AI request/response type definitions
927925
```
928926

929927
**Key design decisions:**
930-
- **Prompt separation**: All prompts extracted to `prompts.ts` (~560 lines) for easy maintenance
931-
- **Unified interface**: Single `AIClient` class handles OpenAI, Anthropic, and Gemini
932-
- **Type-safe builders**: Functions like `buildScenarioPrompt()` ensure consistent prompt structure
933-
934-
### Supported Providers
935-
936-
| Provider | Client Class | Models |
937-
|----------|--------------|--------|
938-
| OpenAI | `AIClient` | GPT-4o, GPT-4 Turbo, GPT-4 |
939-
| Anthropic | `AIClient` | Claude 3.5 Sonnet, Claude 3 Opus |
940-
| Google | `AIClient` | Gemini 1.5 Pro, Gemini 1.5 Flash |
928+
- **Thin client, thick platform**: The extension owns no prompt logic — XTM One owns prompts, model selection, RBAC, quotas, and structured output.
929+
- **Single endpoint**: All tasks go through `POST {xtmOneUrl}/api/v1/extension/execute-task` with a `Bearer fcp-…` token.
930+
- **Agent-per-feature**: Each AI feature maps 1:1 to a dedicated XTM One agent identified by slug.
941931

942932
### AI Features
943933

944-
| Feature | Message Type | Description |
945-
|---------|--------------|-------------|
946-
| Container Description | `AI_GENERATE_DESCRIPTION` | Generate intelligent descriptions from page context |
947-
| Full Scenario Generation | `AI_GENERATE_FULL_SCENARIO` | Generate complete scenarios with injects |
948-
| Atomic Test Generation | `AI_GENERATE_ATOMIC_TEST` | Generate test commands for attack patterns |
949-
| Email Generation | `AI_GENERATE_EMAILS` | Generate email content for table-top exercises |
950-
| Entity Discovery | `AI_DISCOVER_ENTITIES` | Discover entities pattern matching missed |
951-
| Relationship Resolution | `AI_RESOLVE_RELATIONSHIPS` | Identify relationships between entities |
952-
953-
### Prompt Templates (in `ai/prompts.ts`)
954-
955-
All prompt templates are centralized for maintainability:
956-
957-
```typescript
958-
// System prompts for different operations
959-
export const SYSTEM_PROMPTS = {
960-
CONTAINER_DESCRIPTION: '...',
961-
SCENARIO_GENERATION: '...',
962-
ATOMIC_TEST: '...',
963-
EMAIL_GENERATION: '...',
964-
ENTITY_DISCOVERY: '...',
965-
RELATIONSHIP_RESOLUTION: '...',
966-
};
967-
968-
// Theme-specific configurations for table-top scenarios
969-
export const TABLE_TOP_THEMES = {
970-
'cybersecurity': { /* ... */ },
971-
'physical-security': { /* ... */ },
972-
// ... other themes
973-
};
974-
975-
// Prompt builder functions
976-
export function buildContainerDescriptionPrompt(request: ContainerDescriptionRequest): string;
977-
export function buildScenarioPrompt(request: ScenarioGenerationRequest): string;
978-
export function buildFullScenarioPrompt(request: FullScenarioGenerationRequest): string;
979-
export function buildAtomicTestPrompt(request: AtomicTestRequest): string;
980-
export function buildEmailGenerationPrompt(request: EmailGenerationRequest): string;
981-
export function buildEntityDiscoveryPrompt(request: EntityDiscoveryRequest): string;
982-
export function buildRelationshipResolutionPrompt(request: RelationshipResolutionRequest): string;
983-
```
984-
985-
### Scenario Themes
986-
987-
For table-top scenario generation, themes customize the AI prompt. Defined in `ai/prompts.ts`:
988-
989-
```typescript
990-
export const TABLE_TOP_THEMES = {
991-
'cybersecurity': {
992-
systemPromptSuffix: 'Focus on cyber attacks, data breaches, ransomware...',
993-
exampleTopics: 'cyber attacks, malware outbreaks, data breaches...',
994-
},
995-
'physical-security': {
996-
systemPromptSuffix: 'Focus on physical security threats...',
997-
exampleTopics: 'facility intrusions, access control breaches...',
998-
},
999-
'business-continuity': {
1000-
systemPromptSuffix: 'Focus on business disruption scenarios...',
1001-
exampleTopics: 'natural disasters, power outages, supply chain...',
1002-
},
1003-
'crisis-communication': {
1004-
systemPromptSuffix: 'Focus on crisis communication scenarios...',
1005-
exampleTopics: 'media leaks, social media crises, PR incidents...',
1006-
},
1007-
'health-safety': {
1008-
systemPromptSuffix: 'Focus on health and safety incidents...',
1009-
exampleTopics: 'workplace injuries, pandemic outbreaks...',
1010-
},
1011-
'geopolitical': {
1012-
systemPromptSuffix: 'Focus on geopolitical and economic scenarios...',
1013-
exampleTopics: 'sanctions compliance, trade restrictions...',
1014-
},
1015-
};
1016-
```
934+
| Feature | Message Type | XTM One Agent Slug | Description |
935+
|---------|--------------|-------------------|-------------|
936+
| Container Description | `AI_GENERATE_DESCRIPTION` | `browser-container-description` | Generate descriptions from page context |
937+
| Scenario Generation | `AI_GENERATE_SCENARIO` | `browser-scenario-generation` | Generate attack scenarios |
938+
| Full Scenario Generation | `AI_GENERATE_FULL_SCENARIO` | `browser-full-scenario-generation` | Generate complete scenarios with injects |
939+
| Atomic Test Generation | `AI_GENERATE_ATOMIC_TEST` | `browser-atomic-test-generation` | Generate test commands for attack patterns |
940+
| Email Generation | `AI_GENERATE_EMAILS` | `browser-email-generation` | Generate email content for table-top exercises |
941+
| Entity Discovery | `AI_DISCOVER_ENTITIES` | `browser-entity-discovery` | Discover entities pattern matching missed |
942+
| Relationship Resolution | `AI_RESOLVE_RELATIONSHIPS` | `browser-relationship-resolution` | Identify relationships between entities |
943+
| Combined Scan | `AI_SCAN_ALL` | `browser-scan-all` | Entity discovery + relationship resolution in one pass |
1017944

1018945
## Panel Utilities
1019946

docs/configuration.md

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -118,54 +118,31 @@ AI features require at least one connected Enterprise Edition (EE) platform. The
118118

119119
1. Connect to at least one Enterprise Edition platform (OpenCTI EE or OpenAEV EE)
120120
2. Go to **Settings → AI Assistant**
121-
3. Select your LLM provider
122-
4. Enter your API key
123-
5. Click **Save Settings**
121+
3. Enter your **XTM One URL** (e.g. `https://xtm.company.com`)
122+
4. Enter your **XTM One API Token** (starts with `fcp-`)
123+
5. Click **Test Connection** to validate
124+
6. Click **Save Settings**
124125

125-
### Supported LLM Providers
126+
### XTM One Setup
126127

127-
| Provider | API Key | Model Selection |
128-
|----------|---------|-----------------|
129-
| **OpenAI** | Required | Dynamic list from API |
130-
| **Anthropic** | Required | Dynamic list from API |
131-
| **Google Gemini** | Required | Dynamic list from API |
132-
| **XTM One** | Coming Soon | Filigran Agentic AI Platform |
128+
| Field | Description |
129+
|-------|-------------|
130+
| **XTM One URL** | Base URL of your XTM One instance |
131+
| **API Token** | Personal Access Token (generate from your XTM One profile page) |
133132

134-
### Model Selection
133+
### Connection Test
135134

136-
After entering your API key:
135+
After entering your credentials:
137136

138-
1. Click **Test Connection** to validate the key
139-
2. If successful, available models are fetched automatically
140-
3. Select your preferred model from the dropdown
141-
4. Click **Save Settings** to persist your selection
137+
1. Click **Test Connection** to validate the token against XTM One
138+
2. If successful, AI features become available throughout the extension
139+
3. Click **Save Settings** to persist your configuration
142140

143-
Popular models by provider:
144-
145-
| Provider | Recommended Models |
146-
|----------|-------------------|
147-
| OpenAI | `gpt-4o`, `gpt-4-turbo`, `gpt-4` |
148-
| Anthropic | `claude-3-5-sonnet-latest`, `claude-3-opus-latest` |
149-
| Google | `gemini-1.5-pro`, `gemini-1.5-flash` |
150-
151-
### Getting API Keys
152-
153-
#### OpenAI
154-
1. Go to [platform.openai.com](https://platform.openai.com)
155-
2. Navigate to **API Keys**
156-
3. Create a new secret key
157-
4. Copy and paste into the extension settings
158-
159-
#### Anthropic
160-
1. Go to [console.anthropic.com](https://console.anthropic.com)
161-
2. Navigate to **API Keys**
162-
3. Create a new key
163-
4. Copy and paste into the extension settings
141+
### Getting Your API Token
164142

165-
#### Google Gemini
166-
1. Go to [aistudio.google.com](https://aistudio.google.com)
167-
2. Navigate to **Get API Key**
168-
3. Create a new key
143+
1. Go to your XTM One instance
144+
2. Navigate to your **Profile → API Keys**
145+
3. Create a new Personal Access Token
169146
4. Copy and paste into the extension settings
170147

171148
### No Enterprise Edition?

docs/development.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,11 @@ src/
7070
│ └── main.tsx # Options entry point
7171
├── shared/ # Shared code
7272
│ ├── api/ # API clients (modular architecture)
73-
│ │ ├── ai-client.ts # AI/LLM provider client
73+
│ │ ├── ai-client.ts # XTM One agent invocation client
7474
│ │ ├── opencti-client.ts # OpenCTI GraphQL client
7575
│ │ ├── openaev-client.ts # OpenAEV REST client
7676
│ │ ├── ai/ # AI modules
77-
│ │ │ ├── prompts.ts # Prompt templates & builders
78-
│ │ │ ├── types.ts # AI types
79-
│ │ │ └── json-parser.ts # Response parsing
77+
│ │ │ └── types.ts # AI types
8078
│ │ ├── opencti/ # OpenCTI modules
8179
│ │ │ ├── queries.ts # GraphQL queries & filters
8280
│ │ │ ├── fragments.ts # GraphQL fragments
@@ -103,7 +101,7 @@ src/
103101
│ ├── theme/ # Theme configuration
104102
│ ├── types/ # TypeScript type definitions
105103
│ │ ├── settings.ts # Platform config, detection settings
106-
│ │ ├── ai.ts # AI provider types, model selection
104+
│ │ ├── ai.ts # AI settings types (XTM One URL, token)
107105
│ │ ├── observables.ts # Observable types (IoCs) and detection
108106
│ │ ├── platform.ts # Cross-platform matching types
109107
│ │ ├── opencti.ts # OpenCTI types (GraphQL, STIX, entities)
@@ -238,13 +236,11 @@ API clients are organized into modular structures for maintainability:
238236

239237
```
240238
src/shared/api/
241-
├── ai-client.ts # Main AI client (imports from ai/)
239+
├── ai-client.ts # XTM One execute-task client
242240
├── opencti-client.ts # Main OpenCTI client (imports from opencti/)
243241
├── openaev-client.ts # Main OpenAEV client (imports from openaev/)
244242
├── ai/
245-
│ ├── prompts.ts # All prompt templates (~560 lines)
246-
│ ├── types.ts # AI type definitions
247-
│ └── json-parser.ts # Response parsing utilities
243+
│ └── types.ts # AI type definitions
248244
├── opencti/
249245
│ ├── queries.ts # GraphQL queries/mutations & filter builders (~350 lines)
250246
│ ├── fragments.ts # Reusable GraphQL fragments
@@ -398,21 +394,27 @@ chrome.runtime.sendMessage({
398394

399395
### Using AI Features
400396

397+
All AI features are routed through XTM One. The extension is a thin client:
398+
401399
```typescript
402400
import { AIClient } from './shared/api/ai-client';
403401

404402
const client = new AIClient({
405-
provider: 'openai',
406-
apiKey: 'sk-...',
407-
model: 'gpt-4o',
403+
xtmOneUrl: 'https://xtm.company.com',
404+
apiToken: 'fcp-...',
408405
});
409406

410-
// Generate description
411-
const description = await client.generateDescription(pageContent);
407+
// Generate description (delegates to XTM One browser-container-description agent)
408+
const result = await client.generateContainerDescription({
409+
pageTitle: 'Threat Report',
410+
pageUrl: 'https://example.com/report',
411+
pageContent: '...',
412+
containerType: 'Report',
413+
containerName: 'My Report',
414+
});
412415

413-
// Fetch available models
414-
const models = await client.fetchModels();
415-
// Returns: [{ id: 'gpt-4o', name: 'GPT-4o' }, ...]
416+
// Test connection
417+
const status = await client.testConnection();
416418
```
417419

418420
## Message Passing
@@ -457,7 +459,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
457459
| `AI_GENERATE_EMAILS` | Panel → Background | Generate email content for table-top scenarios |
458460
| `AI_GENERATE_ATOMIC_TEST` | Panel → Background | Generate atomic test payload |
459461
| `AI_DISCOVER_ENTITIES` | Panel → Background | Discover entities using AI |
460-
| `AI_TEST_AND_FETCH_MODELS` | Options → Background | Test AI key & fetch models |
462+
| `AI_TEST_CONNECTION` | Options → Background | Test XTM One connection |
461463

462464
## Contributing
463465

docs/features.md

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -280,22 +280,19 @@ AI-powered features require at least one Enterprise Edition platform. If not con
280280
- Configure AI in Settings (if you have EE)
281281
- Start a free 30-day trial (if you don't have EE)
282282

283-
### Supported LLM Providers
284-
285-
| Provider | Description | Model Selection |
286-
|----------|-------------|-----------------|
287-
| **OpenAI** | GPT-4, GPT-4 Turbo, GPT-4o models | ✅ Dynamic model list |
288-
| **Anthropic** | Claude 3.5 Sonnet, Claude 3 Opus | ✅ Dynamic model list |
289-
| **Google Gemini** | Gemini 1.5 Pro and Flash | ✅ Dynamic model list |
290-
| **XTM One** | Filigran Agentic AI Platform (coming soon) | - |
291-
292-
### Model Selection
293-
294-
After configuring your API key, you can:
295-
1. Click **Test Connection** to validate the API key
296-
2. The extension fetches available models from the provider
297-
3. Select your preferred model from the dropdown
298-
4. Models are cached for future sessions
283+
### XTM One (AI Backend)
284+
285+
All AI features are powered by XTM One — no direct LLM provider configuration needed.
286+
287+
| Setting | Description |
288+
|---------|-------------|
289+
| **XTM One URL** | Base URL of your XTM One instance |
290+
| **API Token** | Personal Access Token (starts with `fcp-`) |
291+
292+
### Connection Test
293+
294+
1. Click **Test Connection** to validate your XTM One credentials
295+
2. AI features become available once connected
299296

300297
### AI Container Description (OpenCTI)
301298
When creating containers in OpenCTI, you can use AI to generate intelligent descriptions:

0 commit comments

Comments
 (0)