|
| 1 | +## Assumption-validation check-in |
| 2 | +- The installer API is intended for local host use only and not internet-exposed (`/api/v1/*` loopback + API key guard). |
| 3 | +- Skills/hooks repositories are trusted-by-default but still treated as tamperable supply-chain inputs. |
| 4 | +- `ica serve` is run by a local developer with Docker privileges. |
| 5 | +- The dashboard UI is accessed locally via the BFF proxy and not directly from arbitrary origins. |
| 6 | + |
| 7 | +Questions to confirm: |
| 8 | +1. Is any deployment expected where `/api/v1/*` is reachable beyond loopback (for example remote dev hosts or shared VMs)? |
| 9 | +2. Are third-party/community source repos expected to be used by default in production developer environments? |
| 10 | +3. Should symlink installs be considered acceptable for high-trust local workflows, or must copy+verify be enforced always? |
| 11 | + |
| 12 | +## Executive summary |
| 13 | +The highest risks are supply-chain integrity and privileged local execution paths: source sync pulls and executes content from git repositories, and dashboard/CLI orchestration performs local process and container control. Current controls are solid for local-only API access and content digest verification at install time, but residual risk remains around trust of upstream source repos and symlink-mode drift after installation. |
| 14 | + |
| 15 | +## Scope and assumptions |
| 16 | +In scope: |
| 17 | +- `src/installer-cli/index.ts` |
| 18 | +- `src/installer-api/server/index.ts` |
| 19 | +- `src/installer-core/sourceSync.ts` |
| 20 | +- `src/installer-core/hookSync.ts` |
| 21 | +- `src/installer-core/executor.ts` |
| 22 | +- `src/installer-core/hookExecutor.ts` |
| 23 | +- `src/installer-core/updateCheck.ts` |
| 24 | +- `src/installer-core/contentDigest.ts` |
| 25 | +- `src/installer-dashboard/web/src/InstallerDashboard.tsx` |
| 26 | + |
| 27 | +Out of scope: |
| 28 | +- External GitHub/GHCR runtime security posture. |
| 29 | +- Host OS hardening and Docker daemon configuration. |
| 30 | + |
| 31 | +Open questions materially affecting risk: |
| 32 | +- Whether this API is ever exposed off-loopback. |
| 33 | +- Whether untrusted source repositories are expected in regular workflows. |
| 34 | +- Whether symlink mode is allowed in high-assurance contexts. |
| 35 | + |
| 36 | +## System model |
| 37 | +### Primary components |
| 38 | +- CLI orchestration starts API/BFF and Docker dashboard container (`src/installer-cli/index.ts:1256`). |
| 39 | +- API provides management endpoints and enforces local-only + API key checks (`src/installer-api/server/index.ts:928`). |
| 40 | +- Source sync pulls skills/hooks repositories and mirrors content locally (`src/installer-core/sourceSync.ts:192`, `src/installer-core/hookSync.ts:199`). |
| 41 | +- Install executors verify content digests before/after installation in copy mode (`src/installer-core/executor.ts:86`, `src/installer-core/hookExecutor.ts:62`). |
| 42 | +- Dashboard triggers refresh and install operations over local API/BFF (`src/installer-dashboard/web/src/InstallerDashboard.tsx:845`). |
| 43 | + |
| 44 | +### Data flows and trust boundaries |
| 45 | +- User UI -> BFF/API: local HTTP, API key and loopback guard. |
| 46 | +- API -> Git remotes: git clone/fetch over HTTPS/SSH with optional credentials. |
| 47 | +- API/CLI -> Docker daemon: container lifecycle and image pull/build operations. |
| 48 | +- Source mirror -> Install targets: filesystem copy/symlink of skills/hooks. |
| 49 | +- API -> GitHub Releases API: version metadata fetch (`src/installer-core/updateCheck.ts:43`). |
| 50 | + |
| 51 | +#### Diagram |
| 52 | +```mermaid |
| 53 | +flowchart LR |
| 54 | + User["Local User"] --> UI["Dashboard UI"] |
| 55 | + UI --> BFF["BFF"] |
| 56 | + BFF --> API["Installer API"] |
| 57 | + API --> Src["Skills Hooks Mirror"] |
| 58 | + API --> Git["Git Repos"] |
| 59 | + API --> Docker["Docker Daemon"] |
| 60 | + API --> GH["GitHub Releases API"] |
| 61 | + Src --> Targets["Agent Homes"] |
| 62 | +``` |
| 63 | + |
| 64 | +## Assets and security objectives |
| 65 | +| Asset | Why it matters | Security objective (C/I/A) | |
| 66 | +|---|---|---| |
| 67 | +| Installed skills/hooks content | Controls agent behavior and command execution | I, A | |
| 68 | +| Source credentials/tokens | Access to private repositories | C | |
| 69 | +| API key for local control plane | Authorizes install/refresh operations | C, I | |
| 70 | +| Local Docker/container state | Hosts dashboard process and user workloads | I, A | |
| 71 | +| Source revision/digest metadata | Detects tampering and stale state | I | |
| 72 | + |
| 73 | +## Attacker model |
| 74 | +### Capabilities |
| 75 | +- Local adversary/process on developer host attempting loopback access. |
| 76 | +- Compromised or malicious upstream source repository content. |
| 77 | +- Accidental operator misuse of serve/refresh workflows. |
| 78 | + |
| 79 | +### Non-capabilities |
| 80 | +- Remote internet attacker cannot directly call API when loopback binding is preserved. |
| 81 | +- Browser-origin attacker cannot call API without local origin and API key routing controls. |
| 82 | + |
| 83 | +## Entry points and attack surfaces |
| 84 | +| Surface | How reached | Trust boundary | Notes | Evidence (repo path / symbol) | |
| 85 | +|---|---|---|---|---| |
| 86 | +| `/api/v1/*` endpoints | Local HTTP requests | UI/process -> API | Loopback + `x-ica-api-key` gate | `src/installer-api/server/index.ts:928` | |
| 87 | +| Source refresh endpoints | API POST | API -> Git remotes | Triggers git sync and local mirror writes | `src/installer-api/server/index.ts:861` | |
| 88 | +| Scheduled auto-refresh | API interval timer | API scheduler -> Git remotes | Repeated network + filesystem sync | `src/installer-api/server/index.ts:1192` | |
| 89 | +| CLI serve container/process control | Local CLI run | CLI -> Docker/OS processes | Removes named dashboard container and reclaims ports | `src/installer-cli/index.ts:1263` | |
| 90 | +| Install execution | CLI/API install calls | Mirror -> Agent home FS | Digest verification controls integrity in copy mode | `src/installer-core/executor.ts:86` | |
| 91 | + |
| 92 | +## Top abuse paths |
| 93 | +1. Attacker compromises configured source repo -> API refresh pulls malicious skill -> operator installs -> agent executes attacker instructions. |
| 94 | +2. Local process obtains API key from local environment/log leak -> issues install/uninstall API calls -> modifies agent home behavior. |
| 95 | +3. Malicious local process binds dashboard internal port -> prevents serve startup or induces operational failure. |
| 96 | +4. Operator enables symlink mode -> source directory changes post-install -> runtime content drift bypasses post-copy verification. |
| 97 | +5. Upstream API (GitHub releases) manipulation/instability -> update notification noise or suppression -> delayed patch adoption. |
| 98 | + |
| 99 | +## Threat model table |
| 100 | +| Threat ID | Threat source | Prerequisites | Threat action | Impact | Impacted assets | Existing controls (evidence) | Gaps | Recommended mitigations | Detection ideas | Likelihood | Impact severity | Priority | |
| 101 | +|---|---|---|---|---|---|---|---|---|---|---|---|---| |
| 102 | +| TM-001 | Compromised source repository | Source repo configured/enabled and refreshed | Serve/API refresh pulls malicious skills/hooks | Agent behavior compromise, possible command execution | Installed skills/hooks, agent homes | Digest verification on install (`src/installer-core/executor.ts:86`, `src/installer-core/hookExecutor.ts:62`) | Integrity assures consistency, not trust provenance | Add signed manifests/commit pinning and allowlist trusted source owners | Alert on source revision jumps and digest deltas | medium | high | high | |
| 103 | +| TM-002 | Local unauthorized caller | API key disclosed or guessed; local host access | Call `/api/v1/*` mutating endpoints | Unauthorized install/remove/sync | API key, install state | Loopback restriction + API key check (`src/installer-api/server/index.ts:937`) | No rate limiting/audit policy for failed auth attempts | Add auth-failure throttling and structured security logs | Track repeated 401/403 bursts | low | high | medium | |
| 104 | +| TM-003 | Local availability attacker | Port contention on UI/API/internal dashboard ports | Block or disrupt serve orchestration | Installer downtime, failed refresh/install sessions | Docker state, API/BFF availability | Named-container removal + targeted reclaim (`src/installer-cli/index.ts:426`) | Loopback reclaim can still terminate non-ICA PIDs for API/UI ports | Restrict PID reclaim to ICA-owned commands, otherwise fail-fast | Log process commandline before kill; emit warning if non-ICA | medium | medium | medium | |
| 105 | +| TM-004 | Credential persistence leak | HTTPS token used for source sync; abnormal interruption | Tokenized remote URL left in local git config | Secret exposure from local state | Source credentials | Remote URL reset logic in `finally` (`src/installer-core/sourceSync.ts:244`) | Crash/kill -9 before cleanup can leave credentialized URL | Prefer per-command auth helper over storing tokenized remote URL | Periodic scan for credentials in `~/.ica/**/.git/config` | low | high | medium | |
| 106 | +| TM-005 | Update-check path abuse | External API slowness/outage | Health/update check stalls or fails | Operational noise, delayed UX | Update telemetry | Timeout + cache in update checker (`src/installer-core/updateCheck.ts:41`, `src/installer-core/updateCheck.ts:69`) | No signed metadata verification, relies on API response trust | Optionally verify release origin metadata and add backoff metrics | Monitor update-check errors and latency | low | low | low | |
| 107 | + |
| 108 | +## Criticality calibration |
| 109 | +- critical: direct remote code execution or cross-tenant data compromise without local preconditions. |
| 110 | +- high: local-to-privileged compromise of agent behavior or credential theft with realistic prerequisites. |
| 111 | +- medium: meaningful availability or integrity degradation requiring local foothold/misconfiguration. |
| 112 | +- low: telemetry/noise issues or edge-case misbehavior with limited security impact. |
| 113 | + |
| 114 | +## Focus paths for security review |
| 115 | +| Path | Why it matters | Related Threat IDs | |
| 116 | +|---|---|---| |
| 117 | +| `src/installer-core/sourceSync.ts` | Source trust boundary and tokenized remote handling | TM-001, TM-004 | |
| 118 | +| `src/installer-core/hookSync.ts` | Hook source sync executes same trust pattern as skills | TM-001, TM-004 | |
| 119 | +| `src/installer-core/executor.ts` | Skill integrity enforcement and install mode semantics | TM-001, TM-003 | |
| 120 | +| `src/installer-core/hookExecutor.ts` | Hook integrity enforcement and install mode semantics | TM-001, TM-003 | |
| 121 | +| `src/installer-api/server/index.ts` | Local authn/authz guard and scheduled refresh surface | TM-002, TM-005 | |
| 122 | +| `src/installer-cli/index.ts` | Docker/process lifecycle controls and potential local DoS | TM-003 | |
| 123 | +| `src/installer-core/updateCheck.ts` | External metadata trust and timeout/cache strategy | TM-005 | |
| 124 | + |
| 125 | +## Quality check |
| 126 | +- Entry points covered: API routes, refresh endpoints, serve orchestration, install paths. |
| 127 | +- Trust boundaries represented in threats: UI/API, API/Git, API/Docker, mirror/target FS, API/external release API. |
| 128 | +- Runtime vs CI/dev separation: runtime installer paths only; CI workflows treated as out of scope. |
| 129 | +- User clarifications: pending (questions listed in assumption check-in). |
| 130 | +- Assumptions/open questions: explicitly documented above. |
0 commit comments