Repository navigation
update architecture #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,68 @@ make lint # Run linter | |
| make build-prod # Production build (static, CGO disabled) | ||
| ``` | ||
|
|
||
| ## Session & Pod Lifecycle | ||
|
|
||
| Each investigation gets its own sandbox pod. The MCP server is stateless — session | ||
| state lives in Kubernetes (pod labels/annotations) and is cached in memory for performance. | ||
|
|
||
| ### Request Flow | ||
|
|
||
| ``` | ||
| TARSy (LLM) | ||
| │ MCP tool call + X-Session-ID header | ||
| ▼ | ||
| MCP Server (stateless, multi-replica) | ||
| │ HTTP POST /exec + Bearer HMAC token | ||
| ▼ | ||
| Sandbox Pod (per-session, persistent bash) | ||
| │ stdout / stderr / exit_code | ||
| ▼ | ||
| MCP Server → TARSy | ||
| ``` | ||
|
|
||
| ### GetOrCreatePod — Three-Tier Lookup | ||
|
|
||
| When a command arrives for a session, `SessionManager.GetOrCreatePod` resolves the | ||
| target pod using a three-tier strategy: | ||
|
|
||
| | Tier | Method | Latency | Description | | ||
| |------|--------|---------|-------------| | ||
| | 1 | **PodCache** | ~0ms | In-memory map of session ID → pod IP with 30s TTL | | ||
| | 2 | **Label discovery** | ~50-100ms | `List` pods by `tarsy.redhat.com/session-id` label | | ||
| | 3 | **Create** | ~3-8s | Create auth Secret + Pod, wait for readiness probe | | ||
|
|
||
| Cache misses fall through to tier 2; if no pod exists, tier 3 creates one | ||
| idempotently (handles `AlreadyExists`). | ||
|
|
||
| ### Warm Pool | ||
|
|
||
| When `--warm-pool-size N` is set, N pre-warmed pods are maintained in a ready state. | ||
| New sessions are assigned a warm pod instantly (~0ms) instead of waiting for a cold | ||
| start. Disabled by default (`N=0`). | ||
|
|
||
|
Comment on lines
+78
to
+83
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift Document the reset boundary before reusing warm pods. "Assigned to new sessions instantly" is only safe if every pod is fully reprovisioned or scrubbed between investigations. Without that, shell state and 🤖 Prompt for AI Agents |
||
| ### Pod Spec | ||
|
|
||
| Each sandbox pod runs with a hardened security context: | ||
|
|
||
| - **Non-root**: UID/GID 1001, `allowPrivilegeEscalation: false`, all capabilities dropped | ||
| - **Resources**: 100m/500m CPU, 128Mi/512Mi memory | ||
| - **Readiness**: HTTP GET `/health` on port 8090 | ||
| - **Volumes**: `kubeconfig` (read-only Secret mount), `workspace` (emptyDir) | ||
| - **Auth**: HMAC-SHA256(key, sessionID) → bearer token delivered via Secret → env var | ||
|
|
||
|
Comment on lines
+84
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift Keep the bearer token out of the bash-visible environment. Delivering the credential via env var inside the sandbox makes it readable by any command running there. That turns a shell compromise into control-plane credential exposure. 🤖 Prompt for AI Agents |
||
| ### Cleanup | ||
|
|
||
| | Method | Trigger | Description | | ||
| |--------|---------|-------------| | ||
| | **Explicit delete** | `DELETE /sessions/{id}` | TARSy calls when investigation ends. Deletes pod, Secret, and cache entry | | ||
| | **Stale cleanup** | Background ticker | Deletes pods idle > 30 minutes (via `last-activity` annotation) | | ||
|
|
||
| If a sandbox pod crashes mid-investigation, shell state (env vars, working directory, | ||
| files in emptyDir) is lost. The MCP server detects the transport error, invalidates | ||
| the cache, and creates a new pod on the next call. TARSy retains the investigation | ||
| context. | ||
|
|
||
| ## Design Documents | ||
|
|
||
| - [Sketch](docs/proposals/cli-mcp-server-sketch.md) — Problem statement and approach | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: codeready-toolchain/cli-mcp-server
Length of output: 39337
🏁 Script executed:
Repository: codeready-toolchain/cli-mcp-server
Length of output: 5495
🏁 Script executed:
Repository: codeready-toolchain/cli-mcp-server
Length of output: 25449
Cache a stable pod identity, not just the IP. Tier 1 reads as session ID → pod IP, which can go stale after a restart and send the next request to the wrong address until TTL expiry; keep the pod name in the cache entry and re-resolve the current IP on lookup.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 51-51: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Source: Linked repositories