{"id":34636710,"url":"https://github.com/fullstack-pw/cks-backend","last_synced_at":"2026-02-04T09:01:14.632Z","repository":{"id":296564895,"uuid":"993644047","full_name":"fullstack-pw/cks-backend","owner":"fullstack-pw","description":null,"archived":false,"fork":false,"pushed_at":"2025-11-17T07:21:11.000Z","size":148,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-17T09:15:27.154Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fullstack-pw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-31T07:44:49.000Z","updated_at":"2025-11-17T07:21:15.000Z","dependencies_parsed_at":"2025-06-01T04:03:01.330Z","dependency_job_id":"ad25bea5-7bc5-4932-9648-270e643e9f5e","html_url":"https://github.com/fullstack-pw/cks-backend","commit_stats":null,"previous_names":["fullstack-pw/cks-backend"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/fullstack-pw/cks-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fullstack-pw%2Fcks-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fullstack-pw%2Fcks-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fullstack-pw%2Fcks-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fullstack-pw%2Fcks-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fullstack-pw","download_url":"https://codeload.github.com/fullstack-pw/cks-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fullstack-pw%2Fcks-backend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28005408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-24T17:02:25.822Z","updated_at":"2025-12-24T17:03:31.273Z","avatar_url":"https://github.com/fullstack-pw.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CKS Backend\n\nGo-based backend service for the Certified Kubernetes Security Specialist (CKS) training platform. Implements cluster pool management, snapshot-based VM restoration, and automated validation for security scenarios using KubeVirt.\n\n## Architecture Overview\n\nProduction-grade Kubernetes-native learning platform that provisions isolated practice environments using KubeVirt virtual machines. The system implements a cluster pool pattern with snapshot-based restoration to provide sub-second session allocation while maintaining cost efficiency through resource sharing.\n\n### Core Components\n\n**Cluster Pool Manager** (`src/internal/clusterpool/`)\n- Pre-provisions fixed pool of 3 Kubernetes clusters (control-plane + worker VMs)\n- State persistence via Kubernetes namespace annotations (`cks.io/cluster-status`, `cks.io/last-reset`)\n- Thread-safe cluster assignment using RWMutex for race-free operations\n- Snapshot-based reset workflow achieving 5x faster restoration (2-3 minutes vs 10-15 minutes)\n- Automatic cleanup of VirtualMachineRestore objects and associated PVCs to prevent storage exhaustion\n\n**Session Manager** (`src/internal/sessions/`)\n- Handles complete session lifecycle from cluster assignment to resource cleanup\n- Creates dedicated Kubernetes namespace per session with resource quotas (16 cores, 16Gi memory, 20 pods)\n- Background expiration monitoring via goroutine running every 5 minutes\n- Deterministic terminal ID generation (`{sessionID}-{target}`) enabling frontend reconnection\n- Asynchronous scenario initialization allowing immediate user access to pre-bootstrapped clusters\n\n**Scenario System** (`src/internal/scenarios/`)\n- Filesystem-based scenario loading from structured directory tree\n- YAML-defined scenarios with metadata, tasks, validation rules, and setup steps\n- Markdown task descriptions parsed with objectives, hints, and step-by-step guides\n- Template-based VM generation with variable substitution (20+ configurable parameters)\n- Hot-reload capability via `/api/v1/scenarios/reload` endpoint\n\n**Unified Validation Engine** (`src/internal/validation/`)\n- Multi-strategy validator supporting resource existence, kubectl commands, script execution, and file content checks\n- SSH integration via `virtctl ssh` for command execution and file validation\n- Condition types: equals, contains, exists, not_exists, greater_than, less_than, matches_regex\n- Consistent ValidationResponse format with detailed results per rule\n\n**KubeVirt Integration** (`src/internal/kubevirt/`)\n- VM creation from golden image PVC using DataVolume cloning\n- Cloud-init templating with dynamic join command extraction for worker node provisioning\n- Snapshot operations (create, wait for ready, restore) with comprehensive error handling\n- Advanced cleanup strategy for VirtualMachineRestore artifacts preventing PVC accumulation\n- Context management workaround for `virtctl ssh` (creates temp kubeconfig with correct current-context)\n\n## DevOps Practices\n\n### Immutable Infrastructure\n\n**Golden Image Pattern**\n- Base VM image (`ubuntu-2204-kube`) pre-installed with Kubernetes 1.33.0\n- All clusters clone from identical golden PVC ensuring consistency\n- Fast provisioning (PVC clone ~60s vs full kubeadm init ~10-15 minutes)\n- Image stored in dedicated namespace (`vm-templates`) with lifecycle management\n\n**Snapshot-Based Restoration**\n- Baseline snapshots created after initial cluster bootstrap\n- Reset workflow: Stop VMs → Cleanup old restores → Create VirtualMachineRestore → Wait for complete → Start VMs\n- Immutable baseline state prevents configuration drift\n- CoW (Copy-on-Write) snapshots minimize storage overhead\n\n### Kubernetes-Native State Management\n\n**Persistent State via Annotations**\n```go\nnamespace.Annotations[\"cks.io/cluster-status\"] = \"available|locked|resetting|error\"\nnamespace.Annotations[\"cks.io/last-reset\"] = \"2025-11-15T10:30:00Z\"\nnamespace.Annotations[\"cks.io/created-at\"] = \"2025-11-15T08:00:00Z\"\n```\n\nBenefits:\n- Survives pod restarts without external database\n- Atomic updates via Kubernetes API\n- Distributed consensus via etcd\n- Queryable via kubectl for debugging\n\n**In-Memory Cache with Persistent Fallback**\n- ClusterPoolManager maintains in-memory state for O(1) lookups\n- On initialization, reads annotations to reconstruct state\n- Writes to both in-memory and namespace annotations\n\n### Multi-Stage Docker Build\n\n**Build Stage** (golang:1.24-alpine)\n```dockerfile\nCGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \\\n  -ldflags='-w -s -extldflags \"-static\"' \\\n  -a -installsuffix cgo \\\n  -o server ./cmd/server\n```\n- Static binary with no C dependencies\n- Stripped debug symbols (`-w -s`) reducing size by ~30%\n- Cross-compilation for Linux amd64\n\n**Runtime Stage** (alpine:3.19)\n- Non-root user execution (UID 1001)\n- Minimal tooling: kubectl, virtctl, openssh\n- Health check endpoint configured\n- Final image ~150MB vs ~800MB with full Go environment\n\n### GitOps CI/CD Pipeline\n\n**Automated Pipeline** (`.github/workflows/pipeline.yml`)\n\nJob Flow:\n1. **docker-build-and-push**: Multi-stage build, push to `registry.fullstack.pw/library/cks-backend` with commit SHA + latest tags\n2. **dev-deploy**: Kustomize overlay deployment to development cluster\n3. **versioning**: Semantic version calculation from commit messages, GitHub release creation\n\n**Deployment Strategy**\n- Kustomize base + overlays pattern (dev/stg/prod)\n- Environment-specific configurations via ConfigMap\n- Init container for SSH key setup (copy to writable volume with correct permissions)\n- Resource quotas: 100m-200m CPU, 128Mi-256Mi memory\n- Readiness/liveness probes on `/health` endpoint\n\n**Secret Management**\n- Kubernetes secrets for kubeconfig and SSH private key\n- Mounted read-only, copied by init container\n- Never logged or exposed in error messages\n\n### Observability\n\n**Structured Logging** (logrus)\n```go\nlogger.WithFields(logrus.Fields{\n  \"sessionID\": sessionID,\n  \"clusterID\": clusterID,\n  \"operation\": \"reset\",\n  \"duration\": elapsed,\n}).Info(\"Cluster reset completed\")\n```\n\n**Metrics Exposure**\n- Prometheus endpoint at `/metrics`\n- Go runtime metrics (goroutines, memory, GC)\n- Custom metrics: session count, cluster pool status, validation duration\n\n**Health Checks**\n- `/health` endpoint for Kubernetes probes\n- VM readiness polling with fallback heuristics\n- Background health monitoring (5-minute interval)\n\n### Resilience Patterns\n\n**Exponential Backoff Retry**\n```go\nRetryConfig{\n  MaxRetries: 3,\n  Delay: 10s,\n  Backoff: 2.0  // 10s, 20s, 40s\n}\n```\nApplied to:\n- Cloud-init secret creation\n- VM creation\n- Join command extraction\n- SSH command execution\n\n**Graceful Degradation**\n- Scenario initialization failures don't block session creation\n- Failed cluster resets marked as `StatusError` requiring manual intervention\n- Cleanup failures logged but don't prevent session deletion\n\n**Resource Cleanup**\n- Automatic session expiration (60-minute timeout, extendable)\n- Orphaned PVC detection via regex pattern matching\n- Background cleanup goroutine with graceful shutdown on SIGTERM\n\n## Technical Innovations\n\n### Deterministic Terminal IDs\n\nTraditional UUID-based terminal IDs prevent reconnection after disconnect. Implementation uses predictable IDs:\n\n```go\nterminalID := fmt.Sprintf(\"%s-%s\", sessionID, target)\n// Example: \"abc123-control-plane\", \"abc123-worker-node\"\n```\n\nBenefits:\n- Frontend knows terminal ID before connection\n- Seamless reconnection after network interruption\n- No server-side session storage required\n\n### Cluster Pool Architecture\n\n```\nPool State Machine:\n┌─────────────────────────────────────────────────┐\n│ available → locked → resetting → available      │\n│               ↓                                  │\n│             error (manual recovery)              │\n└─────────────────────────────────────────────────┘\n```\n\n**Allocation Flow**:\n1. Linear search for first available cluster (O(n) with n=3)\n2. Atomic status transition to `locked`\n3. Return cluster metadata (namespace, VM names, network config)\n4. Session inherits pre-bootstrapped infrastructure\n\n**Reset Flow**:\n1. Mark as `resetting` (persistent write)\n2. Stop VMs (20-minute timeout)\n3. Delete old VirtualMachineRestore + restore-* PVCs\n4. Create new VirtualMachineRestore objects\n5. Wait for restore completion\n6. Start VMs\n7. Mark as `available`\n\n**Performance Characteristics**:\n- Session creation WITH pool: \u003c1 second\n- Session creation WITHOUT pool: 10-15 minutes\n- Cluster reset: 2-3 minutes\n- Concurrent sessions: Limited by pool size (3)\n\n### Cloud-Init Template System\n\n**Variable Substitution**:\n```go\nsubstituteEnvVars(template, map[string]string{\n  \"CONTROL_PLANE_VM_NAME\": \"cp-cluster1\",\n  \"K8S_VERSION\": \"1.33.0\",\n  \"POD_CIDR\": \"10.0.0.0/8\",\n  \"JOIN_COMMAND\": \"kubeadm join ...\",  // Extracted from control-plane\n})\n```\n\n**Join Command Extraction** (worker node provisioning):\n1. Wait 60s for control-plane kubelet initialization\n2. SSH execute: `cat /etc/kubeadm-join-command`\n3. Retry with exponential backoff on failure\n4. Inject into worker cloud-init\n5. Worker automatically joins cluster on boot\n\n### Unified Validation Engine\n\nSingle interface supporting multiple validation strategies:\n\n**Resource Existence**:\n```go\nkubectl get Pod nginx -n default\n// Parse output for \"NotFound\" or error\n```\n\n**Script Execution**:\n```go\n// 1. Create temp script: /tmp/validation-{sessionID}-{ruleID}.sh\n// 2. Execute via SSH\n// 3. Parse exit code from stdout\n// 4. Cleanup temp file\n```\n\n**File Content**:\n```go\n// 1. SSH cat /path/to/file\n// 2. Check condition (contains, equals, regex)\n```\n\nBenefits:\n- Consistent error handling across all types\n- Extensible: New validators implement same interface\n- Detailed results: expected vs actual values, error codes\n- Timeout protection via context cancellation\n\n## Cluster Bootstrap Process\n\nComplete VM cluster creation pipeline:\n\n**1. Golden Image Validation**\n- Check PVC exists: `{GoldenImageNamespace}/{GoldenImageName}`\n- Fail early if missing\n\n**2. Control Plane Creation**\n- Create cloud-init secret with variables (K8S_VERSION, POD_CIDR, VM_NAME)\n- Create VirtualMachine with DataVolume (clone source: golden PVC)\n- Wait for VM ready (15-minute timeout, poll every 10s)\n- Ready conditions: `VM.Status.Ready=true` OR `VMI.Status.Phase=Running` for \u003e60s\n\n**3. Join Command Extraction**\n- Wait 60s for kubelet initialization\n- SSH: `cat /etc/kubeadm-join-command` (written by cloud-init)\n- Retry with exponential backoff (3 attempts)\n\n**4. Worker Node Creation**\n- Create cloud-init secret with JOIN_COMMAND, CONTROL_PLANE_IP, ENDPOINT\n- Create VirtualMachine (clone golden PVC)\n- Wait for VM ready\n- Worker automatically joins cluster via cloud-init\n\n**5. Network Configuration**\n- Pod CIDR: 10.0.0.0/8 (configurable)\n- CNI installed via cloud-init (Calico/Flannel)\n- Service network: Kubernetes default\n\n## Task Configuration and Validation\n\n### Scenario Structure\n\n```\nscenarios/\n├── basic-pod-security/\n│   ├── metadata.yaml          # Scenario metadata\n│   ├── tasks/\n│   │   ├── 01-task.md        # Task 1 (Markdown)\n│   │   ├── 02-task.md        # Task 2\n│   │   └── 03-task.md        # Task 3\n│   ├── validation/\n│   │   ├── 01-validation.yaml  # Task 1 validation rules\n│   │   ├── 02-validation.yaml  # Task 2 validation rules\n│   │   └── 03-validation.yaml  # Task 3 validation rules\n│   └── setup/\n│       └── init.yaml          # Setup steps (kubectl apply, scripts)\n```\n\n### Task Markdown Format\n\n```markdown\n# Enforce Pod Security Standards\n\n## Description\nConfigure Pod Security Admission in the test-pods namespace.\n\n## Objectives\n- Create namespace with pod-security labels\n- Verify enforcement with test pod\n- Document security context requirements\n\n## Step-by-Step Guide\n1. Create namespace: `kubectl create namespace test-pods`\n2. Label namespace: `kubectl label namespace test-pods pod-security.kubernetes.io/enforce=baseline`\n\n## Hints\n\u003cdetails\u003e\n\u003csummary\u003eCheck current labels\u003c/summary\u003e\nUse kubectl get namespace test-pods -o yaml to view current configuration.\n\u003c/details\u003e\n```\n\nParser extracts sections by H2 headers, handles nested lists, and processes `\u003cdetails\u003e` blocks for collapsible hints.\n\n### Validation Rules\n\n```yaml\nvalidation:\n  - id: namespace-exists\n    type: resource_exists\n    resource:\n      kind: Namespace\n      name: test-pods\n    errorMessage: \"Namespace test-pods not found\"\n\n  - id: enforce-label\n    type: resource_property\n    resource:\n      kind: Namespace\n      name: test-pods\n      property: .metadata.labels.pod-security\\.kubernetes\\.io/enforce\n    condition: equals\n    value: \"baseline\"\n    errorMessage: \"Pod Security enforcement label not set correctly\"\n\n  - id: verify-runtime\n    type: script\n    script:\n      script: |\n        #!/bin/bash\n        kubectl run test-pod --image=nginx --namespace=test-pods 2\u003e\u00261 | grep -q \"violates\"\n        test $? -eq 0  # Should violate security policy\n      target: control-plane\n      successCode: 0\n    errorMessage: \"Pod Security Standards not enforced at runtime\"\n```\n\n**Validation Execution Flow**:\n1. User clicks \"Validate Task\" in frontend\n2. POST `/api/v1/sessions/{sessionID}/tasks/{taskID}/validate`\n3. SessionManager loads scenario and task\n4. UnifiedValidator processes each validation rule\n5. Results aggregated into ValidationResponse\n6. Task status updated: \"pending\" → \"completed\" or \"failed\"\n7. Frontend displays results with expected vs actual values\n\n## Admin Panel Functionality\n\nThe admin dashboard provides cluster pool and session management capabilities exposed via `/api/v1/admin/*` endpoints.\n\n### Cluster Pool Management\n\n**GET /api/v1/admin/clusters**\n```json\n[\n  {\n    \"id\": \"cluster1\",\n    \"status\": \"locked\",\n    \"sessionId\": \"abc123\",\n    \"namespace\": \"cluster1\",\n    \"lockTime\": \"2025-11-15T10:30:00Z\",\n    \"lastReset\": \"2025-11-15T08:00:00Z\"\n  },\n  {\n    \"id\": \"cluster2\",\n    \"status\": \"available\",\n    \"sessionId\": null,\n    \"namespace\": \"cluster2\"\n  },\n  {\n    \"id\": \"cluster3\",\n    \"status\": \"resetting\",\n    \"sessionId\": null,\n    \"namespace\": \"cluster3\"\n  }\n]\n```\n\n**POST /api/v1/admin/bootstrap-pool**\n- Creates baseline clusters (cp-{clusterID} + wk-{clusterID})\n- Intended for initial setup or disaster recovery\n- Blocks until all 3 clusters ready (can take 30-45 minutes)\n\n**POST /api/v1/admin/create-snapshots**\n- Creates VirtualMachineSnapshot objects for all cluster VMs\n- Snapshot names: `cp-cluster1-snapshot`, `wk-cluster1-snapshot`, etc.\n- Waits for all snapshots to reach ReadyToUse status\n- Must be run after bootstrap and before first session\n\n**POST /api/v1/admin/release-all-clusters**\n- Forces release of all locked clusters\n- Triggers async reset for each cluster\n- Use case: Emergency cleanup, testing, maintenance\n\n### Session Management\n\n**GET /api/v1/admin/sessions**\n```json\n[\n  {\n    \"id\": \"abc123\",\n    \"scenarioId\": \"basic-pod-security\",\n    \"clusterId\": \"cluster1\",\n    \"namespace\": \"cluster1\",\n    \"status\": \"running\",\n    \"createdAt\": \"2025-11-15T10:30:00Z\",\n    \"expiresAt\": \"2025-11-15T11:30:00Z\",\n    \"controlPlaneVM\": \"cp-cluster1\",\n    \"workerVM\": \"wk-cluster1\",\n    \"tasks\": [\n      {\"id\": \"task-1\", \"status\": \"completed\"},\n      {\"id\": \"task-2\", \"status\": \"pending\"}\n    ],\n    \"activeTerminals\": {\n      \"control-plane\": \"abc123-control-plane\",\n      \"worker-node\": \"abc123-worker-node\"\n    }\n  }\n]\n```\n\n**DELETE /api/v1/admin/sessions/{sessionID}**\n- Force delete session regardless of expiration\n- Releases cluster back to pool\n- Triggers cluster reset\n\n## Technology Stack\n\n**Core**\n- Go 1.24.0 (static binary compilation)\n- Gin Web Framework 1.10.0 (HTTP routing, middleware)\n- Kubernetes Client-Go 0.31.8 (API interactions)\n- KubeVirt Client-Go 1.5.0 (VM management)\n\n**Infrastructure**\n- KubeVirt 1.5+ (VM orchestration)\n- Longhorn (storage class for PVCs)\n- Istio (ingress, VirtualService routing)\n- Cert-Manager (automatic TLS certificates)\n\n**Observability**\n- Logrus 1.9.3 (structured logging)\n- Prometheus client_golang 1.19.1 (metrics)\n\n**Utilities**\n- gorilla/websocket 1.5.4 (terminal sessions)\n- creack/pty 1.1.24 (pseudo-terminal)\n- google/uuid 1.6.0 (session IDs)\n\n## Environment Configuration\n\nKey environment variables:\n\n| Variable | Purpose | Default |\n|----------|---------|---------|\n| `KUBERNETES_CONTEXT` | Target cluster context | `sandboxy` |\n| `KUBECONFIG` | Path to kubeconfig | `~/.kube/config` |\n| `KUBERNETES_VERSION` | K8s version for VMs | `1.33.0` |\n| `VM_CPU_CORES` | CPU per VM | `2` |\n| `VM_MEMORY` | Memory per VM | `2Gi` |\n| `VM_STORAGE_SIZE` | Disk per VM | `10Gi` |\n| `VM_STORAGE_CLASS` | Storage class | `longhorn` |\n| `GOLDEN_IMAGE_NAME` | Base image PVC name | `new-golden-image-1-33-0` |\n| `GOLDEN_IMAGE_NAMESPACE` | Image PVC namespace | `vm-templates` |\n| `POD_CIDR` | Pod network CIDR | `10.0.0.0/8` |\n| `SESSION_TIMEOUT_MINUTES` | Session duration | `60` |\n| `CLEANUP_INTERVAL_MINUTES` | Cleanup frequency | `5` |\n\n## Deployment Architecture\n\n**Kubernetes Manifests** (`kustomize/base/`)\n\n**Deployment**:\n- Init container: Copies SSH key from secret to writable volume with correct permissions\n- Main container: Runs as UID 1001, mounts kubeconfig + SSH key\n- Resources: 100m-200m CPU, 128Mi-256Mi memory\n- Probes: Readiness (5s delay, 10s period), Liveness (15s delay, 20s period)\n\n**Service**:\n- Type: ClusterIP\n- Port: 8080 → targetPort: 8080\n\n**VirtualService** (Istio):\n- Routes traffic from ingress gateway to service\n- TLS termination via cert-manager annotation\n- Path-based routing: All paths to cks-backend service\n\n**ConfigMap**:\n- Environment variables for runtime configuration\n- Overlay pattern: base values, environment-specific overrides\n\n**Secrets**:\n- `cluster-secrets`: kubeconfig + SSH private key\n- Mounted read-only, copied by init container\n\n## Repository Structure\n\n```\ncks-backend/\n├── src/\n│   ├── cmd/server/main.go           # Application entry point\n│   ├── internal/\n│   │   ├── clusterpool/manager.go   # Cluster pool state machine\n│   │   ├── sessions/session_manager.go  # Session lifecycle\n│   │   ├── scenarios/scenario_manager.go  # Scenario loading\n│   │   ├── validation/unified_validator.go  # Validation engine\n│   │   ├── kubevirt/client.go       # KubeVirt operations\n│   │   ├── terminal/terminal_manager.go  # WebSocket SSH\n│   │   ├── controllers/             # HTTP handlers\n│   │   ├── services/                # Business logic\n│   │   └── models/models.go         # Data structures\n│   ├── scenarios/                   # CKS training scenarios\n│   │   ├── basic-pod-security/\n│   │   ├── falco-runtime-security/\n│   │   └── categories.yaml\n│   └── templates/                   # VM templates\n│       ├── control-plane-template.yaml\n│       ├── worker-node-template.yaml\n│       └── cloud-config files\n├── kustomize/                       # Kubernetes deployment\n│   ├── base/\n│   └── overlays/{dev,stg,prod}/\n├── .github/workflows/               # CI/CD pipelines\n├── Dockerfile                       # Multi-stage build\n└── go.mod                          # Dependencies\n```\n\n## Performance Characteristics\n\n**Session Operations**:\n- Create (with pool): \u003c1 second\n- Create (bootstrap): 10-15 minutes\n- Extend: \u003c100ms\n- Delete: 1-2 seconds\n\n**Cluster Operations**:\n- Bootstrap: 15-20 minutes\n- Reset (with snapshots): 2-3 minutes\n- Snapshot creation: 3-5 minutes\n- Assignment: \u003c10ms\n\n**Validation**:\n- Resource check: 1-2 seconds\n- Command execution: 2-5 seconds\n- Script validation: 3-10 seconds\n\n**Resource Usage**:\n- Backend pod: ~80Mi memory, ~50m CPU (idle)\n- Per cluster: 4 cores, 4Gi memory, 20Gi storage\n- Max concurrent sessions: 3 (pool size)\n\n## Security Implementation\n\n**Container Security**:\n- Non-root execution (UID 1001)\n- Static binary (no runtime dependencies)\n- Minimal base image (Alpine 3.19)\n- Health checks for liveness/readiness\n\n**Secret Management**:\n- SSH keys in Kubernetes secrets\n- Kubeconfig in secrets\n- Init container for permission setup\n- Never logged or exposed\n\n**Network Isolation**:\n- Namespace per session\n- Resource quotas prevent resource exhaustion\n- Istio service mesh for mTLS (if configured)\n\n**SSH Security**:\n- Known hosts checking disabled for VM connections\n- Private key mounted read-only\n- Temp kubeconfig with restricted permissions\n\n---\n\n**Version**: 0.1.0\n**License**: Proprietary\n**Repository**: https://github.com/fullstack-pw/cks-backend\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffullstack-pw%2Fcks-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffullstack-pw%2Fcks-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffullstack-pw%2Fcks-backend/lists"}