Skip to content

Security: okisdev/claude-code-fusion

Security

SECURITY.md

Security

The Grok plugin executes the local Grok CLI with your xAI credentials. Consult, write, review, and best-of-n all pin --sandbox strict; the companion never silently downgrades to workspace. Strict does not confine reads to the workspace or Grok home; its broader system_read roots are described below, while user toolchains outside those readable roots may still be unavailable. Its configuration requests child process network restriction, which Linux enforces through seccomp while macOS currently treats network blocking as a no-op; a write shell can therefore reach the network on macOS, and --web controls only Grok's built in web tools. Consult overrides inherited approval bypass, exposes only file read, list, and search tools plus explicitly requested web search and fetch, and denies shell, edits, native questions, delegated search and tools, MCP, and Agent. Write and best-of-n auto approve a fixed list containing read, grep, list, search_replace, and terminal tools; search_replace is the file creation path, and no nonexistent write tool id is requested. Upstream parses --no-subagents, but the single-turn and agent resolvers do not forward it, while the interactive TUI does apply it; the hard Agent tool deny and GROK_SUBAGENTS=0 are the effective headless controls. Best-of-n alone retains Agent with a bounded native background wait.

Before sending the prompt, the companion requires a new ProfileApplied event from the shared sandbox-events.jsonl that contains this run's private temporary path and matches the canonical workspace, strict profile, enforced state, and requested restrict_network: true configuration. The event proves that the profile and configuration were applied and marked enforced, not that the platform blocked every network path. Upstream records have no run id or pid, so unrelated ProfileApplied and ApplyFailed events are not attributed to the current run and failure events are auxiliary diagnostics only. A matching warning on the owned stderr stream, handshake timeout, missing or malformed matching evidence, shared-log rotation or disappearance, and matching field mismatches fail closed. Forced builder tracing initializes only after Grok consumes stdin, so it is not a pre-prompt or pre-side-effect attestation. Fallback or unmatched warnings trigger early termination, and a successful close is rejected without positive tool allowlist evidence.

The child sets all eighteen GROK_CLAUDE_*_ENABLED, GROK_CURSOR_*_ENABLED, and GROK_CODEX_*_ENABLED bridge variables to false; upstream currently consumes the six Claude and six Cursor cells plus the Codex sessions cell and reserves the other five Codex cells, and the child also pins GROK_MANAGED_MCPS_ENABLED=false because that variable has highest precedence over [managed_mcps] in ~/.grok/config.toml and remote settings. It disables subagents outside best-of-n, disables automatic updates through --no-auto-update, removes inherited Claude session and plugin variables plus _GROK_CLAUDE_MARKER_OVERRIDE, and broadly scrubs secret-bearing variables while preserving required xAI authentication. Upstream minimum-version enforcement can still force an update. Memory is force-disabled unless the user explicitly passes --memory to an ordinary task. Review, stop gate, and best-of-n always keep memory off. A memory-enabled task allows upstream to inject selected global or workspace memory into the model context sent to xAI and to update memory according to the user's Grok configuration. Upstream automatic saving usually requires at least three real user prompts in the same resumed session, so one Fusion task usually only reads existing memory and does not guarantee that new memory is saved. Continuity defaults to manual. Optional claude-session affinity resumes only a compatible completed ordinary direct task from the same Claude session, exact resolved working directory, mode, strict profile, and memory boundary. Fusion routed briefs do not receive automatic affinity and stay fresh unless explicitly resumed; --fresh disables affinity for one task. Write and best-of-n include terminal commands, so treat them as giving Grok your own shell inside the strict workspace view and run them on a clean branch or an orchestrator-created disposable worktree. Command-pattern denies for common direct grok, claude, and codex calls do not cover absolute paths, aliases or functions, or indirect scripts; a hard nested-execution boundary requires removing run_terminal_cmd or applying an OS-level executable or network policy. Headless stdout is captured through a 0600 file that is unlinked immediately after open. A resumable Grok task keeps its strict profile, mode, and memory boundary for its lifetime, so incompatible resumes fail closed. Job briefs and logs are stored in plain text under ~/.claude/plugins/data/grok-claude-code-fusion/. The routing policy, panel blindness, and circuit breaker are prompt level conventions, not runtime enforcement; see the Safety model section of the README for the full split between what code enforces and what prompts request.

Upstream strict's system_read roots include /var and /tmp on Linux, and /private plus the entire ~/Library on macOS. Shared temporary content and substantial user application configuration and caches may therefore be readable. Strict always permits writes to /tmp and /var/tmp; macOS also permits /private/tmp, /private/var/tmp, and all of /private/var/folders. The adapter's unique private TMPDIR is preferred and handshake-verified, not the only writable temporary surface. On Linux, a strict profile with deny paths re-executes under bubblewrap and refuses to start when bwrap is missing or unusable; macOS has no equivalent hard enforcement and relies on Seatbelt application plus best-effort tool denies. The entire Grok home is read-write. The sandbox permits consult read_file to reach ~/.grok/auth.json, config, and sessions, while write terminal commands can receive preserved xAI authentication variables. The companion applies best-effort Read denies to auth.json, mcp_credentials.json, config.toml, sessions, memory, logs, and debug under the Grok home with absolute paths and standard **/.grok patterns, but raw path variants, symbolic links, and shell or indirect scripts can bypass those tool-level rules. These Read denies apply to model tool calls. They do not prevent upstream's internal first-turn memory search and injection when --memory is enabled, so memory snippets can enter the xAI request even though direct model reads of ~/.grok/memory/** are denied. Environment scrubbing and path-pattern denies do not isolate credentials or memory content. Model-facing MCP and meta-tool denies do not prove that native MCP servers, plugins, or hooks configured under ~/.grok did not start during agent construction or had no side effects; those bridge variables disable compatibility imports, not native Grok configuration. Narrower exposure requires a dedicated sandbox profile, an isolated Grok home, an authentication broker, or upstream path-level authorization.

Never include secrets, API keys, tokens, or credentials in briefs delegated to Codex or Grok. The routing policy in plugins/fusion/rules/orchestration.md forbids it, but the companion does not scan or redact briefs before invoking the peer CLIs, and job briefs are stored in plain text under the plugin data directory.

Grok sends the prompt and any selected repository context to xAI. A task with --memory can also send internally injected Grok memory content. The optional --web tools use the network and may transmit inspected content. The strict profile is not a secret boundary for the workspace, selected system paths, or opted-in memory, and its verified application does not make sensitive content safe to delegate. Do not run consult, memory, or web delegation over a workspace or memory store that exposes credentials. Use an isolated working directory that excludes sensitive paths. Stronger path exclusions require a reviewed companion profile change.

Companion history and native Grok storage have separate retention. The companion ledger under ~/.claude/plugins/data/grok-claude-code-fusion/ has no promised automatic garbage collection and must be deleted manually when its records, briefs, logs, uncollected results, and resume evidence are no longer needed. Native Grok sessions under ~/.grok/sessions default to 30 days of retention. ~/.grok/config.toml accepts a positive integer at [storage] cleanup_ttl_days; 0 falls back to the default 30 days. Cross-session memory under ~/.grok/memory is separate from both histories and must be removed separately if it should be forgotten.

The Fusion inline guard keeps short lived per session counters and a longer lived JSONL audit ledger. Audit events contain the session id, tool, lane, a workspace relative write path when it is safe to retain, or a short dispatch description. Recognizable credential shapes are removed and unsafe optional fields are omitted, but this is not a general secret scanner. Keep secrets out of filenames, dispatch descriptions, and optional semantic acceptance reasons. Codex observation sidecars retain job and workspace identifiers, model, effort, token counts, and acceptance metadata. They do not automatically copy prompts or result text, but an optional acceptance reason is caller supplied plain text and is retained after limited credential shape redaction.

Report vulnerabilities to hi@okis.dev or through a GitHub security advisory on this repository. Please do not open public issues for exploitable problems before contact.

There aren't any published security advisories