skills/defectdojo/SKILL.md
Guide for implementing DefectDojo - an open-source DevSecOps, ASPM, and vulnerability management platform. Use when querying vulnerabilities, managing findings, configuring CI/CD pipeline imports, or working with security scan data. Includes MCP tools for direct API interaction.
npx skillsauth add julianobarbosa/claude-code-skills defectdojoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
DefectDojo is an open-source DevSecOps, Application Security Posture Management (ASPM), and vulnerability management platform. It orchestrates end-to-end security testing, vulnerability tracking, deduplication, remediation, and reporting.
Key Capabilities:
Official Resources:
This skill provides 12 MCP tools for direct DefectDojo API interaction. Use these tools instead of manual API calls.
| Tool | Description | Key Parameters |
|------|-------------|----------------|
| defectdojo_list_products | List and search products | name_contains, prod_type, limit |
| defectdojo_get_product | Get detailed product info | product_id (required) |
| defectdojo_list_engagements | List engagements with filters | product_id, status, engagement_type |
| defectdojo_list_tests | List tests in engagements | engagement_id, test_type |
| defectdojo_list_findings | Primary tool - Search findings | severity, active, product_id, cwe |
| defectdojo_get_finding | Get finding details | finding_id (required) |
| defectdojo_get_statistics | Vulnerability statistics | product_id, engagement_id |
| defectdojo_list_endpoints | List product endpoints | product_id, host, protocol |
| defectdojo_list_test_types | List scanner types | name_contains |
| Tool | Description | Key Parameters |
|------|-------------|----------------|
| defectdojo_create_engagement | Create new engagement | product_id, name, engagement_type |
| defectdojo_update_finding | Update finding status | finding_id, active, verified, false_p |
| defectdojo_close_engagement | Close engagement | engagement_id |
List all critical active findings:
Use defectdojo_list_findings with:
- severity: "Critical"
- active: true
Get vulnerability statistics for a product:
Use defectdojo_get_statistics with:
- product_id: 1
Search for SQL injection findings:
Use defectdojo_list_findings with:
- cwe: 89
- active: true
Mark a finding as false positive:
Use defectdojo_update_finding with:
- finding_id: 123
- false_p: true
- active: false
Create a CI/CD engagement:
Use defectdojo_create_engagement with:
- product_id: 1
- name: "Pipeline Security Scan"
- engagement_type: "CI/CD"
All tools support two output formats via the response_format parameter:
markdown (default) - Human-readable formatted outputjson - Raw JSON for programmatic processingThe MCP server is configured in .mcp.json:
{
"mcpServers": {
"defectdojo": {
"command": "python",
"args": [".claude/mcp-servers/defectdojo-mcp/defectdojo_mcp.py"],
"env": {
"DEFECTDOJO_URL": "https://defectdojo.dev.cafehyna.com.br",
"DEFECTDOJO_API_TOKEN": "${DEFECTDOJO_API_TOKEN}"
}
}
}
}
Environment Variables:
DEFECTDOJO_URL - Your DefectDojo instance URLDEFECTDOJO_API_TOKEN - API token from /api/key-v2DefectDojo uses five interconnected data classes to organize security work:
Product Type
└── Product
└── Engagement (CI/CD or Interactive)
└── Test
└── Finding
└── Endpoint
The topmost organizational level that categorizes products by business domain, team, or security area. Enables role-based access control at the category level.
Individual applications or systems under security testing. Each product maintains:
Scheduled testing periods containing one or more tests. Two types:
| Type | Purpose | Use Case | |------|---------|----------| | CI/CD | Automated pipeline integration | Automated scans per build/commit | | Interactive | Manual testing by engineers | Penetration tests, manual reviews |
Individual security scans grouped by tool type. Tests support:
Specific vulnerabilities discovered during testing:
| Severity | Description | |----------|-------------| | Critical | Immediate action required | | High | High priority remediation | | Medium | Standard priority | | Low | Low priority | | Info | Informational only |
Finding States:
References to affected hosts, URLs, or systems. Enables vulnerability tracking by infrastructure component.
Note: For most operations, use the MCP Tools above instead of direct API calls. Use direct API calls only for scan imports or operations not covered by MCP tools.
Generate API token at: <your-instance>/api/key-v2
# Header format
Authorization: Token <api_key>
Environment Variables:
DD_API_TOKENS_ENABLED=False - Disable API tokens entirelyDD_API_TOKEN_AUTH_ENDPOINT_ENABLED=False - Disable only token auth endpoint| Endpoint | Method | Purpose |
|----------|--------|---------|
| /api/v2/import-scan/ | POST | Initial scan import |
| /api/v2/reimport-scan/ | POST | Subsequent imports (deduplication) |
| /api/v2/products/ | GET/POST | Manage products |
| /api/v2/engagements/ | GET/POST | Manage engagements |
| /api/v2/tests/ | GET/POST | Manage tests |
| /api/v2/findings/ | GET/POST/PATCH | Manage findings |
| /api/v2/endpoints/ | GET/POST | Manage endpoints |
| /api/v2/users/ | GET | List users |
curl -X POST "https://defectdojo.example.com/api/v2/import-scan/" \
-H "Authorization: Token <api-token>" \
-F "scan_type=<scanner-type>" \
-F "[email protected]" \
-F "engagement=<engagement-id>" \
-F "minimum_severity=Info" \
-F "active=true" \
-F "verified=false" \
-F "scan_date=2024-01-15"
Key Parameters:
| Parameter | Description |
|-----------|-------------|
| scan_type | Scanner identifier (e.g., "Trivy Scan", "Semgrep JSON Report") |
| engagement | Target engagement ID |
| test_title | Custom test name |
| minimum_severity | Filter threshold (Info, Low, Medium, High, Critical) |
| active | Mark findings as active (boolean) |
| verified | Mark findings as verified (boolean) |
| scan_date | Override scan completion date |
| do_not_reactivate | Prevent reopening closed findings |
| auto_create_context | Auto-create Product/Engagement if missing |
curl -X POST "https://defectdojo.example.com/api/v2/reimport-scan/" \
-H "Authorization: Token <api-token>" \
-F "scan_type=Trivy Scan" \
-F "[email protected]" \
-F "test=<test-id>" \
-F "do_not_reactivate=true"
The reimport endpoint:
auto_create_context=trueAccess Swagger UI at: <your-instance>/api/v2/oa3/swagger-ui/
# GitLab CI Example
stages:
- security-scan
- upload-results
trivy-scan:
stage: security-scan
script:
- trivy image --format json -o trivy-results.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
artifacts:
paths:
- trivy-results.json
upload-to-defectdojo:
stage: upload-results
script: |
curl -X POST "${DEFECTDOJO_URL}/api/v2/reimport-scan/" \
-H "Authorization: Token ${DEFECTDOJO_API_TOKEN}" \
-F "scan_type=Trivy Scan" \
-F "[email protected]" \
-F "product_name=${CI_PROJECT_NAME}" \
-F "engagement_name=CI/CD-${CI_PIPELINE_ID}" \
-F "auto_create_context=true" \
-F "minimum_severity=Low"
Install the DefectDojo Jenkins plugin from: https://plugins.jenkins.io/defectdojo/
Pipeline Configuration:
pipeline {
agent any
environment {
DEFECTDOJO_URL = 'https://defectdojo.example.com'
DEFECTDOJO_API_KEY = credentials('defectdojo-api-key')
}
stages {
stage('Security Scan') {
steps {
sh 'trivy image --format json -o trivy.json myapp:latest'
}
}
stage('Upload to DefectDojo') {
steps {
defectDojoPublisher(
artifact: 'trivy.json',
productName: 'MyApp',
scanType: 'Trivy Scan',
engagementName: "Build-${BUILD_NUMBER}"
)
}
}
}
}
name: Security Scan
on: [push]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
format: 'json'
output: 'trivy-results.json'
- name: Upload to DefectDojo
run: |
curl -X POST "${{ secrets.DEFECTDOJO_URL }}/api/v2/reimport-scan/" \
-H "Authorization: Token ${{ secrets.DEFECTDOJO_TOKEN }}" \
-F "scan_type=Trivy Scan" \
-F "[email protected]" \
-F "product_name=${{ github.repository }}" \
-F "engagement_name=GitHub-${{ github.run_id }}" \
-F "auto_create_context=true"
Tip: For Claude Code interactions, use the MCP tools (
defectdojo_list_findings, etc.) instead of writing Python code. The examples below are for CI/CD scripts and external integrations.
import requests
class DefectDojoAPI:
def __init__(self, url, api_token):
self.url = url.rstrip('/')
self.headers = {
'Authorization': f'Token {api_token}',
'Accept': 'application/json'
}
def get_products(self):
response = requests.get(
f'{self.url}/api/v2/products/',
headers=self.headers
)
response.raise_for_status()
return response.json()
def import_scan(self, engagement_id, scan_type, file_path, **kwargs):
with open(file_path, 'rb') as f:
data = {
'engagement': engagement_id,
'scan_type': scan_type,
'minimum_severity': kwargs.get('minimum_severity', 'Info'),
'active': kwargs.get('active', True),
'verified': kwargs.get('verified', False),
}
files = {'file': f}
response = requests.post(
f'{self.url}/api/v2/import-scan/',
headers={'Authorization': self.headers['Authorization']},
data=data,
files=files
)
response.raise_for_status()
return response.json()
# Usage
api = DefectDojoAPI('https://defectdojo.example.com', 'your-api-token')
products = api.get_products()
def create_product(api, name, prod_type_id, description=''):
response = requests.post(
f'{api.url}/api/v2/products/',
headers=api.headers,
json={
'name': name,
'prod_type': prod_type_id,
'description': description
}
)
response.raise_for_status()
return response.json()
def create_engagement(api, product_id, name, target_start, target_end,
engagement_type='CI/CD'):
response = requests.post(
f'{api.url}/api/v2/engagements/',
headers=api.headers,
json={
'name': name,
'product': product_id,
'target_start': target_start,
'target_end': target_end,
'engagement_type': engagement_type,
'status': 'In Progress'
}
)
response.raise_for_status()
return response.json()
def get_findings(api, product_id=None, severity=None, active=True):
params = {'active': active}
if product_id:
params['test__engagement__product'] = product_id
if severity:
params['severity'] = severity
response = requests.get(
f'{api.url}/api/v2/findings/',
headers=api.headers,
params=params
)
response.raise_for_status()
return response.json()
# Get all critical findings
critical = get_findings(api, severity='Critical')
Full list: https://docs.defectdojo.com/supported_tools/
Enable in System Settings:
Configuration > System Settings > Enable JIRA Integration
Add JIRA Instance:
Enterprise Settings > JIRA Instances > + New JIRA Instance
Configure Webhook (bidirectional sync):
https://<defectdojo>/jira/webhook/<webhook-secret>extraEnv:
- name: DD_JIRA_URL
value: "https://your-jira.atlassian.net"
- name: DD_JIRA_MAX_RETRIES
value: "3"
| File Type | Path |
|-----------|------|
| ApplicationSet | infra-team/applicationset/defectdojo.yaml |
| Helm Values | argo-cd-helm-values/kube-addons/defectdojo/<cluster>/values.yaml |
| SecretProviderClass | argo-cd-helm-values/kube-addons/defectdojo/<cluster>/secretproviderclass.yaml |
| Cluster | Key Vault | Azure AD Tenant ID |
|---------|-----------|-------------------|
| cafehyna-dev | kv-cafehyna-dev-hlg | 3f7a3df4-f85b-4ca8-98d0-08b1034e6567 |
| Setting | Value |
|---------|-------|
| Application (Client) ID | 79ada8c7-4270-41e8-9ea0-1e1e62afff3d |
| Tenant ID | 3f7a3df4-f85b-4ca8-98d0-08b1034e6567 |
| Redirect URI | https://defectdojo.dev.cafehyna.com.br/complete/azuread-tenant-oauth2/ |
extraEnv:
# Enable Azure AD OAuth2
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_ENABLED
value: "True"
# Application (Client) ID
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY
value: "<client-id>"
# Directory (Tenant) ID
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID
value: "<tenant-id>"
# Client Secret (from Key Vault)
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET
valueFrom:
secretKeyRef:
name: defectdojo
key: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET
extraEnv:
# Sync groups from Azure AD token
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_GET_GROUPS
value: "True"
# Remove users from groups when removed in Azure AD
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_CLEANUP_GROUPS
value: "True"
# Filter to only sync DefectDojo groups
- name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_GROUPS_FILTER
value: "^G-Usuarios-DefectDojo-.*"
Required Azure AD Permissions (Application type, Admin consent required):
Group.Read.AllGroupMember.Read.AllUser.Read.AllFor complete Azure AD SSO details, see references/azure-ad-sso.md.
| Role | Permissions | |------|-------------| | Superuser | Full system access, manage users, system settings | | Owner | Delete products, designate other owners | | Maintainer | Edit products, add members, delete findings | | Writer | Add/edit engagements, tests, findings | | Reader | View-only, add comments | | API Importer | Limited API access for CI/CD pipelines |
| Azure AD Group | DefectDojo Role |
|----------------|-----------------|
| G-Usuarios-DefectDojo-Superuser | Superuser |
| G-Usuarios-DefectDojo-Owner | Owner |
| G-Usuarios-DefectDojo-Maintainer | Maintainer |
| G-Usuarios-DefectDojo-Writer | Writer |
| G-Usuarios-DefectDojo-Reader | Reader |
# Host configuration
host: defectdojo.dev.cafehyna.com.br
siteUrl: https://defectdojo.dev.cafehyna.com.br
# Secrets (use CSI driver)
createSecret: false
disableHooks: true
# Django
django:
replicas: 1
ingress:
enabled: true
activateTLS: true
className: nginx
# Celery (keep beat at 1 replica)
celery:
beat:
enabled: true
replicas: 1
worker:
enabled: true
replicas: 1
# Database
postgresql:
enabled: true
# Cache
redis:
enabled: true
For complete Helm values reference, see references/helm-values.md.
git clone https://github.com/DefectDojo/django-DefectDojo
cd django-DefectDojo
helm install defectdojo ./helm/defectdojo \
-n defectdojo --create-namespace \
--set django.ingress.enabled=true \
--set django.ingress.activateTLS=false \
--set createSecret=true \
--set createRabbitMqSecret=true \
--set createPostgresqlSecret=true
kubectl port-forward --namespace=defectdojo service/defectdojo-django 8080:80
Secrets are managed via Azure Key Vault CSI Driver:
| Key Vault Secret | K8s Secret Key | Purpose |
|------------------|----------------|---------|
| defectdojo-admin-password | DD_ADMIN_PASSWORD | Admin user password |
| defectdojo-secret-key | DD_SECRET_KEY | Django secret key |
| defectdojo-credential-aes-key | DD_CREDENTIAL_AES_256_KEY | Credential encryption |
| defectdojo-azuread-client-secret | DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET | Azure AD client secret |
Symptoms: User logged in via Azure AD but shows "No group members found"
Solutions:
DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_GET_GROUPS=TrueError: "The redirect URI specified in the request does not match"
Solution: Ensure these are set:
- name: DD_SESSION_COOKIE_SECURE
value: "True"
- name: DD_CSRF_COOKIE_SECURE
value: "True"
- name: DD_SECURE_PROXY_SSL_HEADER
value: "True"
Cause: DD_SECURE_SSL_REDIRECT=True with TLS-terminating proxy
Solution: Set DD_SECURE_SSL_REDIRECT=False when behind NGINX Ingress
If SSO breaks, access standard login form:
https://defectdojo.dev.cafehyna.com.br/login?force_login_form
For complete troubleshooting guide, see references/troubleshooting.md.
KUBECONFIG=~/.kube/aks-rg-hypera-cafehyna-dev-config kubectl get pods -n defectdojo
KUBECONFIG=~/.kube/aks-rg-hypera-cafehyna-dev-config kubectl logs -n defectdojo -l app.kubernetes.io/name=defectdojo -c uwsgi
KUBECONFIG=~/.kube/aks-rg-hypera-cafehyna-dev-config kubectl rollout restart deployment/defectdojo-django -n defectdojo
reimport-scan closes missing findings silently: Reimporting a partial scan (one path instead of full) auto-closes every finding not in the new file. Use do_not_reactivate=true and scope tests carefully.auto_create_context=true creates duplicate products on name drift: "MyApp" vs "myapp" vs "MyApp " produce three products. Normalize product_name upstream — DefectDojo does not fuzzy-match.DD_SECURE_SSL_REDIRECT=True behind NGINX Ingress causes redirect loops: TLS terminates at the ingress, Django then redirects HTTP to HTTPS again. Set to False and rely on the ingress for TLS enforcement.testing
Brief description of what this skill does. Include specific triggers - when should Claude use this skill? Example triggers, file types, or keywords that indicate this skill applies.
tools
Manage and troubleshoot PATH configuration in zsh. Use when adding tools to PATH (bun, nvm, Python venv, cargo, go), diagnosing "command not found" errors, validating PATH entries, or organizing shell configuration in .zshrc and .zshrc.local files.
tools
Zabbix monitoring system automation via API and Python. Use when: (1) Managing hosts, templates, items, triggers, or host groups, (2) Automating monitoring configuration, (3) Sending data via Zabbix trapper/sender, (4) Querying historical data or events, (5) Bulk operations on Zabbix objects, (6) Maintenance window management, (7) User/permission management
development
Operate YouTube Music via natural language. Search songs, artists, albums, playlists, lyrics, charts, recommendations, and control playback. Browse personal library, manage playlists, rate tracks, and inspect account info. Use this skill whenever the user asks about YouTube Music, wants to play music, manage playlists, search by song or artist name, inspect lyrics, or control playback.