Files
charybdis/docs/PLUGIN_CONFIGURATION_GUIDE.md
T
2026-05-12 17:06:43 +02:00

1010 lines
28 KiB
Markdown

# Charybdis Plugin Configuration Guide
Complete reference for configuring and using the Charybdis plugin system.
## Table of Contents
1. [Overview](#overview)
2. [Plugin System Architecture](#plugin-system-architecture)
3. [Configuration File Structure](#configuration-file-structure)
4. [Field Mapping System](#field-mapping-system)
5. [Entity Resolution](#entity-resolution)
6. [Plugin Configuration Reference](#plugin-configuration-reference)
7. [Environment Variables](#environment-variables)
8. [Best Practices](#best-practices)
9. [Troubleshooting](#troubleshooting)
10. [Examples](#examples)
## Overview
Charybdis plugins extend the core platform with integrations to external tools and services. Plugins react to entity lifecycle events (Create, Update, Delete) and automatically provision or sync resources in external systems.
### Plugin Types
**Event-Driven Plugins** (Current Implementation):
- React to entity lifecycle events
- Push data to external systems
- One-way sync: Charybdis → External Tool
**Sync Plugins** (Future):
- Pull data from external systems on schedule
- Create/update entities in Charybdis
- One-way sync: External Tool → Charybdis
## Plugin System Architecture
```
┌─────────────────────────────────────────┐
│ Charybdis Core │
│ ┌────────────────────────────────┐ │
│ │ Entity Repository │ │
│ │ (PostgreSQL) │ │
│ └──────────┬─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────┐ │
│ │ Event Bus │ │
│ │ (In-Memory / Future: Redis) │ │
│ └──────────┬─────────────────────┘ │
│ │ EntityEvent │
│ │ (Created/Updated/Deleted) │
└─────────────┼────────────────────────────┘
┌─────────────────────────────────────────┐
│ Event Dispatcher │
│ (Routes events to plugins) │
└──────────┬──────────────────────────────┘
├─────────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ DefectDojo │ │ Future Plugins │
│ Plugin │ │ (DependencyTrack)│
│ │ │ │
│ ┌──────────────┐ │ └──────────────────┘
│ │ProductHandler│ │
│ │UserHandler │ │
│ │... │ │
│ └──────────────┘ │
└─────────┬────────┘
│ HTTP/REST
┌──────────────────┐
│ External Tool │
│ (DefectDojo) │
└──────────────────┘
```
### Key Components
1. **Plugin**: Top-level plugin interface
2. **ResourceHandler**: Handles specific resource types (e.g., Products, Users)
3. **FieldMapper**: Maps Charybdis entity fields to external tool fields
4. **Event Dispatcher**: Routes entity events to appropriate handlers
5. **Plugin Manager**: Manages plugin lifecycle and registration
## Configuration File Structure
Plugin configuration lives in your main `config.toml` file under the `[plugins.<plugin_name>]` section.
### Basic Structure
```toml
[plugins.<plugin_name>]
enabled = true # Enable/disable plugin
base_url = "${API_URL}" # External tool API URL
api_token = "${API_TOKEN}" # Authentication token
<plugin_specific_options> # Plugin-specific settings
[plugins.<plugin_name>.field_mappings.<resource_type>]
<field_name> = <mapping> # Field mappings per resource type
```
### Configuration Sections
#### 1. Plugin Enable/Disable
```toml
[plugins.defectdojo]
enabled = true # or false to disable
```
When disabled, the plugin:
- Will NOT be compiled into the binary
- Will NOT react to entity events
- Will NOT appear in plugin registry
#### 2. Connection Settings
```toml
[plugins.defectdojo]
base_url = "${DEFECTDOJO_URL}"
api_token = "${DEFECTDOJO_API_TOKEN}"
```
**Security Best Practice**: Always use environment variables for sensitive data (tokens, passwords, secrets).
#### 3. Plugin-Specific Options
Each plugin may have unique configuration options:
```toml
[plugins.defectdojo]
default_product_type_id = 1 # Default product type for new products
auto_create_users = true # Auto-create missing users
auto_create_product_types = false # Require manual product type creation
```
#### 4. Field Mappings
Field mappings define how Charybdis entity fields map to external tool API fields.
```toml
[plugins.defectdojo.field_mappings.product]
name = "metadata.name" # Direct field mapping
description = "metadata.description" # Direct field mapping
business_criticality = { value = "high" } # Static value
tags = "metadata.tags" # Array mapping
```
## Field Mapping System
### Mapping Types
The field mapping system supports three types of mappings:
#### 1. Direct Field Mapping (String)
Maps a field from the Charybdis entity using dot notation:
```toml
name = "metadata.name"
description = "metadata.description"
email = "spec.profile.email"
tags = "metadata.tags"
```
**Syntax**: `"<path.to.field>"`
**Examples**:
- `"metadata.name"``entity.metadata.name`
- `"spec.owner"``entity.spec.owner`
- `"metadata.annotations.version"``entity.metadata.annotations["version"]`
#### 2. Static Value Mapping (Object with `value` key)
Provides a static value regardless of entity content:
```toml
business_criticality = { value = "high" }
platform = { value = "web" }
is_active = { value = true }
priority = { value = 100 }
lifecycle = { value = "production" }
```
**Syntax**: `{ value = <any_json_value> }`
**Supported Types**:
- String: `{ value = "text" }`
- Boolean: `{ value = true }`
- Number: `{ value = 42 }`
- Object: `{ value = { key = "value" } }`
- Array: `{ value = ["item1", "item2"] }`
#### 3. Complex Mapping with Entity Resolution (Object)
Resolves entity references and extracts data from related entities:
```toml
product_manager = {
from = "spec.owner",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
```
**Syntax**:
```toml
<field> = {
from = "<source_field>", # Source field path
resolve_entity = "<entity_kind>", # Entity kind to resolve to
extract = "<field_to_extract>", # Field to extract from resolved entity
resolve_array = <true|false>, # Optional: resolve array of entities
lookup_entity = "<entity_kind>" # Optional: lookup linked entity
}
```
**Parameters**:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `from` | string | ✓ | Source field path in dot notation |
| `resolve_entity` | string | ✓ | Entity kind to resolve (User, Component, etc.) |
| `extract` | string | ✓ | Field path to extract from resolved entity |
| `resolve_array` | boolean | ✗ | Set to true if `from` contains array of entity IDs |
| `lookup_entity` | string | ✗ | Find linked entity by source ID |
## Entity Resolution
Entity resolution is the most powerful feature of the field mapping system. It allows plugins to navigate entity relationships and extract data from related entities.
### How Entity Resolution Works
```
1. Start with source entity (e.g., Component)
entity.spec.owner = "user:john.doe"
2. Extract source value
from = "spec.owner" → "user:john.doe"
3. Resolve entity reference
resolve_entity = "User" → Query for User entity with id "john.doe"
4. Extract target field
extract = "annotations.defectdojo.com/user-id" → "123"
5. Result
product_manager = 123
```
### Single Entity Resolution
Resolve one entity reference:
```toml
[plugins.defectdojo.field_mappings.product]
product_manager = {
from = "spec.owner", # Component.spec.owner = "user:john.doe"
resolve_entity = "User", # Find User entity
extract = "annotations.defectdojo.com/user-id" # Get DD user ID → "123"
}
```
### Array Entity Resolution
Resolve multiple entity references:
```toml
[plugins.defectdojo.field_mappings.product_member]
user_ids = {
from = "spec.members", # Group.spec.members = ["user:john", "user:jane"]
resolve_entity = "User", # Find each User entity
extract = "annotations.defectdojo.com/user-id", # Get DD user ID for each
resolve_array = true # Process as array
}
```
**Result**: `user_ids = [123, 124]`
### Linked Entity Lookup
Find an entity linked to the source entity:
```toml
engagement_product = {
from = "id", # Start with engagement entity ID
lookup_entity = "Component", # Find Component where...
extract = "annotations.defectdojo.com/product-id" # Component links to this engagement
}
```
This searches for a Component entity that references the source entity.
### Nested Entity Resolution
Chain multiple resolutions:
```toml
team_lead_email = {
from = "spec.owner", # Component.spec.owner = "group:platform-team"
resolve_entity = "Group", # Find Group entity
extract = "spec.parent" # Get parent = "user:tech-lead"
}
# Then in a second mapping:
lead_id = {
from = "spec.parent", # From previous resolution
resolve_entity = "User", # Find User entity
extract = "annotations.defectdojo.com/user-id"
}
```
### Entity Resolution Error Handling
The field mapper handles errors gracefully:
- **Entity not found**: Logs warning, field is omitted
- **Annotation missing**: Logs warning, field is omitted
- **Invalid entity reference**: Logs warning, field is omitted
- **Array with missing entities**: Logs warning, includes found entities only
**In `map_all()` mode**: Failed field mappings log warnings but don't fail entire operation.
## Plugin Configuration Reference
### DefectDojo Plugin
Complete configuration reference for the DefectDojo plugin.
#### Connection Settings
```toml
[plugins.defectdojo]
enabled = true
base_url = "${DEFECTDOJO_URL}"
api_token = "${DEFECTDOJO_API_TOKEN}"
```
#### Plugin Options
```toml
[plugins.defectdojo]
# Default product type ID for new products (required if not mapped)
default_product_type_id = 1
# Automatically create users in DefectDojo when referenced
# If false, referenced users must exist in DefectDojo
auto_create_users = true
# Automatically create product types in DefectDojo
# If false, product types must be created manually
auto_create_product_types = false
```
#### Resource Type: Product
Maps **Component** entities to DefectDojo Products.
```toml
[plugins.defectdojo.field_mappings.product]
# Required fields
name = "metadata.name" # Product name
description = "metadata.description" # Product description
product_type_id = { value = 1 } # Product type ID
# Optional fields
tags = "metadata.tags" # Product tags (array)
business_criticality = { value = "high" } # very high, high, medium, low, very low, none
platform = { value = "web" } # web, mobile, desktop, iot, etc.
lifecycle = { value = "production" } # production, development, retirement
origin = { value = "internal" } # internal, external, third party
user_records = { value = 1000000 } # Number of user records
revenue = { value = "1000000" } # Revenue amount
external_audience = { value = true } # Accessible to external users
internet_accessible = { value = true } # Accessible via internet
# User references (with entity resolution)
product_manager = {
from = "spec.owner",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
technical_contact = {
from = "metadata.annotations.technical-contact",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
team_manager = {
from = "metadata.annotations.team-manager",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
```
#### Resource Type: User
Maps **User** entities to DefectDojo Users.
```toml
[plugins.defectdojo.field_mappings.user]
# Required fields
username = "metadata.name" # Username (unique)
email = "spec.profile.email" # Email address (unique)
# Optional fields
first_name = "spec.profile.displayName" # First name
last_name = "spec.profile.displayName" # Last name (can use same field)
is_active = { value = true } # User active status
```
#### Resource Type: Product Type
Maps **System** entities to DefectDojo Product Types.
```toml
[plugins.defectdojo.field_mappings.product_type]
# Required fields
name = "metadata.name" # Product type name
# Optional fields
description = "metadata.description" # Product type description
critical_product = { value = false } # Requires extra review
key_product = { value = true } # Important but not critical
```
#### Resource Type: Product Member
Maps **Group** entities to DefectDojo Product Members (user-product-role assignments).
**Note**: Only Group entities with specific structure are processed.
```toml
[plugins.defectdojo.field_mappings.product_member]
# Product reference (resolve from Group parent)
product_id = {
from = "spec.parent", # Group.spec.parent = "component:my-service"
resolve_entity = "Component", # Find Component entity
extract = "annotations.defectdojo.com/product-id" # Get DD product ID
}
# User reference (resolve from Group members)
user_id = {
from = "spec.members", # Group.spec.members = ["user:john", "user:jane"]
resolve_entity = "User", # Find User entities
extract = "annotations.defectdojo.com/user-id", # Get DD user IDs
resolve_array = true # Process as array
}
# Role assignment
role_name = { value = "Reader" } # Owner, Maintainer, Reader, Writer, API_Importer
```
**DefectDojo Roles**:
- **Owner**: Full control over product
- **Maintainer**: Can modify product settings
- **Writer**: Can add findings and tests
- **Reader**: Read-only access
- **API_Importer**: Can import findings via API
#### Resource Type: Engagement
Maps **Resource** entities to DefectDojo Engagements (security assessments).
```toml
[plugins.defectdojo.field_mappings.engagement]
# Required fields
name = "metadata.name" # Engagement name
description = "metadata.description" # Engagement description
# Product reference
product_id = {
from = "spec.owner", # Resource.spec.owner = "component:my-service"
resolve_entity = "Component", # Find Component entity
extract = "annotations.defectdojo.com/product-id"
}
# Date fields (ISO 8601 format: YYYY-MM-DD)
target_start = "spec.target_start" # Start date
target_end = "spec.target_end" # End date
# Optional fields
status = { value = "In Progress" } # Not Started, In Progress, Completed, Cancelled
engagement_type = { value = "CI/CD" } # Interactive, CI/CD, etc.
# Lead user reference
lead_id = {
from = "spec.dependsOn", # Resource.spec.dependsOn = ["user:lead"]
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
# Version control fields
version = "metadata.annotations.version"
commit_hash = "metadata.annotations.commit_hash"
branch_tag = "metadata.annotations.branch"
build_id = "metadata.annotations.build_id"
source_code_management_uri = "metadata.annotations.repo_url"
# Test type flags
deduplication_on_engagement = { value = true }
threat_model = { value = false }
api_test = { value = true }
pen_test = { value = false }
check_list = { value = false }
```
## Environment Variables
### Required Variables
```bash
# DefectDojo Plugin
export DEFECTDOJO_URL="https://defectdojo.example.com"
export DEFECTDOJO_API_TOKEN="your-api-token-here"
# Database
export DATABASE_URL="postgresql://user:pass@localhost/charybdis"
# Optional: Telemetry
export OTLP_ENDPOINT="http://localhost:4317"
```
### Obtaining DefectDojo API Token
1. Log into DefectDojo UI
2. Go to **User Profile****API Key**
3. Click **Generate** or copy existing key
4. Set environment variable: `export DEFECTDOJO_API_TOKEN="<token>"`
### Security Considerations
**Never commit secrets to git**:
- ✓ Use environment variables for tokens/passwords
- ✓ Add `.env` to `.gitignore`
- ✓ Use secret management (HashiCorp Vault, AWS Secrets Manager)
- ✗ Don't hardcode secrets in `config.toml`
## Best Practices
### 1. Field Mapping Design
**Start Simple**:
```toml
# Start with required fields only
name = "metadata.name"
description = "metadata.description"
```
**Add Optional Fields Gradually**:
```toml
# Add optional fields as needed
tags = "metadata.tags"
business_criticality = { value = "medium" }
```
**Use Entity Resolution Last**:
```toml
# Complex mappings last (requires other entities to exist)
product_manager = {
from = "spec.owner",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
```
### 2. Entity Creation Order
For entity resolution to work, create entities in this order:
1. **Users** (no dependencies)
2. **Product Types** (no dependencies)
3. **Components** (may reference Users)
4. **Groups** (references Components and Users)
5. **Resources/Engagements** (references Components and Users)
### 3. Testing Strategy
**Test in Isolation**:
1. Create a test Component without references
2. Verify Product created in DefectDojo
3. Check annotation added: `defectdojo.com/product-id`
**Test with References**:
1. Create User entity
2. Wait for DefectDojo sync
3. Create Component with `spec.owner = "user:john.doe"`
4. Verify product_manager set correctly in DefectDojo
**Test Updates**:
1. Update Component name
2. Verify Product name updated in DefectDojo
**Test Deletes**:
1. Delete Component
2. Verify Product deleted in DefectDojo
### 4. Error Handling
**Check Logs**: Plugin operations are logged with `tracing`:
```
INFO DefectDojo plugin: Creating DefectDojo product for entity: component-123
INFO DefectDojo plugin: Created DefectDojo product 456 for entity component-123
WARN DefectDojo plugin: Entity component-789 has no DefectDojo product ID, skipping deletion
ERROR DefectDojo plugin: Failed to create product: API error 400: Invalid product type ID
```
**Log Levels**:
- `INFO`: Normal operations
- `WARN`: Non-critical issues (missing annotations, skipped operations)
- `ERROR`: Critical failures (API errors, invalid configuration)
### 5. Performance Optimization
**Minimize Entity Resolution**:
- Cache resolved IDs when possible
- Use static values when appropriate
- Avoid deep resolution chains
**Batch Operations**:
- Create multiple entities in succession
- Plugin handles each independently
- No manual batching needed
### 6. Configuration Management
**Use Configuration Profiles**:
```toml
# config.development.toml
[plugins.defectdojo]
base_url = "https://defectdojo-dev.example.com"
auto_create_users = true
# config.production.toml
[plugins.defectdojo]
base_url = "https://defectdojo.example.com"
auto_create_users = false # Require manual user creation
```
**Environment-Specific Settings**:
```bash
# Development
export CONFIG_FILE="config.development.toml"
# Production
export CONFIG_FILE="config.production.toml"
```
## Troubleshooting
### Plugin Not Reacting to Events
**Check**:
1. Plugin enabled: `plugins.defectdojo.enabled = true`
2. Plugin compiled: Run `cargo build`
3. Entity kind matches trigger: Component → product handler
4. Event bus running: Check logs for event publications
### Field Mapping Not Working
**Check**:
1. Field path correct: `"metadata.name"` not `"meta.name"`
2. Field exists in entity: Use YAML adapter to inspect entity
3. Static value syntax: `{ value = "text" }` not `"text"`
4. Entity resolution: Resolved entity exists and has required annotation
### Entity Resolution Fails
**Check**:
1. Referenced entity exists: `user:john.doe` exists in database
2. Referenced entity has annotation: `defectdojo.com/user-id` present
3. Entity kind correct: `resolve_entity = "User"` not `"user"`
4. Array syntax: `resolve_array = true` for array fields
### API Errors
**Common Errors**:
```
400 Bad Request: Invalid product type ID
→ Check default_product_type_id or product_type_id mapping
401 Unauthorized: Invalid token
→ Check DEFECTDOJO_API_TOKEN is correct
404 Not Found: Product not found
→ Entity may not have been created yet
409 Conflict: User already exists
→ Normal for users (plugin detects and reuses)
```
### Missing Annotations
If annotations not created:
1. Check entity update succeeded: `repository.update()` logs
2. Verify annotation key: `defectdojo.com/product-id`
3. Check database: `SELECT annotations FROM entities WHERE id = '...'`
### Performance Issues
If plugin causing slowness:
1. Check DefectDojo API response times
2. Reduce entity resolution depth
3. Use static values where possible
4. Check network connectivity to DefectDojo
## Examples
### Example 1: Basic Product Creation
**Entity** (Component):
```yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
description: Payment processing microservice
tags:
- payment
- critical
- pci-dss
spec:
type: service
lifecycle: production
owner: platform-team
```
**Configuration**:
```toml
[plugins.defectdojo.field_mappings.product]
name = "metadata.name"
description = "metadata.description"
tags = "metadata.tags"
product_type_id = { value = 1 }
business_criticality = { value = "very high" }
platform = { value = "web" }
lifecycle = "spec.lifecycle"
```
**Result in DefectDojo**:
```json
{
"id": 456,
"name": "payment-service",
"description": "Payment processing microservice",
"tags": ["payment", "critical", "pci-dss"],
"prod_type": 1,
"business_criticality": "very high",
"platform": "web",
"lifecycle": "production"
}
```
**Updated Entity**:
```yaml
metadata:
annotations:
defectdojo.com/product-id: "456"
```
### Example 2: Product with User References
**Entities**:
User:
```yaml
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
name: john.doe
spec:
profile:
displayName: John Doe
email: john.doe@example.com
memberOf:
- platform-team
```
Component:
```yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
annotations:
technical-contact: user:jane.smith
spec:
owner: user:john.doe
```
**Configuration**:
```toml
[plugins.defectdojo.field_mappings.product]
name = "metadata.name"
product_type_id = { value = 1 }
product_manager = {
from = "spec.owner",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
technical_contact = {
from = "metadata.annotations.technical-contact",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
```
**Resolution Process**:
1. Component created → Product handler triggered
2. Field mapper resolves `spec.owner = "user:john.doe"`
3. Queries for User entity with id "john.doe"
4. Extracts `annotations.defectdojo.com/user-id = "123"`
5. Sets `product_manager: 123` in API call
### Example 3: Product Member Assignment
**Entities**:
Component (already has DD product ID):
```yaml
metadata:
annotations:
defectdojo.com/product-id: "456"
```
Users (already have DD user IDs):
```yaml
# john.doe
metadata:
annotations:
defectdojo.com/user-id: "123"
# jane.smith
metadata:
annotations:
defectdojo.com/user-id: "124"
```
Group:
```yaml
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
name: payment-service-security-team
spec:
type: team
parent: component:payment-service
members:
- user:john.doe
- user:jane.smith
```
**Configuration**:
```toml
[plugins.defectdojo.field_mappings.product_member]
product_id = {
from = "spec.parent",
resolve_entity = "Component",
extract = "annotations.defectdojo.com/product-id"
}
user_id = {
from = "spec.members",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id",
resolve_array = true
}
role_name = { value = "Reader" }
```
**Result**:
- Creates Product Member: Product 456 + User 123 + Role "Reader"
- Creates Product Member: Product 456 + User 124 + Role "Reader"
### Example 4: Engagement with Full Metadata
**Entity**:
```yaml
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: payment-service-q1-2025-assessment
description: Q1 2025 Security Assessment
annotations:
version: "2.3.0"
commit_hash: "abc123def456"
branch: "release/2.3"
build_id: "build-789"
repo_url: "https://github.com/example/payment-service"
spec:
type: security-assessment
owner: component:payment-service
dependsOn:
- user:security-lead
target_start: "2025-01-01"
target_end: "2025-03-31"
```
**Configuration**:
```toml
[plugins.defectdojo.field_mappings.engagement]
name = "metadata.name"
description = "metadata.description"
product_id = {
from = "spec.owner",
resolve_entity = "Component",
extract = "annotations.defectdojo.com/product-id"
}
lead_id = {
from = "spec.dependsOn",
resolve_entity = "User",
extract = "annotations.defectdojo.com/user-id"
}
target_start = "spec.target_start"
target_end = "spec.target_end"
version = "metadata.annotations.version"
commit_hash = "metadata.annotations.commit_hash"
branch_tag = "metadata.annotations.branch"
build_id = "metadata.annotations.build_id"
source_code_management_uri = "metadata.annotations.repo_url"
status = { value = "In Progress" }
engagement_type = { value = "CI/CD" }
deduplication_on_engagement = { value = true }
api_test = { value = true }
pen_test = { value = false }
```
**Result in DefectDojo**:
```json
{
"id": 789,
"name": "payment-service-q1-2025-assessment",
"description": "Q1 2025 Security Assessment",
"product": 456,
"lead": 123,
"target_start": "2025-01-01",
"target_end": "2025-03-31",
"version": "2.3.0",
"commit_hash": "abc123def456",
"branch_tag": "release/2.3",
"build_id": "build-789",
"source_code_management_uri": "https://github.com/example/payment-service",
"status": "In Progress",
"engagement_type": "CI/CD",
"deduplication_on_engagement": true,
"api_test": true,
"pen_test": false
}
```
## Advanced Topics
### Custom Field Mapping Logic
For complex scenarios not covered by built-in mapping types, implement custom resource handlers.
### Plugin Development
See `docs/PLUGIN_DEVELOPMENT_GUIDE.md` (future) for creating new plugins.
### Entity Resolution Performance
Entity resolution requires database queries. For high-throughput scenarios:
- Use static values where possible
- Cache resolved IDs in memory
- Consider implementing a resolution cache layer
### Multi-Environment Configuration
```bash
# Development
cargo run -- --config config.development.toml
# Staging
cargo run -- --config config.staging.toml
# Production
cargo run -- --config config.production.toml
```
## Related Documentation
- [DefectDojo Plugin README](../plugins/defectdojo/README.md)
- [Plugin Implementation Guide](./DEFECTDOJO_PLUGIN_IMPLEMENTATION.md)
- [Charybdis Architecture](architecture.md)
- [Field Mapper Tests](../src/plugins/field_mapper.rs#tests)
## Support
For issues or questions:
1. Check this documentation
2. Review plugin logs
3. Test with minimal configuration
4. Open issue on GitHub with:
- Configuration (sanitized)
- Entity YAML
- Error logs
- Expected vs actual behavior