c753797019
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Leads get a Create Template button that adds directly to the catalog (existing POST /test-templates). Operators (red_tech/blue_tech) get the same button, but their proposal now lands in a new template_suggestions review queue instead — a lead on their team can approve it as-is, edit fields before approving, or discard it. Modeled on the existing ProcedureSuggestion review workflow.
73 lines
2.2 KiB
Python
73 lines
2.2 KiB
Python
"""Pydantic schemas for the TemplateSuggestion (operator template proposal) workflow."""
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
|
|
class TemplateSuggestionCreate(BaseModel):
|
|
"""Payload for an operator proposing a new test template."""
|
|
|
|
mitre_technique_id: str
|
|
name: str
|
|
description: str | None = None
|
|
source: str = "custom"
|
|
source_url: str | None = None
|
|
attack_procedure: str | None = None
|
|
expected_detection: str | None = None
|
|
platform: str | None = None
|
|
tool_suggested: str | None = None
|
|
severity: str | None = None
|
|
atomic_test_id: str | None = None
|
|
suggested_remediation: str | None = None
|
|
|
|
|
|
class TemplateSuggestionApprove(BaseModel):
|
|
"""Optional field overrides a lead can apply while approving a suggestion.
|
|
|
|
Any field left unset falls back to what the operator originally
|
|
submitted — the lead only needs to pass the fields they want to change.
|
|
"""
|
|
|
|
mitre_technique_id: str | None = None
|
|
name: str | None = None
|
|
description: str | None = None
|
|
source: str | None = None
|
|
source_url: str | None = None
|
|
attack_procedure: str | None = None
|
|
expected_detection: str | None = None
|
|
platform: str | None = None
|
|
tool_suggested: str | None = None
|
|
severity: str | None = None
|
|
atomic_test_id: str | None = None
|
|
suggested_remediation: str | None = None
|
|
|
|
|
|
class TemplateSuggestionOut(BaseModel):
|
|
"""Full representation of a pending/reviewed template suggestion."""
|
|
|
|
id: uuid.UUID
|
|
mitre_technique_id: str
|
|
name: str
|
|
description: str | None = None
|
|
source: str
|
|
source_url: str | None = None
|
|
attack_procedure: str | None = None
|
|
expected_detection: str | None = None
|
|
platform: str | None = None
|
|
tool_suggested: str | None = None
|
|
severity: str | None = None
|
|
atomic_test_id: str | None = None
|
|
suggested_remediation: str | None = None
|
|
team: str
|
|
submitted_by: uuid.UUID | None = None
|
|
submitter_name: str | None = None
|
|
status: str
|
|
reviewed_by: uuid.UUID | None = None
|
|
reviewed_at: datetime | None = None
|
|
created_template_id: uuid.UUID | None = None
|
|
created_at: datetime | None = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|