initial-commit

This commit is contained in:
Guillaume GRABÉ
2026-05-12 17:06:43 +02:00
commit 051a080dfa
110 changed files with 26377 additions and 0 deletions
Executable
+222
View File
@@ -0,0 +1,222 @@
#!/bin/bash
set -e
# Run from the deploy/ directory
cd "$(dirname "$0")"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}"
cat << "EOF"
______ __ __ ___
/ ____// /_ ____ _ _____ __ __ / /_ ____/ (_)____
/ / / __ \ / __ `// ___// / / // __ \ / __ // // __ \
/ /___ / / / // /_/ // / / /_/ // /_/ // /_/ // // /_/ /
\____//_/ /_/ \__,_//_/ \__, //_.___/ \__,_//_/ \____/
/____/
EOF
echo -e "${NC}"
echo -e "${GREEN}Charybdis Demo${NC}\n"
# Detect gRPC client
GRPC_CMD=""
if command -v buf &> /dev/null; then
GRPC_CMD="buf"
elif command -v grpcurl &> /dev/null; then
GRPC_CMD="grpcurl"
else
echo -e "${RED}Error: Neither 'buf' nor 'grpcurl' found. Install one:${NC}"
echo -e " brew install bufbuild/buf/buf"
echo -e " brew install grpcurl"
exit 1
fi
echo -e "${BLUE}Using gRPC client: ${GRPC_CMD}${NC}\n"
# Helper function for gRPC calls
grpc_call() {
local service_method="$1"
local data="$2"
local host="${3:-localhost:50051}"
if [ "$GRPC_CMD" = "buf" ]; then
buf curl --protocol grpc --http2-prior-knowledge \
-d "$data" \
"http://${host}/${service_method}" 2>&1
else
grpcurl -plaintext -d "$data" "$host" "$service_method" 2>&1
fi
}
# Check if Docker is running
if ! docker info > /dev/null 2>&1; then
echo -e "${RED}Error: Docker is not running. Please start Docker first.${NC}"
exit 1
fi
echo -e "${BLUE}Starting services...${NC}\n"
# Start core services (Charybdis + Postgres only for quick demo)
docker compose -f docker-compose.demo.yml up -d postgres-charybdis 2>/dev/null
echo -e "${GREEN} Postgres started${NC}"
# Wait for Postgres
for i in {1..15}; do
if docker compose -f docker-compose.demo.yml exec -T postgres-charybdis pg_isready -U charybdis > /dev/null 2>&1; then
break
fi
sleep 1
done
docker compose -f docker-compose.demo.yml up -d charybdis 2>/dev/null
echo -e "${GREEN} Charybdis started${NC}"
# Wait for Charybdis gRPC
echo -e "\n${BLUE}Waiting for Charybdis to be ready...${NC}"
for i in {1..30}; do
if timeout 2 bash -c "echo > /dev/tcp/localhost/50051" 2>/dev/null; then
echo -e "${GREEN} gRPC server ready on :50051${NC}"
break
fi
if [ $i -eq 30 ]; then
echo -e "${RED} Charybdis failed to start${NC}"
docker compose -f docker-compose.demo.yml logs charybdis | tail -10
exit 1
fi
sleep 1
done
sleep 2 # Allow service to fully initialize
# --- Demo: Entity Management ---
echo -e "\n${BLUE}=== Entity Management ===${NC}\n"
echo -e "${YELLOW}1. Creating a Component...${NC}"
RESULT=$(grpc_call "charybdis.entities.EntityService/CreateEntity" '{
"entity": {
"kind": "Component",
"component_metadata": {
"name": "payment-service",
"namespace": "default",
"description": "Payment processing microservice"
},
"component_spec": {
"type": "service",
"lifecycle": "production",
"owner": "team-payments"
}
}
}')
echo "$RESULT" | head -5
ENTITY_ID=$(echo "$RESULT" | grep '"id"' | head -1 | sed 's/.*"id": *"//;s/".*//')
echo -e "${GREEN} Created entity: ${ENTITY_ID}${NC}\n"
echo -e "${YELLOW}2. Listing entities...${NC}"
grpc_call "charybdis.entities.EntityService/ListEntities" '{}' | head -5
echo -e ""
# --- Demo: Vulnerability Ingestion ---
echo -e "\n${BLUE}=== Vulnerability Ingestion ===${NC}\n"
# Create a SARIF report
SARIF_REPORT=$(cat << 'SARIF'
{
"version": "2.1.0",
"runs": [{
"tool": {"driver": {"name": "semgrep", "version": "1.0.0", "rules": [
{"id": "sql-injection", "shortDescription": {"text": "SQL Injection"}, "defaultConfiguration": {"level": "error"}, "properties": {"tags": ["CWE-89"]}},
{"id": "xss-reflected", "shortDescription": {"text": "Reflected XSS"}, "defaultConfiguration": {"level": "warning"}, "properties": {"tags": ["CWE-79"]}},
{"id": "hardcoded-secret", "shortDescription": {"text": "Hardcoded Secret"}, "defaultConfiguration": {"level": "error"}}
]}},
"results": [
{"ruleId": "sql-injection", "level": "error", "message": {"text": "User input in SQL query without parameterization"}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/db/queries.rs"}, "region": {"startLine": 42}}}], "partialFingerprints": {"primaryLocationLineHash": "fp-sql-001"}},
{"ruleId": "xss-reflected", "level": "warning", "message": {"text": "User input reflected in response without encoding"}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/handlers/search.rs"}, "region": {"startLine": 18}}}]},
{"ruleId": "hardcoded-secret", "level": "error", "message": {"text": "AWS secret key found in source code"}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/config.rs"}, "region": {"startLine": 7}}}]}
]
}]
}
SARIF
)
SARIF_B64=$(echo "$SARIF_REPORT" | base64)
echo -e "${YELLOW}3. Dry-run scan (preview without persisting)...${NC}"
grpc_call "charybdis.ingestion.IngestionService/DryRunScan" "{
\"component_ref\": \"payment-service\",
\"lifecycle\": \"production\",
\"format\": \"sarif\",
\"data\": \"${SARIF_B64}\"
}"
echo -e ""
echo -e "${YELLOW}4. Importing scan (persisting findings)...${NC}"
grpc_call "charybdis.ingestion.IngestionService/ImportScan" "{
\"component_ref\": \"payment-service\",
\"lifecycle\": \"production\",
\"format\": \"sarif\",
\"data\": \"${SARIF_B64}\"
}"
echo -e ""
echo -e "${YELLOW}5. Re-importing same scan (testing deduplication)...${NC}"
grpc_call "charybdis.ingestion.IngestionService/ImportScan" "{
\"component_ref\": \"payment-service\",
\"lifecycle\": \"production\",
\"format\": \"sarif\",
\"data\": \"${SARIF_B64}\"
}"
echo -e ""
# Simulate a fix: remove the SQL injection finding
SARIF_FIXED=$(cat << 'SARIF'
{
"version": "2.1.0",
"runs": [{
"tool": {"driver": {"name": "semgrep", "version": "1.0.0", "rules": [
{"id": "xss-reflected", "shortDescription": {"text": "Reflected XSS"}, "defaultConfiguration": {"level": "warning"}, "properties": {"tags": ["CWE-79"]}},
{"id": "hardcoded-secret", "shortDescription": {"text": "Hardcoded Secret"}, "defaultConfiguration": {"level": "error"}}
]}},
"results": [
{"ruleId": "xss-reflected", "level": "warning", "message": {"text": "User input reflected in response without encoding"}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/handlers/search.rs"}, "region": {"startLine": 18}}}]},
{"ruleId": "hardcoded-secret", "level": "error", "message": {"text": "AWS secret key found in source code"}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/config.rs"}, "region": {"startLine": 7}}}]}
]
}]
}
SARIF
)
SARIF_FIXED_B64=$(echo "$SARIF_FIXED" | base64)
echo -e "${YELLOW}6. Importing scan after fix (SQL injection resolved)...${NC}"
grpc_call "charybdis.ingestion.IngestionService/ImportScan" "{
\"component_ref\": \"payment-service\",
\"lifecycle\": \"production\",
\"format\": \"sarif\",
\"data\": \"${SARIF_FIXED_B64}\"
}"
echo -e ""
# --- Summary ---
echo -e "\n${GREEN}=== Demo Complete ===${NC}\n"
echo -e "${BLUE}What we demonstrated:${NC}"
echo -e " 1. Created a Component entity via gRPC"
echo -e " 2. Dry-run scan: preview findings without persisting"
echo -e " 3. Import scan: persist 3 findings (SQL injection, XSS, hardcoded secret)"
echo -e " 4. Deduplication: re-import same scan -> all unchanged"
echo -e " 5. Auto-resolution: import without SQL injection -> marked as resolved"
echo ""
echo -e "${BLUE}Access:${NC}"
echo -e " gRPC: localhost:50051"
echo -e " YAML Adapter: http://localhost:8081"
echo ""
echo -e "${BLUE}Stop:${NC}"
echo -e " docker compose -f docker-compose.demo.yml down"
echo ""
echo -e "${BLUE}Clean up:${NC}"
echo -e " docker compose -f docker-compose.demo.yml down -v"
echo ""