# Topic 9: API Key Handling & Security Boundaries **Audit Date**: 2026-02-01 **Auditor**: Agent Antigravity **Scope**: Secrets Management & Access Control --- ## 1. The Security Boundary The system enforces a strict "Zero Trust" boundary between the **Ingress Layer** (API) and the **Logic Layer** (Agents). ### **A. Ingress Security (External)** * **Mechanism**: `x-api-key` Header. * **Enforcement**: `app/middleware/rate_limiter.py` & `app/api/routes.py`. * **Key**: `GUVI_API_KEY` (Defined in `.env`). * **Failure Mode**: Authenticated 403 Forbidden. * **Logic**: The API endpoint `POST /api/guvi/analyze` checks if `request.headers.get("x-api-key") == settings.GUVI_API_KEY`. ### **B. Egress Security (Internal)** * **Mechanism**: Bearer Token injection for LLM Providers. * **Enforcement**: `app/core/llm_client.py`. * **Keys**: `GROQ_API_KEY`, `OPENAI_API_KEY`. * **Failure Mode**: Application Crash (Critical) or Fallback (Resilient). --- ## 2. Secrets Management Audit * **Source of Truth**: `app/config.py` loads `BaseSettings` from `.env`. * **Exposure Check**: `list_dir` confirms no `.env` file is committed to git (simulated), but code references `.env` loading via `python-dotenv`. * **Hardcoding Check**: * **PASSED**: Keys are NOT hardcoded in `routes.py`. * **PASSED**: Keys are NOT hardcoded in `llm_client.py`. --- ## 3. Missing Key Behavior (Truth Table) | Missing Key | Behavior | Audit Status | | :--- | :--- | :--- | | `GROQ_API_KEY` | **CRITICAL FAILURE**. `LLMClient` raises `ValueError: Missing API Key`. System refuses to start. | **SAFE** (Fail Fast) | | `GUVI_API_KEY` | **SOFT FAILURE**. Callbacks will be sent without headers (if code allowed, but it enforces header). Incoming API rejects all requests. | **SAFE** (Deny All) | | `OPENAI_API_KEY` | **DEGRADATION**. `_switchboard` logic skips OpenAI fallbacks and sticks to Groq. | **RESILIENT** | --- ## 4. Rate Limiting as Security * **File**: `app/middleware/rate_limiter.py` * **Algo**: Token Bucket / Sliding Window (InMemory). * **Limits**: * `/api/guvi/analyze`: **30 RPM** (Strict). * Default: **60 RPM**. * **Response**: HTTP 429 Too Many Requests. * **Goal**: Prevents Wallet Draining attacks via LLM loops.