Public Access
initial-commit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// APIMetadata represents identifying information for an API entity
|
||||
// An API is a contract for data exchange between software components
|
||||
message APIMetadata {
|
||||
// Required: The name of the API
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of the API
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "protocol": "rest", "version": "v1")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// APISpec represents configuration for an API entity
|
||||
message APISpec {
|
||||
// Required: Type of API definition
|
||||
// Standard types: "openapi", "grpc", "graphql", "asyncapi", "rest"
|
||||
string type = 1;
|
||||
|
||||
// Required: Lifecycle stage (e.g., "production", "experimental", "deprecated")
|
||||
string lifecycle = 2;
|
||||
|
||||
// Required: Owner team or individual (references a Group or User entity)
|
||||
string owner = 3;
|
||||
|
||||
// Optional: System this API belongs to (references a System entity)
|
||||
string system = 4;
|
||||
|
||||
// Required: The API definition itself
|
||||
// For OpenAPI: the full OpenAPI spec in YAML or JSON
|
||||
// For gRPC: the .proto file content or reference
|
||||
// For GraphQL: the schema definition
|
||||
string definition = 5;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
// Link represents an external URL reference
|
||||
// Used across all entity types for documentation, dashboards, etc.
|
||||
message Link {
|
||||
// URL to the external resource
|
||||
string url = 1;
|
||||
|
||||
// Human-readable title for the link
|
||||
string title = 2;
|
||||
|
||||
// Optional: Icon identifier (e.g., "github", "dashboard", "docs")
|
||||
string icon = 3;
|
||||
|
||||
// Optional: Type of link (e.g., "documentation", "monitoring", "repository")
|
||||
string type = 4;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// ComponentMetadata represents identifying information for a component entity
|
||||
// A component is a software component (service, website, library, etc.)
|
||||
message ComponentMetadata {
|
||||
// Required: The name of the component
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of the component
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "environment": "production", "team": "payments")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// ComponentSpec represents configuration for a component entity
|
||||
message ComponentSpec {
|
||||
// Required: Type of component (e.g., "service", "website", "library", "documentation")
|
||||
string type = 1;
|
||||
|
||||
// Required: Lifecycle stage (e.g., "production", "experimental", "deprecated")
|
||||
string lifecycle = 2;
|
||||
|
||||
// Required: Owner team or individual (references a Group or User entity)
|
||||
string owner = 3;
|
||||
|
||||
// Optional: Parent system this component belongs to (references a System entity)
|
||||
string system = 4;
|
||||
|
||||
// Optional: Sub-component of another component (references a Component entity)
|
||||
string subcomponent_of = 5;
|
||||
|
||||
// Optional: Components this component depends on (references Component entities)
|
||||
repeated string depends_on = 6;
|
||||
|
||||
// Optional: APIs this component provides (references API entities)
|
||||
repeated string provides_apis = 7;
|
||||
|
||||
// Optional: APIs this component consumes (references API entities)
|
||||
repeated string consumes_apis = 8;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// DomainMetadata represents identifying information for a domain entity
|
||||
// A domain is a high-level organizational boundary (e.g., "payments", "identity")
|
||||
message DomainMetadata {
|
||||
// Required: The domain name
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of the domain
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "business-unit": "platform", "priority": "high")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// DomainSpec represents configuration for a domain entity
|
||||
message DomainSpec {
|
||||
// Required: Owner team or individual (references a Group or User entity)
|
||||
string owner = 1;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
// FindingMetadata represents identifying information for a security finding
|
||||
message FindingMetadata {
|
||||
// Required: Title of the finding (e.g., "SQL Injection in login handler")
|
||||
string title = 1;
|
||||
|
||||
// Optional: Namespace (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Detailed description of the vulnerability
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags (e.g., "owasp-top-10", "cwe-89")
|
||||
repeated string tags = 5;
|
||||
}
|
||||
|
||||
// FindingSpec contains the security-relevant data for a finding
|
||||
message FindingSpec {
|
||||
// Required: Reference to the component this finding belongs to (entity name or UUID)
|
||||
string component_ref = 1;
|
||||
|
||||
// Required: Lifecycle/environment scope (e.g., "production", "integration", "development")
|
||||
string lifecycle = 2;
|
||||
|
||||
// Required: Severity level
|
||||
Severity severity = 3;
|
||||
|
||||
// Required: Current state of the finding
|
||||
FindingState state = 4;
|
||||
|
||||
// Required: Scanner that produced this finding
|
||||
string scanner = 5;
|
||||
|
||||
// Required: Rule/check identifier from the scanner (e.g., "CWE-89", "RUSTSEC-2024-001")
|
||||
string rule_id = 6;
|
||||
|
||||
// Computed: Fingerprint for deduplication (set by reconciliation engine)
|
||||
string fingerprint = 7;
|
||||
|
||||
// Optional: File path where the vulnerability was found
|
||||
string file_path = 8;
|
||||
|
||||
// Optional: Line number in the file
|
||||
uint32 line_start = 9;
|
||||
|
||||
// Optional: End line number (for multi-line findings)
|
||||
uint32 line_end = 10;
|
||||
|
||||
// Optional: CWE identifier (e.g., "CWE-89")
|
||||
string cwe = 11;
|
||||
|
||||
// Optional: CVE identifier (e.g., "CVE-2024-1234")
|
||||
string cve = 12;
|
||||
|
||||
// Optional: CVSS score (0.0 - 10.0)
|
||||
float cvss_score = 13;
|
||||
|
||||
// Optional: Affected package/dependency name
|
||||
string package_name = 14;
|
||||
|
||||
// Optional: Affected package version
|
||||
string package_version = 15;
|
||||
|
||||
// Optional: Fixed version (if known)
|
||||
string fixed_version = 16;
|
||||
|
||||
// Optional: URL to more details (advisory, documentation)
|
||||
string details_url = 17;
|
||||
|
||||
// Timestamp of first detection
|
||||
google.protobuf.Timestamp first_seen = 18;
|
||||
|
||||
// Timestamp of most recent detection
|
||||
google.protobuf.Timestamp last_seen = 19;
|
||||
|
||||
// Optional: Timestamp when the finding was resolved
|
||||
google.protobuf.Timestamp resolved_at = 20;
|
||||
|
||||
// Optional: Scan identifier that produced this finding (for tracing back to CI run)
|
||||
string scan_id = 21;
|
||||
}
|
||||
|
||||
// Severity levels aligned with CVSS qualitative ratings
|
||||
enum Severity {
|
||||
SEVERITY_UNSPECIFIED = 0;
|
||||
SEVERITY_INFO = 1;
|
||||
SEVERITY_LOW = 2;
|
||||
SEVERITY_MEDIUM = 3;
|
||||
SEVERITY_HIGH = 4;
|
||||
SEVERITY_CRITICAL = 5;
|
||||
}
|
||||
|
||||
// Finding lifecycle states
|
||||
enum FindingState {
|
||||
FINDING_STATE_UNSPECIFIED = 0;
|
||||
// Active: currently detected by scanner
|
||||
FINDING_STATE_ACTIVE = 1;
|
||||
// Resolved: no longer detected by scanner (auto-closed on reimport)
|
||||
FINDING_STATE_RESOLVED = 2;
|
||||
// Accepted: risk accepted by human decision
|
||||
FINDING_STATE_ACCEPTED = 3;
|
||||
// False positive: marked as not a real issue
|
||||
FINDING_STATE_FALSE_POSITIVE = 4;
|
||||
// Reopened: was resolved but detected again
|
||||
FINDING_STATE_REOPENED = 5;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// GroupMetadata represents identifying information for a group entity
|
||||
// A group represents a team or organizational unit
|
||||
message GroupMetadata {
|
||||
// Required: The group name (e.g., "team-a", "engineering")
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of the group
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "department": "engineering", "cost-center": "1234")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources (e.g., team page, Slack channel)
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// GroupSpec represents configuration for a group entity
|
||||
message GroupSpec {
|
||||
// Required: Type of group
|
||||
// Standard types: "team", "business-unit", "product-area", "root", "department"
|
||||
string type = 1;
|
||||
|
||||
// Optional: Group profile information
|
||||
GroupProfile profile = 2;
|
||||
|
||||
// Optional: Parent group for hierarchy (references a Group entity)
|
||||
// Leave empty for root-level groups
|
||||
string parent = 3;
|
||||
|
||||
// Optional: Child groups in the hierarchy (references Group entities)
|
||||
repeated string children = 4;
|
||||
|
||||
// Optional: Direct members of this group (references User entities)
|
||||
repeated string members = 5;
|
||||
}
|
||||
|
||||
// GroupProfile contains detailed profile information
|
||||
message GroupProfile {
|
||||
// Display name (e.g., "Engineering Team")
|
||||
string display_name = 1;
|
||||
|
||||
// Group email address
|
||||
string email = 2;
|
||||
|
||||
// Group picture/logo URL
|
||||
string picture = 3;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// ResourceMetadata represents identifying information for a resource entity
|
||||
// A resource is infrastructure or operational component (database, S3 bucket, cluster, etc.)
|
||||
message ResourceMetadata {
|
||||
// Required: The resource name
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of the resource
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "cloud": "aws", "region": "us-west-2")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources (e.g., AWS console, monitoring dashboard)
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// ResourceSpec represents configuration for a resource entity
|
||||
message ResourceSpec {
|
||||
// Required: Type of resource
|
||||
// Standard types: "database", "s3-bucket", "cluster", "pipeline", "queue", "cache"
|
||||
string type = 1;
|
||||
|
||||
// Required: Owner team or individual (references a Group or User entity)
|
||||
string owner = 2;
|
||||
|
||||
// Optional: System this resource belongs to (references a System entity)
|
||||
string system = 3;
|
||||
|
||||
// Optional: Resources this resource depends on (references other Resource entities)
|
||||
repeated string depends_on = 4;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// ServiceMetadata represents identifying information for a service entity
|
||||
// Compatible with Backstage Component metadata structure
|
||||
message ServiceMetadata {
|
||||
// Required: The name of the service
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (e.g., "production", "staging")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of what this service does
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
repeated string labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// ServiceSpec represents configuration and behavior for a service entity
|
||||
// Compatible with Backstage Component spec structure
|
||||
message ServiceSpec {
|
||||
// Type of service (e.g., "backend-service", "frontend", "api", "website")
|
||||
string type = 1;
|
||||
|
||||
// Lifecycle stage (e.g., "production", "experimental", "deprecated")
|
||||
string lifecycle = 2;
|
||||
|
||||
// Owner team or individual (e.g., "team-platform", "john.doe@company.com")
|
||||
string owner = 3;
|
||||
|
||||
// Optional: Parent system this service belongs to
|
||||
string system = 4;
|
||||
|
||||
// Optional: Sub-component of another service
|
||||
string subcomponent_of = 5;
|
||||
|
||||
// Optional: Services this service depends on
|
||||
repeated string depends_on = 6;
|
||||
|
||||
// Optional: Services that provide APIs this service consumes
|
||||
repeated string consumes_apis = 7;
|
||||
|
||||
// Optional: APIs that this service provides
|
||||
repeated string provides_apis = 8;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// SystemMetadata represents identifying information for a system entity
|
||||
// A system is a collection of services and resources that work together
|
||||
message SystemMetadata {
|
||||
// Required: The name of the system
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Human-readable description of the system
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "environment": "production", "criticality": "high")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// SystemSpec represents configuration for a system entity
|
||||
message SystemSpec {
|
||||
// Required: Owner team or individual responsible for this system (references a Group or User entity)
|
||||
string owner = 1;
|
||||
|
||||
// Optional: Domain this system belongs to (references a Domain entity)
|
||||
string domain = 2;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.core;
|
||||
|
||||
import "core/common.proto";
|
||||
|
||||
// UserMetadata represents identifying information for a user entity
|
||||
// A user represents a person in the organization
|
||||
message UserMetadata {
|
||||
// Required: The username (e.g., "jdoe", "john.doe")
|
||||
string name = 1;
|
||||
|
||||
// Optional: Namespace for organizational grouping (default: "default")
|
||||
string namespace = 2;
|
||||
|
||||
// Optional: Full name or description
|
||||
string description = 3;
|
||||
|
||||
// Optional: Labels for categorization and filtering
|
||||
// Key-value pairs (e.g., "department": "engineering", "location": "SF")
|
||||
map<string, string> labels = 4;
|
||||
|
||||
// Optional: Tags for additional classification
|
||||
repeated string tags = 5;
|
||||
|
||||
// Optional: Links to external resources (e.g., GitHub profile, LinkedIn)
|
||||
repeated Link links = 6;
|
||||
}
|
||||
|
||||
// UserSpec represents configuration for a user entity
|
||||
message UserSpec {
|
||||
// Optional: User profile information
|
||||
UserProfile profile = 1;
|
||||
|
||||
// Optional: Groups this user is a member of (references Group entities)
|
||||
repeated string member_of = 2;
|
||||
}
|
||||
|
||||
// UserProfile contains detailed profile information
|
||||
message UserProfile {
|
||||
// Display name (e.g., "John Doe")
|
||||
string display_name = 1;
|
||||
|
||||
// Email address
|
||||
string email = 2;
|
||||
|
||||
// Avatar/picture URL
|
||||
string picture = 3;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.entities;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/field_mask.proto";
|
||||
import "core/service.proto";
|
||||
import "core/system.proto";
|
||||
import "core/component.proto";
|
||||
import "core/api.proto";
|
||||
import "core/user.proto";
|
||||
import "core/group.proto";
|
||||
import "core/domain.proto";
|
||||
import "core/resource.proto";
|
||||
import "core/finding.proto";
|
||||
|
||||
// Plugin imports will be inserted here by build.rs
|
||||
import "plugins/defectdojo/proto/defectdojo.proto";
|
||||
import "plugins/keycloak/proto/keycloak.proto";
|
||||
import "plugins/dependencytrack/proto/dependencytrack.proto";
|
||||
|
||||
|
||||
// GENERATED FILE - DO NOT EDIT MANUALLY
|
||||
// This file is generated by build.rs based on plugins.toml configuration
|
||||
// To add new entity types, configure plugins in plugins.toml and rebuild
|
||||
|
||||
// Main entity structure
|
||||
// This represents any cataloged entity in Charybdis
|
||||
message Entity {
|
||||
// Unique identifier (UUID)
|
||||
string id = 1;
|
||||
|
||||
// Entity kind (e.g., "Service", "System", "Component")
|
||||
// This determines which metadata/spec variant is populated
|
||||
string kind = 2;
|
||||
|
||||
// Polymorphic metadata - identifying information
|
||||
// Each kind has its own metadata structure
|
||||
oneof metadata {
|
||||
charybdis.core.ServiceMetadata service_metadata = 10;
|
||||
charybdis.core.SystemMetadata system_metadata = 11;
|
||||
charybdis.core.ComponentMetadata component_metadata = 12;
|
||||
charybdis.core.APIMetadata api_metadata = 13;
|
||||
charybdis.core.UserMetadata user_metadata = 14;
|
||||
charybdis.core.GroupMetadata group_metadata = 15;
|
||||
charybdis.core.DomainMetadata domain_metadata = 16;
|
||||
charybdis.core.ResourceMetadata resource_metadata = 17;
|
||||
charybdis.core.FindingMetadata finding_metadata = 24;
|
||||
|
||||
// Plugin metadata types will be inserted here by build.rs
|
||||
// Example:
|
||||
// charybdis.plugins.defectdojo.DefectDojoProductMetadata defectdojo_product_metadata = 100;
|
||||
// charybdis.plugins.dependencytrack.DependencyTrackProjectMetadata dependencytrack_project_metadata = 101;
|
||||
charybdis.plugins.defectdojo.DefectdojoMetadata defectdojo_metadata = 100;
|
||||
charybdis.plugins.keycloak.KeycloakMetadata keycloak_metadata = 102;
|
||||
charybdis.plugins.dependencytrack.DependencytrackMetadata dependencytrack_metadata = 101;
|
||||
|
||||
}
|
||||
|
||||
// Polymorphic spec - configuration and behavior
|
||||
// Each kind has its own spec structure
|
||||
oneof spec {
|
||||
charybdis.core.ServiceSpec service_spec = 4;
|
||||
charybdis.core.SystemSpec system_spec = 5;
|
||||
charybdis.core.ComponentSpec component_spec = 6;
|
||||
charybdis.core.APISpec api_spec = 7;
|
||||
charybdis.core.UserSpec user_spec = 8;
|
||||
charybdis.core.GroupSpec group_spec = 9;
|
||||
charybdis.core.DomainSpec domain_spec = 18;
|
||||
charybdis.core.ResourceSpec resource_spec = 19;
|
||||
charybdis.core.FindingSpec finding_spec = 25;
|
||||
|
||||
// Plugin spec types will be inserted here by build.rs
|
||||
// Example:
|
||||
// charybdis.plugins.defectdojo.DefectDojoProductSpec defectdojo_product_spec = 100;
|
||||
// charybdis.plugins.dependencytrack.DependencyTrackProjectSpec dependencytrack_project_spec = 101;
|
||||
charybdis.plugins.defectdojo.DefectdojoSpec defectdojo_spec = 200;
|
||||
charybdis.plugins.keycloak.KeycloakSpec keycloak_spec = 202;
|
||||
charybdis.plugins.dependencytrack.DependencytrackSpec dependencytrack_spec = 201;
|
||||
|
||||
}
|
||||
|
||||
// Annotations - arbitrary string key-value pairs
|
||||
// This is where plugins store external tool IDs and references
|
||||
// Examples:
|
||||
// "defectdojo.com/product-id": "12345"
|
||||
// "dependencytrack.com/project-uuid": "550e8400-e29b-41d4-a716-446655440000"
|
||||
// "github.com/repo-slug": "myorg/myrepo"
|
||||
map<string, string> annotations = 20;
|
||||
|
||||
// Timestamps (managed by the system)
|
||||
google.protobuf.Timestamp created_at = 21;
|
||||
google.protobuf.Timestamp updated_at = 22;
|
||||
}
|
||||
|
||||
// Request to create a new entity
|
||||
message CreateEntityRequest {
|
||||
// Entity data (id, created_at, updated_at will be set by server)
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Response after creating an entity
|
||||
message CreateEntityResponse {
|
||||
// The created entity with server-assigned fields
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Request to get an entity by ID
|
||||
message GetEntityRequest {
|
||||
// The UUID of the entity to retrieve
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
// Response containing a single entity
|
||||
message GetEntityResponse {
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Request to update an existing entity
|
||||
message UpdateEntityRequest {
|
||||
// The UUID of the entity to update
|
||||
string id = 1;
|
||||
|
||||
// Updated entity data (id, created_at will be ignored)
|
||||
Entity entity = 2;
|
||||
|
||||
// Optional: Field mask for partial updates
|
||||
// If not provided, performs a full update
|
||||
// If provided, only updates the fields specified in the mask
|
||||
// Example paths: "kind", "annotations", "metadata", "spec",
|
||||
// "annotations.github.com/repo-slug",
|
||||
// "component_metadata.name", "component_spec.lifecycle"
|
||||
google.protobuf.FieldMask update_mask = 3;
|
||||
}
|
||||
|
||||
// Response after updating an entity
|
||||
message UpdateEntityResponse {
|
||||
// The updated entity
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Request to delete an entity by ID
|
||||
message DeleteEntityRequest {
|
||||
// The UUID of the entity to delete
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
// Response after deleting an entity
|
||||
message DeleteEntityResponse {
|
||||
// Whether the deletion was successful
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
// Request to list entities
|
||||
message ListEntitiesRequest {
|
||||
// Optional: Filter by kind
|
||||
string kind = 1;
|
||||
|
||||
// Optional: Filter by annotation key-value pairs
|
||||
map<string, string> annotations = 2;
|
||||
|
||||
// Page size (default: 100, max: 1000)
|
||||
int32 page_size = 3;
|
||||
|
||||
// Cursor for next page (opaque token from previous response)
|
||||
string page_token = 4;
|
||||
|
||||
// Optional: Filter by name
|
||||
string name = 5;
|
||||
}
|
||||
|
||||
// Response containing a list of entities
|
||||
message ListEntitiesResponse {
|
||||
// The list of entities matching the filter
|
||||
repeated Entity entities = 1;
|
||||
|
||||
// Cursor for next page (empty if no more results)
|
||||
string next_page_token = 2;
|
||||
|
||||
// Total count of matching entities
|
||||
int32 total_count = 3;
|
||||
}
|
||||
|
||||
// Service definition for managing entities
|
||||
service EntityService {
|
||||
// Creates a new entity
|
||||
rpc CreateEntity (CreateEntityRequest) returns (CreateEntityResponse);
|
||||
|
||||
// Gets an entity by its ID
|
||||
rpc GetEntity (GetEntityRequest) returns (GetEntityResponse);
|
||||
|
||||
// Updates an existing entity
|
||||
rpc UpdateEntity (UpdateEntityRequest) returns (UpdateEntityResponse);
|
||||
|
||||
// Deletes an entity by its ID
|
||||
rpc DeleteEntity (DeleteEntityRequest) returns (DeleteEntityResponse);
|
||||
|
||||
// Lists entities with optional filtering
|
||||
rpc ListEntities (ListEntitiesRequest) returns (ListEntitiesResponse);
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.entities;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/field_mask.proto";
|
||||
import "core/service.proto";
|
||||
import "core/system.proto";
|
||||
import "core/component.proto";
|
||||
import "core/api.proto";
|
||||
import "core/user.proto";
|
||||
import "core/group.proto";
|
||||
import "core/domain.proto";
|
||||
import "core/resource.proto";
|
||||
import "core/finding.proto";
|
||||
|
||||
// Plugin imports will be inserted here by build.rs
|
||||
{{PLUGIN_IMPORTS}}
|
||||
|
||||
// GENERATED FILE - DO NOT EDIT MANUALLY
|
||||
// This file is generated by build.rs based on plugins.toml configuration
|
||||
// To add new entity types, configure plugins in plugins.toml and rebuild
|
||||
|
||||
// Main entity structure
|
||||
// This represents any cataloged entity in Charybdis
|
||||
message Entity {
|
||||
// Unique identifier (UUID)
|
||||
string id = 1;
|
||||
|
||||
// Entity kind (e.g., "Service", "System", "Component")
|
||||
// This determines which metadata/spec variant is populated
|
||||
string kind = 2;
|
||||
|
||||
// Polymorphic metadata - identifying information
|
||||
// Each kind has its own metadata structure
|
||||
oneof metadata {
|
||||
charybdis.core.ServiceMetadata service_metadata = 10;
|
||||
charybdis.core.SystemMetadata system_metadata = 11;
|
||||
charybdis.core.ComponentMetadata component_metadata = 12;
|
||||
charybdis.core.APIMetadata api_metadata = 13;
|
||||
charybdis.core.UserMetadata user_metadata = 14;
|
||||
charybdis.core.GroupMetadata group_metadata = 15;
|
||||
charybdis.core.DomainMetadata domain_metadata = 16;
|
||||
charybdis.core.ResourceMetadata resource_metadata = 17;
|
||||
charybdis.core.FindingMetadata finding_metadata = 24;
|
||||
|
||||
// Plugin metadata types will be inserted here by build.rs
|
||||
// Example:
|
||||
// charybdis.plugins.defectdojo.DefectDojoProductMetadata defectdojo_product_metadata = 100;
|
||||
// charybdis.plugins.dependencytrack.DependencyTrackProjectMetadata dependencytrack_project_metadata = 101;
|
||||
{{PLUGIN_METADATA_FIELDS}}
|
||||
}
|
||||
|
||||
// Polymorphic spec - configuration and behavior
|
||||
// Each kind has its own spec structure
|
||||
oneof spec {
|
||||
charybdis.core.ServiceSpec service_spec = 4;
|
||||
charybdis.core.SystemSpec system_spec = 5;
|
||||
charybdis.core.ComponentSpec component_spec = 6;
|
||||
charybdis.core.APISpec api_spec = 7;
|
||||
charybdis.core.UserSpec user_spec = 8;
|
||||
charybdis.core.GroupSpec group_spec = 9;
|
||||
charybdis.core.DomainSpec domain_spec = 18;
|
||||
charybdis.core.ResourceSpec resource_spec = 19;
|
||||
charybdis.core.FindingSpec finding_spec = 25;
|
||||
|
||||
// Plugin spec types will be inserted here by build.rs
|
||||
// Example:
|
||||
// charybdis.plugins.defectdojo.DefectDojoProductSpec defectdojo_product_spec = 100;
|
||||
// charybdis.plugins.dependencytrack.DependencyTrackProjectSpec dependencytrack_project_spec = 101;
|
||||
{{PLUGIN_SPEC_FIELDS}}
|
||||
}
|
||||
|
||||
// Annotations - arbitrary string key-value pairs
|
||||
// This is where plugins store external tool IDs and references
|
||||
// Examples:
|
||||
// "defectdojo.com/product-id": "12345"
|
||||
// "dependencytrack.com/project-uuid": "550e8400-e29b-41d4-a716-446655440000"
|
||||
// "github.com/repo-slug": "myorg/myrepo"
|
||||
map<string, string> annotations = 20;
|
||||
|
||||
// Timestamps (managed by the system)
|
||||
google.protobuf.Timestamp created_at = 21;
|
||||
google.protobuf.Timestamp updated_at = 22;
|
||||
}
|
||||
|
||||
// Request to create a new entity
|
||||
message CreateEntityRequest {
|
||||
// Entity data (id, created_at, updated_at will be set by server)
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Response after creating an entity
|
||||
message CreateEntityResponse {
|
||||
// The created entity with server-assigned fields
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Request to get an entity by ID
|
||||
message GetEntityRequest {
|
||||
// The UUID of the entity to retrieve
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
// Response containing a single entity
|
||||
message GetEntityResponse {
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Request to update an existing entity
|
||||
message UpdateEntityRequest {
|
||||
// The UUID of the entity to update
|
||||
string id = 1;
|
||||
|
||||
// Updated entity data (id, created_at will be ignored)
|
||||
Entity entity = 2;
|
||||
|
||||
// Optional: Field mask for partial updates
|
||||
// If not provided, performs a full update
|
||||
// If provided, only updates the fields specified in the mask
|
||||
// Example paths: "kind", "annotations", "metadata", "spec",
|
||||
// "annotations.github.com/repo-slug",
|
||||
// "component_metadata.name", "component_spec.lifecycle"
|
||||
google.protobuf.FieldMask update_mask = 3;
|
||||
}
|
||||
|
||||
// Response after updating an entity
|
||||
message UpdateEntityResponse {
|
||||
// The updated entity
|
||||
Entity entity = 1;
|
||||
}
|
||||
|
||||
// Request to delete an entity by ID
|
||||
message DeleteEntityRequest {
|
||||
// The UUID of the entity to delete
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
// Response after deleting an entity
|
||||
message DeleteEntityResponse {
|
||||
// Whether the deletion was successful
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
// Request to list entities
|
||||
message ListEntitiesRequest {
|
||||
// Optional: Filter by kind
|
||||
string kind = 1;
|
||||
|
||||
// Optional: Filter by annotation key-value pairs
|
||||
map<string, string> annotations = 2;
|
||||
|
||||
// Page size (default: 100, max: 1000)
|
||||
int32 page_size = 3;
|
||||
|
||||
// Cursor for next page (opaque token from previous response)
|
||||
string page_token = 4;
|
||||
|
||||
// Optional: Filter by name
|
||||
string name = 5;
|
||||
}
|
||||
|
||||
// Response containing a list of entities
|
||||
message ListEntitiesResponse {
|
||||
// The list of entities matching the filter
|
||||
repeated Entity entities = 1;
|
||||
|
||||
// Cursor for next page (empty if no more results)
|
||||
string next_page_token = 2;
|
||||
|
||||
// Total count of matching entities
|
||||
int32 total_count = 3;
|
||||
}
|
||||
|
||||
// Service definition for managing entities
|
||||
service EntityService {
|
||||
// Creates a new entity
|
||||
rpc CreateEntity (CreateEntityRequest) returns (CreateEntityResponse);
|
||||
|
||||
// Gets an entity by its ID
|
||||
rpc GetEntity (GetEntityRequest) returns (GetEntityResponse);
|
||||
|
||||
// Updates an existing entity
|
||||
rpc UpdateEntity (UpdateEntityRequest) returns (UpdateEntityResponse);
|
||||
|
||||
// Deletes an entity by its ID
|
||||
rpc DeleteEntity (DeleteEntityRequest) returns (DeleteEntityResponse);
|
||||
|
||||
// Lists entities with optional filtering
|
||||
rpc ListEntities (ListEntitiesRequest) returns (ListEntitiesResponse);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package charybdis.ingestion;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "core/finding.proto";
|
||||
|
||||
// Service for ingesting security scan results
|
||||
service IngestionService {
|
||||
// Import a scan report: parse, reconcile with existing findings, and persist
|
||||
rpc ImportScan (ImportScanRequest) returns (ImportScanResponse);
|
||||
|
||||
// Dry-run a scan report: parse, reconcile, return diff without persisting
|
||||
// Useful for MR/PR comments: "this change introduces X new vulnerabilities"
|
||||
rpc DryRunScan (DryRunScanRequest) returns (DryRunScanResponse);
|
||||
}
|
||||
|
||||
// Request to import a scan report
|
||||
message ImportScanRequest {
|
||||
// Required: Reference to the component (entity name or UUID)
|
||||
string component_ref = 1;
|
||||
|
||||
// Required: Lifecycle/environment scope (e.g., "production", "integration")
|
||||
string lifecycle = 2;
|
||||
|
||||
// Required: Format of the scan data (e.g., "sarif", "cyclonedx-vex")
|
||||
string format = 3;
|
||||
|
||||
// Required: Raw scan report data (JSON/XML bytes)
|
||||
bytes data = 4;
|
||||
|
||||
// Optional: Scanner name override (if not derivable from the report)
|
||||
string scanner_name = 5;
|
||||
|
||||
// Optional: Identifier for this scan run (e.g., CI job ID)
|
||||
string scan_id = 6;
|
||||
}
|
||||
|
||||
// Response after importing a scan
|
||||
message ImportScanResponse {
|
||||
// Summary of what happened during reconciliation
|
||||
ReconciliationSummary summary = 1;
|
||||
|
||||
// New findings created during this import
|
||||
repeated FindingResult new_findings = 2;
|
||||
|
||||
// Findings that were resolved (no longer detected)
|
||||
repeated FindingResult resolved_findings = 3;
|
||||
|
||||
// Findings that were reopened (detected again after being resolved)
|
||||
repeated FindingResult reopened_findings = 4;
|
||||
}
|
||||
|
||||
// Request for dry-run scan (same as import but no persistence)
|
||||
message DryRunScanRequest {
|
||||
// Required: Reference to the component (entity name or UUID)
|
||||
string component_ref = 1;
|
||||
|
||||
// Required: Lifecycle/environment scope
|
||||
string lifecycle = 2;
|
||||
|
||||
// Required: Format of the scan data
|
||||
string format = 3;
|
||||
|
||||
// Required: Raw scan report data
|
||||
bytes data = 4;
|
||||
|
||||
// Optional: Scanner name override
|
||||
string scanner_name = 5;
|
||||
}
|
||||
|
||||
// Response for dry-run scan
|
||||
message DryRunScanResponse {
|
||||
// Summary of what would happen
|
||||
ReconciliationSummary summary = 1;
|
||||
|
||||
// New findings that would be created
|
||||
repeated FindingResult new_findings = 2;
|
||||
|
||||
// Findings that would be resolved
|
||||
repeated FindingResult resolved_findings = 3;
|
||||
|
||||
// Findings that would be reopened
|
||||
repeated FindingResult reopened_findings = 4;
|
||||
}
|
||||
|
||||
// Summary statistics of a reconciliation operation
|
||||
message ReconciliationSummary {
|
||||
// Total findings parsed from the scan report
|
||||
uint32 total_parsed = 1;
|
||||
|
||||
// New findings (not previously seen)
|
||||
uint32 new_count = 2;
|
||||
|
||||
// Existing findings still detected (unchanged)
|
||||
uint32 unchanged_count = 3;
|
||||
|
||||
// Previously active findings no longer detected (resolved)
|
||||
uint32 resolved_count = 4;
|
||||
|
||||
// Previously resolved findings detected again (reopened)
|
||||
uint32 reopened_count = 5;
|
||||
}
|
||||
|
||||
// A finding result returned in import/dry-run responses
|
||||
message FindingResult {
|
||||
// Finding title
|
||||
string title = 1;
|
||||
|
||||
// Severity
|
||||
charybdis.core.Severity severity = 2;
|
||||
|
||||
// Scanner rule ID
|
||||
string rule_id = 3;
|
||||
|
||||
// File path (if applicable)
|
||||
string file_path = 4;
|
||||
|
||||
// Line number (if applicable)
|
||||
uint32 line_start = 5;
|
||||
|
||||
// Fingerprint used for deduplication
|
||||
string fingerprint = 6;
|
||||
|
||||
// Entity ID (set for existing findings, empty for dry-run new findings)
|
||||
string entity_id = 7;
|
||||
}
|
||||
Reference in New Issue
Block a user