Public Access
initial-commit
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user