Public Access
629 lines
16 KiB
Markdown
629 lines
16 KiB
Markdown
# Core Concepts
|
|
|
|
Charybdis is a **security-native platform engineering tool** that unifies software catalog, vulnerability management, and compliance posture behind a gRPC API. When entities change or scan results are ingested, the event bus triggers rules evaluation, security gate checks, and plugin integrations automatically.
|
|
|
|
This page explains the key concepts you need to understand.
|
|
|
|
## Architecture Overview
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph "Sources"
|
|
A1[CI/CD Pipelines]
|
|
A2[Security Scanners]
|
|
A3[IaC Tools]
|
|
end
|
|
|
|
subgraph "Charybdis Core"
|
|
B1[gRPC API]
|
|
B3[Authentication & Authorization]
|
|
C1[Entity Service]
|
|
C4[Vulnerability Engine]
|
|
C5[Security Gates & Rules]
|
|
C2[Event Bus]
|
|
end
|
|
|
|
subgraph "Integrations - Plugins"
|
|
D1[Slack / Teams]
|
|
D2[Jira / GitHub]
|
|
D3[Custom Plugins]
|
|
end
|
|
|
|
subgraph "Data Layer"
|
|
E1[(PostgreSQL)]
|
|
end
|
|
|
|
A1 -.gRPC.-> B1
|
|
A2 -.Scan Results.-> B1
|
|
A3 -.gRPC.-> B1
|
|
|
|
B1 --> B3
|
|
B3 --> C1
|
|
B3 --> C4
|
|
C4 --> C5
|
|
C1 --> E1
|
|
C4 --> E1
|
|
C1 --> C2
|
|
C4 --> C2
|
|
|
|
C2 -.Events.-> D1
|
|
C2 -.Events.-> D2
|
|
C2 -.Events.-> D3
|
|
|
|
style C4 fill:#E24A4A,stroke:#8A2E2E,color:#fff
|
|
style C5 fill:#E2884A,stroke:#8A5C2E,color:#fff
|
|
style C2 fill:#4A90E2,stroke:#2E5C8A,color:#fff
|
|
```
|
|
|
|
## Entities
|
|
|
|
An **entity** is the core data model in Charybdis, representing any cataloged item in your software ecosystem.
|
|
|
|
### Entity Structure
|
|
|
|
Every entity has three main parts:
|
|
|
|
```mermaid
|
|
classDiagram
|
|
class Entity {
|
|
+string id
|
|
+string kind
|
|
+metadata
|
|
+spec
|
|
+annotations
|
|
+timestamps
|
|
}
|
|
|
|
class Metadata {
|
|
+string name
|
|
+string namespace
|
|
+string description
|
|
+labels
|
|
+links
|
|
+tags
|
|
}
|
|
|
|
class Spec {
|
|
+string type
|
|
+string lifecycle
|
|
+string owner
|
|
+dependencies
|
|
}
|
|
|
|
Entity --> Metadata
|
|
Entity --> Spec
|
|
```
|
|
|
|
### Entity Kinds
|
|
|
|
Charybdis supports all standard Backstage entity kinds:
|
|
|
|
| Kind | Description | Example |
|
|
|------|-------------|---------|
|
|
| **Service** | Individual microservices or applications | `payment-api` |
|
|
| **Component** | Reusable libraries, SDKs, modules | `auth-sdk` |
|
|
| **System** | Collections of services working together | `e-commerce-platform` |
|
|
| **API** | Interfaces exposed by components | `payments-rest-api` |
|
|
| **User** | Individual people | `john.doe` |
|
|
| **Group** | Teams and organizational units | `team-payments` |
|
|
| **Domain** | Business domains | `payments`, `shipping` |
|
|
| **Resource** | Infrastructure resources | `payments-db`, `cache-cluster` |
|
|
|
|
#### Example: Service
|
|
|
|
```json
|
|
{
|
|
"kind": "Service",
|
|
"service_metadata": {
|
|
"name": "payment-api",
|
|
"namespace": "production",
|
|
"description": "Payment processing service",
|
|
"labels": { "team": "payments" }
|
|
},
|
|
"service_spec": {
|
|
"type": "service",
|
|
"lifecycle": "production",
|
|
"owner": "team-payments",
|
|
"system": "payment-system"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Example: Component
|
|
|
|
```json
|
|
{
|
|
"kind": "Component",
|
|
"component_metadata": {
|
|
"name": "auth-sdk",
|
|
"namespace": "shared"
|
|
},
|
|
"component_spec": {
|
|
"type": "library",
|
|
"lifecycle": "production",
|
|
"owner": "platform-team"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Example: System
|
|
|
|
```json
|
|
{
|
|
"kind": "System",
|
|
"system_metadata": {
|
|
"name": "e-commerce-platform",
|
|
"namespace": "production",
|
|
"description": "Complete e-commerce system"
|
|
},
|
|
"system_spec": {
|
|
"owner": "platform-team",
|
|
"domain": "retail"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Metadata Fields
|
|
|
|
| Field | Type | Description | Required |
|
|
|-------|------|-------------|----------|
|
|
| `name` | string | Entity name (unique within namespace) | ✅ |
|
|
| `namespace` | string | Logical grouping (e.g., "production", "staging") | ✅ |
|
|
| `description` | string | Human-readable description | ❌ |
|
|
| `labels` | map | Key-value pairs for categorization | ❌ |
|
|
| `tags` | array | Search tags | ❌ |
|
|
| `links` | array | External URLs (dashboards, docs, etc.) | ❌ |
|
|
|
|
### Annotations
|
|
|
|
Annotations store integration-specific metadata:
|
|
|
|
```json
|
|
{
|
|
"annotations": {
|
|
"github.com/repo-slug": "myorg/payment-service",
|
|
"defectdojo.com/product-id": "123",
|
|
"dependencytrack.com/project-uuid": "550e8400...",
|
|
"pagerduty.com/service-id": "PXYZ123",
|
|
"grafana.com/dashboard-url": "https://..."
|
|
}
|
|
}
|
|
```
|
|
|
|
**Best Practices**:
|
|
- Use domain-style keys (`tool.com/key`)
|
|
- Store tool-specific IDs
|
|
- Keep values as strings
|
|
- Use for integration metadata only
|
|
|
|
## Events
|
|
|
|
Charybdis uses an **event-driven architecture** to trigger actions when entities change.
|
|
|
|
### Event Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Client
|
|
participant API as Entity Service
|
|
participant Bus as Event Bus
|
|
participant Plugin1 as DefectDojo Plugin
|
|
participant Plugin2 as Dependency-Track
|
|
|
|
Client->>API: CreateEntity(service)
|
|
API->>API: Store entity
|
|
API->>Bus: Emit EntityCreated event
|
|
Bus->>Plugin1: Handle event
|
|
Bus->>Plugin2: Handle event
|
|
Plugin1-->>Plugin1: Create DefectDojo product
|
|
Plugin2-->>Plugin2: Create DT project
|
|
API-->>Client: Return created entity
|
|
|
|
Note over Bus,Plugin2: Asynchronous processing
|
|
```
|
|
|
|
### Event Types
|
|
|
|
| Event | Trigger | Plugins Receive |
|
|
|-------|---------|----------------|
|
|
| `EntityCreated` | New entity created | Full entity data |
|
|
| `EntityUpdated` | Entity modified | Updated entity + changes |
|
|
| `EntityDeleted` | Entity removed | Entity ID + metadata |
|
|
|
|
### Event Structure
|
|
|
|
```rust
|
|
pub enum EntityEvent {
|
|
Created {
|
|
entity: Entity,
|
|
timestamp: DateTime<Utc>,
|
|
},
|
|
Updated {
|
|
entity: Entity,
|
|
previous: Entity,
|
|
timestamp: DateTime<Utc>,
|
|
},
|
|
Deleted {
|
|
id: String,
|
|
metadata: Metadata,
|
|
timestamp: DateTime<Utc>,
|
|
},
|
|
}
|
|
```
|
|
|
|
## Vulnerabilities & Security (Phase 1 — Planned)
|
|
|
|
> **Note**: The features described in this section are part of Phase 1 (Security Core) and are not yet implemented. This documents the planned architecture. See [VISION.md](../VISION.md) for the roadmap.
|
|
|
|
Security is a **first-class concept** in Charybdis, not a plugin. Once Phase 1 is complete, vulnerability management, scan ingestion, security gates, and assessment workflows will be native to the core.
|
|
|
|
### Vulnerability Lifecycle
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Scanner
|
|
participant API as Charybdis API
|
|
participant Rules as Rules Engine
|
|
participant Gate as Security Gate
|
|
participant Bus as Event Bus
|
|
participant Plugin as Slack / Jira
|
|
|
|
Scanner->>API: IngestScan(SARIF report)
|
|
API->>API: Parse & create Vulnerability entities
|
|
API->>API: Link vulnerabilities to Component
|
|
API->>Rules: Evaluate auto-assessment rules
|
|
Rules-->>API: Auto-assess (e.g., accept known low-risk)
|
|
API->>Gate: Check security gate thresholds
|
|
alt Gate Passed
|
|
Gate-->>API: OK
|
|
else Gate Failed
|
|
Gate->>Bus: GateFailed event
|
|
Bus->>Plugin: Alert #security channel
|
|
end
|
|
API->>Bus: VulnerabilitiesIngested event
|
|
Bus->>Plugin: Notify / create tickets
|
|
```
|
|
|
|
### Scan Ingestion
|
|
|
|
Charybdis ingests scan results natively. You don't need an external vulnerability management tool.
|
|
|
|
| Format | Coverage | Use Case |
|
|
|--------|----------|----------|
|
|
| **SARIF** | 60%+ of modern scanners (Semgrep, CodeQL, Trivy, etc.) | SAST, DAST, secrets |
|
|
| **CycloneDX** | SBOMs + vulnerability data | SCA, license |
|
|
| **SPDX** | License and package data | License compliance |
|
|
|
|
### Assessments
|
|
|
|
Each vulnerability can be assessed:
|
|
|
|
| Status | Meaning |
|
|
|--------|---------|
|
|
| **Open** | New, unreviewed vulnerability |
|
|
| **In Triage** | Under review by security team |
|
|
| **Accepted** | Risk accepted with justification |
|
|
| **Remediated** | Fixed, pending verification |
|
|
| **False Positive** | Not a real vulnerability |
|
|
| **Auto-Assessed** | Automatically assessed by rules engine |
|
|
|
|
### Security Gates
|
|
|
|
Security gates define thresholds per product:
|
|
|
|
```
|
|
payment-api:
|
|
critical: 0 # No critical vulns allowed
|
|
high: 5 # Up to 5 high
|
|
medium: 20 # Up to 20 medium
|
|
```
|
|
|
|
When a gate is violated, events fire and plugins react (block CI/CD, alert Slack, create Jira tickets).
|
|
|
|
### Rules Engine
|
|
|
|
Rules auto-assess vulnerabilities based on patterns:
|
|
|
|
- Severity + component combination (e.g., "low severity in test dependencies → auto-accept")
|
|
- Scanner source (e.g., "all informational from ZAP → auto-accept")
|
|
- Known patterns (e.g., "CVE-XXXX already accepted org-wide")
|
|
|
|
### License Compliance (Phase 2)
|
|
|
|
Track licenses across your dependency tree:
|
|
|
|
- Ingest license data from CycloneDX/SPDX
|
|
- Define license policies (allowed, restricted, banned)
|
|
- Flag violations per component
|
|
- Compliance reporting
|
|
|
|
## Storage Model
|
|
|
|
Charybdis uses PostgreSQL with JSONB for schema-less storage.
|
|
|
|
### Database Schema
|
|
|
|
```sql
|
|
CREATE TABLE entities (
|
|
id UUID PRIMARY KEY,
|
|
kind TEXT NOT NULL,
|
|
entity_data BYTEA NOT NULL, -- Protobuf binary
|
|
annotations JSONB NOT NULL DEFAULT '{}', -- Plugin metadata (indexed)
|
|
created_at TIMESTAMP NOT NULL,
|
|
updated_at TIMESTAMP NOT NULL
|
|
);
|
|
|
|
CREATE INDEX idx_entities_kind ON entities(kind);
|
|
CREATE INDEX idx_entities_annotations ON entities USING GIN(annotations);
|
|
```
|
|
|
|
### Why Protobuf + JSONB?
|
|
|
|
**Advantages**:
|
|
- ✅ No schema migrations — new entity kinds via protobuf `oneof`, schema never changes
|
|
- ✅ Protobuf binary storage for compact, versioned entity data
|
|
- ✅ JSONB annotations for fast querying with GIN indexes
|
|
- ✅ Forward/backward compatibility built-in
|
|
|
|
**Example Query**:
|
|
```sql
|
|
-- Find entities with specific annotation
|
|
SELECT * FROM entities
|
|
WHERE annotations->>'defectdojo.com/product-id' = '42';
|
|
```
|
|
|
|
## Security Model
|
|
|
|
Charybdis implements defense-in-depth security.
|
|
|
|
### Authentication: mTLS
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Client
|
|
participant TLS as TLS Layer
|
|
participant Auth as Auth Interceptor
|
|
participant Service as Entity Service
|
|
|
|
Client->>TLS: Connect with client certificate
|
|
TLS->>TLS: Validate certificate
|
|
TLS->>Auth: Extract certificate
|
|
Auth->>Auth: Parse identity (CN, OU, O)
|
|
Auth->>Auth: Map to role
|
|
Client->>Auth: Request (with identity)
|
|
Auth->>Auth: Check permissions
|
|
alt Authorized
|
|
Auth->>Service: Forward request
|
|
Service-->>Client: Response
|
|
else Denied
|
|
Auth-->>Client: PermissionDenied error
|
|
end
|
|
```
|
|
|
|
### Authorization: RBAC
|
|
|
|
**Role Mapping**:
|
|
|
|
```
|
|
Certificate (CN, OU, O) → RBAC Role → Permissions
|
|
```
|
|
|
|
**Default Roles**:
|
|
|
|
| Role | Certificate OU | Permissions |
|
|
|------|---------------|-------------|
|
|
| `platform` | `platform-team` | Full access (CRUD + list) |
|
|
| `automation` | `automation` | Create, read, update, list |
|
|
| `plugin` | `plugins` | Read, list only |
|
|
|
|
### Permissions
|
|
|
|
| Permission | Operations | Required For |
|
|
|------------|-----------|--------------|
|
|
| `entity:create` | Create new entities | CreateEntity |
|
|
| `entity:read` | Get entity by ID | GetEntity |
|
|
| `entity:update` | Modify entities | UpdateEntity |
|
|
| `entity:delete` | Remove entities | DeleteEntity |
|
|
| `entity:list` | List all entities | ListEntities |
|
|
|
|
## Plugin System
|
|
|
|
Core features (catalog, vulnerabilities, compliance) are **native**. Plugins handle **integrations** with external systems.
|
|
|
|
### Plugin Architecture
|
|
|
|
```mermaid
|
|
graph LR
|
|
A[Entity/Vuln Event] --> B[Event Bus]
|
|
B --> C{Plugin Manager}
|
|
C --> D[Slack Plugin]
|
|
C --> E[Jira Plugin]
|
|
C --> F[Custom Plugin]
|
|
|
|
D --> G[Slack API]
|
|
E --> H[Jira API]
|
|
F --> I[Your Tool API]
|
|
|
|
style C fill:#4A90E2,stroke:#2E5C8A
|
|
```
|
|
|
|
### What's Native vs. Plugin
|
|
|
|
| Native (core) | Status | Plugin (integration) | Status |
|
|
|---|---|---|---|
|
|
| Software catalog | Done | DefectDojo sync | Done |
|
|
| Vulnerability management | Phase 1 | Keycloak user sync | Done |
|
|
| Security gates & rules | Phase 1 | Slack / Teams notifications | Planned |
|
|
| Assessment workflow | Phase 1 | Jira / GitHub issue creation | Planned |
|
|
| License compliance | Phase 2 | Custom integrations | Framework ready |
|
|
| TechDocs | Future | | |
|
|
|
|
### Plugin Lifecycle
|
|
|
|
1. **Configuration** - Load plugin settings from `plugins.toml`
|
|
2. **Initialization** - Plugin registers event handlers
|
|
3. **Event Processing** - Plugin receives events asynchronously (entity, vulnerability, gate events)
|
|
4. **External Integration** - Plugin calls external tool APIs
|
|
5. **Error Handling** - Failed plugins don't affect core service
|
|
|
|
### Plugin Configuration
|
|
|
|
Example `plugins.toml`:
|
|
|
|
```toml
|
|
[plugins.slack]
|
|
enabled = true
|
|
webhook_url = "${SLACK_WEBHOOK_URL}"
|
|
|
|
[[plugins.slack.on_gate_failed]]
|
|
channel = "#security-alerts"
|
|
|
|
[[plugins.slack.on_entity_created]]
|
|
channel = "#platform"
|
|
```
|
|
|
|
See [Plugin Guide](plugins.md) for details.
|
|
|
|
## Data Consistency
|
|
|
|
### Eventual Consistency
|
|
|
|
Charybdis uses **eventual consistency** for plugin integrations:
|
|
|
|
- Entity CRUD operations are **immediately consistent**
|
|
- Plugin synchronization is **eventually consistent**
|
|
- Events are processed **asynchronously**
|
|
|
|
```mermaid
|
|
graph LR
|
|
A[CreateEntity] -->|Immediate| B[Entity Stored]
|
|
B -->|Async| C[Event Emitted]
|
|
C -->|Async| D[Plugin Processing]
|
|
D -->|Eventual| E[External Tool Synced]
|
|
|
|
style B fill:#00C851
|
|
style E fill:#ffbb33
|
|
```
|
|
|
|
### Guarantees
|
|
|
|
| Operation | Consistency | Guarantee |
|
|
|-----------|-------------|-----------|
|
|
| Entity CRUD | Strong | Immediate |
|
|
| Entity queries | Strong | Read-your-writes |
|
|
| Event delivery | At-least-once | May retry |
|
|
| Plugin sync | Eventual | Best-effort |
|
|
|
|
## Performance Characteristics
|
|
|
|
### Scalability
|
|
|
|
- **Entities**: Tested with 100,000+ entities
|
|
- **Throughput**: 1,000+ requests/second
|
|
- **Latency**: Sub-millisecond average
|
|
- **Concurrency**: Tokio async runtime
|
|
|
|
### Resource Usage
|
|
|
|
Typical resource consumption:
|
|
|
|
| Component | CPU | Memory | Storage |
|
|
|-----------|-----|--------|---------|
|
|
| Charybdis | < 5% | ~50 MB | Minimal |
|
|
| PostgreSQL | ~10% | ~256 MB | Depends on entity count |
|
|
|
|
### Optimization Tips
|
|
|
|
1. **Index annotations** used for frequent queries
|
|
2. **Use connection pooling** (built-in)
|
|
3. **Enable query caching** in PostgreSQL
|
|
4. **Monitor event bus** queue depth
|
|
|
|
## Backstage Migration
|
|
|
|
Charybdis includes a YAML adapter for teams migrating from Backstage. This is a **migration path**, not the primary interface.
|
|
|
|
### How It Works
|
|
|
|
```mermaid
|
|
graph LR
|
|
A[Charybdis Entity] --> B[YAML Adapter]
|
|
B --> C[Backstage YAML Format]
|
|
C --> D[Backstage Catalog]
|
|
|
|
style B fill:#4A90E2,stroke:#2E5C8A
|
|
```
|
|
|
|
Point Backstage at Charybdis and stop maintaining `catalog-info.yaml` files:
|
|
|
|
```yaml
|
|
catalog:
|
|
locations:
|
|
- type: url
|
|
target: http://charybdis:8080/yaml/locations
|
|
```
|
|
|
|
### Recommended Migration Path
|
|
|
|
1. **Start** with Charybdis + YAML adapter feeding your existing Backstage
|
|
2. **Adopt** Charybdis gRPC API for CI/CD integrations and security scanning
|
|
3. **Leverage** event-driven plugins for auto-provisioning (DefectDojo, Jira, etc.)
|
|
4. **Optionally retire** Backstage when Charybdis covers your catalog needs
|
|
|
|
## Best Practices
|
|
|
|
### Entity Design
|
|
|
|
✅ **DO**:
|
|
- Use descriptive names
|
|
- Group by namespace
|
|
- Add relevant labels
|
|
- Include documentation links
|
|
- Set appropriate owners
|
|
|
|
❌ **DON'T**:
|
|
- Store sensitive data in metadata
|
|
- Use very long descriptions
|
|
- Create deeply nested hierarchies
|
|
- Duplicate data across entities
|
|
|
|
### Naming Conventions
|
|
|
|
```
|
|
<entity-type>-<purpose>-<environment>
|
|
|
|
Examples:
|
|
- payment-api-prod
|
|
- user-service-staging
|
|
- auth-library
|
|
- e-commerce-system
|
|
```
|
|
|
|
### Metadata Organization
|
|
|
|
```json
|
|
{
|
|
"labels": {
|
|
"team": "payments", // Ownership
|
|
"tier": "critical", // Importance
|
|
"environment": "production" // Deployment
|
|
},
|
|
"tags": ["pci-compliant", "public-api"],
|
|
"links": [
|
|
{ "url": "...", "title": "Dashboard" },
|
|
{ "url": "...", "title": "Documentation" }
|
|
]
|
|
}
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
- Read the [Vision & Roadmap](../VISION.md) to understand where Charybdis is going
|
|
- Configure [Security](security.md) for production (mTLS + RBAC)
|
|
- Explore [Plugins](plugins.md) for external integrations
|
|
- Review the [Architecture](architecture.md) for technical deep dive
|
|
|
|
---
|
|
|
|
**Questions?** [Open an issue](../../issues).
|