Public Access
302 lines
8.1 KiB
Markdown
302 lines
8.1 KiB
Markdown
# DefectDojo Plugin for Charybdis
|
|
|
|
Event-driven plugin that synchronizes Charybdis entities with DefectDojo security testing platform.
|
|
|
|
## Overview
|
|
|
|
The DefectDojo plugin automatically provisions and manages resources in DefectDojo based on entity lifecycle events in Charybdis. It provides bidirectional mapping between Charybdis entities and DefectDojo resources.
|
|
|
|
## Supported Resources
|
|
|
|
| Charybdis Entity | DefectDojo Resource | Trigger |
|
|
|-----------------|---------------------|---------|
|
|
| Component | Product | Create/Update/Delete Component |
|
|
| User | User | Create/Update/Delete User |
|
|
| System | Product Type | Create/Update/Delete System |
|
|
| Group | Product Member | Create/Update/Delete Group with annotation |
|
|
| Resource | Engagement | Create/Update/Delete Resource with annotation |
|
|
|
|
## Configuration
|
|
|
|
Add the DefectDojo plugin configuration to your `config.toml`:
|
|
|
|
```toml
|
|
[plugins.defectdojo]
|
|
enabled = true
|
|
base_url = "${DEFECTDOJO_URL}"
|
|
api_token = "${DEFECTDOJO_API_TOKEN}"
|
|
default_product_type_id = 1
|
|
auto_create_users = true
|
|
auto_create_product_types = false
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
- `DEFECTDOJO_URL`: Base URL of your DefectDojo instance (e.g., `https://defectdojo.example.com`)
|
|
- `DEFECTDOJO_API_TOKEN`: API token for authentication
|
|
|
|
### Field Mappings
|
|
|
|
Define how Charybdis entity fields map to DefectDojo API fields:
|
|
|
|
```toml
|
|
[plugins.defectdojo.field_mappings.product]
|
|
name = "metadata.name"
|
|
description = "metadata.description"
|
|
business_criticality = { value = "high" }
|
|
product_type_id = { value = 1 }
|
|
```
|
|
|
|
#### Mapping Types
|
|
|
|
1. **Direct field mapping**: `"metadata.name"` - Extract field from entity
|
|
2. **Static value**: `{ value = "high" }` - Use static value
|
|
3. **Entity resolution**: Resolve entity references
|
|
```toml
|
|
product_manager = {
|
|
from = "spec.owner",
|
|
resolve_entity = "User",
|
|
extract = "annotations.defectdojo.com/user-id"
|
|
}
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### 1. Create a Product from Component
|
|
|
|
```yaml
|
|
apiVersion: backstage.io/v1alpha1
|
|
kind: Component
|
|
metadata:
|
|
name: payment-service
|
|
description: Payment processing service
|
|
tags:
|
|
- payment
|
|
- critical
|
|
spec:
|
|
type: service
|
|
lifecycle: production
|
|
owner: platform-team
|
|
```
|
|
|
|
When this Component is created in Charybdis, the plugin automatically:
|
|
1. Creates a Product in DefectDojo
|
|
2. Stores the DefectDojo product ID in annotations: `defectdojo.com/product-id`
|
|
|
|
### 2. Create Users
|
|
|
|
```yaml
|
|
apiVersion: backstage.io/v1alpha1
|
|
kind: User
|
|
metadata:
|
|
name: john.doe
|
|
spec:
|
|
profile:
|
|
displayName: John Doe
|
|
email: john.doe@example.com
|
|
memberOf:
|
|
- platform-team
|
|
```
|
|
|
|
The plugin creates a DefectDojo user and stores the user ID in annotations.
|
|
|
|
### 3. Add Product Members
|
|
|
|
Create a Group entity with a special annotation to trigger product member creation:
|
|
|
|
```yaml
|
|
apiVersion: backstage.io/v1alpha1
|
|
kind: Group
|
|
metadata:
|
|
name: payment-service-security-team
|
|
annotations:
|
|
defectdojo.com/product-member: "true"
|
|
spec:
|
|
type: team
|
|
parent: component:payment-service # Reference to Component
|
|
members:
|
|
- user:john.doe
|
|
- user:jane.smith
|
|
```
|
|
|
|
The plugin resolves:
|
|
- `parent` → Component → DefectDojo Product ID
|
|
- `members` → Users → DefectDojo User IDs
|
|
- Creates Product Member entries with specified role
|
|
|
|
### 4. Create Engagements
|
|
|
|
```yaml
|
|
apiVersion: backstage.io/v1alpha1
|
|
kind: Resource
|
|
metadata:
|
|
name: payment-service-q1-security-assessment
|
|
annotations:
|
|
defectdojo.com/engagement: "true"
|
|
version: "2.1.0"
|
|
commit_hash: "abc123"
|
|
spec:
|
|
type: security-assessment
|
|
owner: component:payment-service
|
|
dependsOn:
|
|
- user:john.doe # Lead
|
|
target_start: "2025-01-01"
|
|
target_end: "2025-03-31"
|
|
```
|
|
|
|
## Annotations
|
|
|
|
The plugin uses annotations to:
|
|
|
|
1. **Store DefectDojo IDs** (auto-managed):
|
|
- `defectdojo.com/product-id`
|
|
- `defectdojo.com/user-id`
|
|
- `defectdojo.com/product-type-id`
|
|
- `defectdojo.com/product-member-id`
|
|
- `defectdojo.com/engagement-id`
|
|
|
|
2. **Trigger special behaviors**:
|
|
- `defectdojo.com/product-member: "true"` - Create product members from Group
|
|
- `defectdojo.com/engagement: "true"` - Create engagement from Resource
|
|
|
|
## Entity Resolution
|
|
|
|
The plugin supports complex field mappings that resolve entity references:
|
|
|
|
```toml
|
|
[plugins.defectdojo.field_mappings.product]
|
|
product_manager = {
|
|
from = "spec.owner", # Get owner field from entity
|
|
resolve_entity = "User", # Resolve as User entity
|
|
extract = "annotations.defectdojo.com/user-id" # Extract DD user ID
|
|
}
|
|
```
|
|
|
|
This allows you to reference Users by entity ID in Charybdis, and the plugin automatically resolves to DefectDojo user IDs.
|
|
|
|
### Array Resolution
|
|
|
|
For resolving arrays of entities (like group members):
|
|
|
|
```toml
|
|
user_id = {
|
|
from = "spec.members",
|
|
resolve_entity = "User",
|
|
extract = "annotations.defectdojo.com/user-id",
|
|
resolve_array = true
|
|
}
|
|
```
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ Charybdis │
|
|
│ (gRPC API) │
|
|
└────────┬────────┘
|
|
│ Entity Events
|
|
▼
|
|
┌─────────────────┐
|
|
│ Event Dispatcher│
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────┐
|
|
│ DefectDojo Plugin │
|
|
│ ┌────────────────────────┐ │
|
|
│ │ ProductHandler │ │
|
|
│ │ UserHandler │ │
|
|
│ │ ProductTypeHandler │ │
|
|
│ │ ProductMemberHandler │ │
|
|
│ │ EngagementHandler │ │
|
|
│ └────────────────────────┘ │
|
|
└──────────┬──────────────────┘
|
|
│ HTTP API
|
|
▼
|
|
┌─────────────────┐
|
|
│ DefectDojo │
|
|
│ (REST API) │
|
|
└─────────────────┘
|
|
```
|
|
|
|
## Resource Handlers
|
|
|
|
Each resource handler implements:
|
|
- `handle_create()`: Create resource in DefectDojo when entity created
|
|
- `handle_update()`: Update resource in DefectDojo when entity updated
|
|
- `handle_delete()`: Delete/deactivate resource in DefectDojo when entity deleted
|
|
|
|
## Error Handling
|
|
|
|
- Failed API calls are logged with full error details
|
|
- Entity is still created/updated in Charybdis even if DefectDojo sync fails
|
|
- Missing DefectDojo IDs trigger automatic creation
|
|
- User deletion deactivates users instead of deleting (DefectDojo best practice)
|
|
|
|
## Development
|
|
|
|
### Building
|
|
|
|
```bash
|
|
cargo build
|
|
```
|
|
|
|
### Testing
|
|
|
|
```bash
|
|
cargo test
|
|
```
|
|
|
|
### Adding New Resource Types
|
|
|
|
1. Create new handler in `src/handlers/`
|
|
2. Implement `ResourceHandler` trait
|
|
3. Add handler to plugin in `src/lib.rs`
|
|
4. Define field mappings in config
|
|
|
|
## API Reference
|
|
|
|
### DefectDojo API Endpoints Used
|
|
|
|
- `POST /api/v2/products/` - Create product
|
|
- `PUT /api/v2/products/{id}/` - Update product
|
|
- `DELETE /api/v2/products/{id}/` - Delete product
|
|
- `POST /api/v2/users/` - Create user
|
|
- `PUT /api/v2/users/{id}/` - Update user
|
|
- `POST /api/v2/product_types/` - Create product type
|
|
- `POST /api/v2/product_members/` - Create product member
|
|
- `DELETE /api/v2/product_members/{id}/` - Remove product member
|
|
- `POST /api/v2/engagements/` - Create engagement
|
|
- `PUT /api/v2/engagements/{id}/` - Update engagement
|
|
|
|
## Security
|
|
|
|
- API token should be stored in environment variables, not committed to git
|
|
- Use mTLS for Charybdis gRPC connections
|
|
- DefectDojo HTTPS endpoint recommended for production
|
|
|
|
## Troubleshooting
|
|
|
|
### Entity not syncing to DefectDojo
|
|
|
|
1. Check plugin is enabled in `config.toml`
|
|
2. Verify `DEFECTDOJO_API_TOKEN` is set
|
|
3. Check entity kind matches handler trigger kinds
|
|
4. Review logs for API errors
|
|
|
|
### Missing DefectDojo IDs
|
|
|
|
If annotations are missing:
|
|
- Plugin will attempt to create resource on next update
|
|
- Check for errors in creation logs
|
|
- Verify field mappings provide required fields
|
|
|
|
### User already exists errors
|
|
|
|
- Plugin checks for existing users by email before creating
|
|
- Will reuse existing user ID instead of creating duplicate
|
|
|
|
## License
|
|
|
|
Part of Charybdis project.
|