Back to skill

Security audit

Gateway Env Injector

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-built for configuring OpenClaw secrets, but it makes misleading safety claims while persistently storing API keys and a 1Password token in a LaunchAgent plist.

Review carefully before installing. This skill can expose OpenAI, Anthropic, Gemini, Mistral, Voyage, Hugging Face, and 1Password credentials in a persistent LaunchAgent plist and process environment. Use only if you accept that storage model, restrict the 1Password service account to the smallest possible vault scope, verify plist permissions, and rotate any credentials previously written by this script.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/inject-gateway-env.sh:40
Finding
Persistent Plaintext Storage of API Credentials in the LaunchAgent Plist## Vulnerability Details **File Location**: `scripts/inject-gateway-env.sh:40-54` **Vulnerability Type**: Plaintext sensitive-data storage **Risk Level**: High ### Vulnerable Code ```bash inject_key() { local key="$1" val="$2" [ -z "$val" ] && return $BUDDY -c "Delete :EnvironmentVariables:$key" "$PLIST" 2>/dev/null || true $BUDDY -c "Add :EnvironmentVariables:$key string $val" "$PLIST" echo " ✅ $key" } inject_key "OPENAI_API_KEY" "$OPENAI_API_KEY" inject_key "ANTHROPIC_API_KEY" "$ANTHROPIC_API_KEY" inject_key "GEMINI_API_KEY" "$GEMINI_API_KEY" inject_key "MISTRAL_API_KEY" "$MISTRAL_API_KEY" inject_key "VOYAGE_API_KEY" "$VOYAGE_API_KEY" inject_key "HF_TOKEN" "$HF_TOKEN" inject_key "OP_SERVICE_ACCOUNT_TOKEN" "$(cat "$TOKEN_FILE")" inject_key "SHERPA_ONNX_RUNTIME_DIR" "$HOME/.openclaw/sherpa-onnx/runtime" inject_key "SHERPA_ONNX_MODEL_DIR" "$HOME/.openclaw/sherpa-onnx/models/vits-piper-en_US-lessac-high" inject_key "OTLP_ENDPOINT" "localhost:4317" ``` ### Technical Analysis `PlistBuddy` serializes the environment-variable values into `~/Library/LaunchAgents/ai.openclaw.gateway.plist`. Consequently, the OpenAI, Anthropic, Gemini, Mistral, Voyage, Hugging Face, and 1Password credentials are stored persistently in plaintext on disk. This behavior directly contradicts the Skill's claim that it injects credentials “without leaving plaintext keys on disk.” No code verifies or enforces restrictive permissions on the resulting plist. Although restarting an existing LaunchAgent is consistent with the declared gateway-management function, persistent storage of all credentials in its configuration is not a minimum-privilege secret-delivery mechanism. ### Attack Path 1. An attacker obtains local execution under the user account, access to the user's files, a readable backup, or a diagnostic archive containing the LaunchAgent plist. ...[truncated 901 chars]
Remediation
## Remediation Suggestions - Do not place secret values directly in a persistent LaunchAgent plist. - Use a narrowly scoped runtime secret broker or wrapper that obtains credentials immediately before launching the gateway and does not serialize them into persistent configuration. - Prefer platform-supported secret storage, such as macOS Keychain, with access controls restricted to the intended executable and user. - If runtime environment variables remain unavoidable, ensure the persistent plist contains only non-secret configuration and references a protected runtime-loading mechanism. - Never include the 1Password service-account token in the gateway environment. - As defense in depth, verify ownership and enforce mode `0600` on any file that can contain sensitive configuration. - Remove existing secret values from deployed plists and rotate every credential previously written there. - Correct `SKILL.md` so its security claims accurately describe the implementation.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/inject-gateway-env.sh:51
Finding
1Password Service-Account Token Granted to the Persistent Gateway Service## Vulnerability Details **File Location**: `scripts/inject-gateway-env.sh:51` **Vulnerability Type**: Excessive credential delegation and violation of least privilege **Risk Level**: High ### Vulnerable Code ```bash inject_key "OP_SERVICE_ACCOUNT_TOKEN" "$(cat "$TOKEN_FILE")" ``` ### Technical Analysis The 1Password service-account token is required by the injection script while executing `op read`. It is not required by the gateway after the provider credentials have been fetched. Injecting the token into the LaunchAgent therefore delegates 1Password access to a persistent service beyond the needs of the stated task. This widens the trust boundary from a short-lived administrative script to the gateway process and every component capable of inspecting its environment or plist configuration. The obtainable privileges are determined by the service account's 1Password vault permissions and may extend beyond the six credentials used by this script. ### Attack Path 1. An attacker compromises the OpenClaw gateway process, a plugin loaded by it, or another component capable of inspecting its environment. 2. Alternatively, the attacker reads the gateway LaunchAgent plist from disk or from a backup. 3. The attacker extracts `OP_SERVICE_ACCOUNT_TOKEN`. 4. The attacker supplies the token to the 1Password CLI or API. 5. The attacker enumerates and reads any vault items authorized to the service account. 6. Recovered credentials are used to compromise additional external services. ### Impact Assessment A gateway compromise can escalate into access to the associated 1Password service account. The scope is not limited to the API keys explicitly injected by this script; it includes all vaults and items the service account is permitted to read. The token remains available across gateway restarts because it is stored in persistent LaunchAgent configuration.
Remediation
## Remediation Suggestions - Delete the `OP_SERVICE_ACCOUNT_TOKEN` injection entirely. - Keep the token scoped to the injector process and unset it immediately after the necessary `op read` operations. - Configure the 1Password service account with read access only to the exact items required by this workflow. - Use separate service accounts for unrelated applications and environments. - Rotate the existing service-account token after removing it from the plist. - Audit the relevant 1Password activity history for unexpected access. - Remove the token from existing LaunchAgent files, backups, logs, and diagnostic bundles where feasible.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/inject-gateway-env.sh:40
Finding
Secret Values Exposed Through PlistBuddy Process Arguments## Vulnerability Details **File Location**: `scripts/inject-gateway-env.sh:40-46` **Vulnerability Type**: Sensitive information exposed in command-line arguments **Risk Level**: Medium ### Vulnerable Code ```bash inject_key() { local key="$1" val="$2" [ -z "$val" ] && return $BUDDY -c "Delete :EnvironmentVariables:$key" "$PLIST" 2>/dev/null || true $BUDDY -c "Add :EnvironmentVariables:$key string $val" "$PLIST" echo " ✅ $key" } ``` ### Technical Analysis Each secret is interpolated into the argument passed to `PlistBuddy` with `-c`. While the process is running, the complete command may be visible to local process-inspection or endpoint-monitoring tools. Process-accounting systems, crash diagnostics, or security telemetry may also retain command arguments after execution. The value is additionally embedded into PlistBuddy's command language rather than supplied through a structured data interface. A secret containing command-parser metacharacters, quotes, or unusual whitespace may be misinterpreted or cause injection to fail. The reviewed code does not validate or safely encode values for this parser. ### Attack Path 1. An attacker or monitoring component observes process arguments while the injection script is running. 2. The attacker identifies the `PlistBuddy -c` processes. 3. The attacker extracts the value following the `string` portion of each command argument. 4. The recovered API credentials or 1Password token are used against their respective services. A second failure path exists when a valid credential contains parser-significant characters: the value may be truncated, rejected, or interpreted as part of PlistBuddy's command syntax, resulting in incorrect configuration or unintended plist modification. ### Impact Assessment Exploitation can disclose every credential passed to `inject_key`, including the high-impact 1Password service-account token. The direct obse ...[truncated 188 chars]
Remediation
## Remediation Suggestions - Do not pass secrets as command-line arguments. - Replace PlistBuddy command-string interpolation with a structured plist API that accepts data without embedding it into a secondary command language. - Prefer a runtime secret-delivery design that does not write secrets into the plist at all. - If a plist must be manipulated, use a small trusted program based on Foundation or another structured plist library, with secret input received through a protected channel rather than `argv`. - Avoid logging command arguments and review endpoint telemetry retention policies for sensitive process data. - Rotate credentials if process accounting or monitoring systems may already have captured these commands.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/inject-gateway-env.sh:14
Finding
Token Provisioning Guidance Can Leak the Secret Through Shell History and File-Creation Permissions## Vulnerability Details **File Location**: `scripts/inject-gateway-env.sh:14-17` **Vulnerability Type**: Unsafe credential provisioning guidance **Risk Level**: Medium ### Vulnerable Code ```bash if [ ! -f "$TOKEN_FILE" ]; then echo "❌ No 1Password token at $TOKEN_FILE" echo " Get it from 1Password and run: echo <TOKEN> > $TOKEN_FILE && chmod 600 $TOKEN_FILE" exit 1 fi ``` ### Technical Analysis The displayed guidance encourages users to substitute the actual service-account token directly into an interactive shell command. Depending on shell configuration, that command can be retained in command history. The file is also created before `chmod 600` is applied. Its initial mode is governed by the user's current `umask`; with a permissive configuration, the file may briefly be readable by unintended local principals. If the follow-up `chmod` fails or the compound command is interrupted, the weak permissions may persist. ### Attack Path 1. A user follows the printed instruction and inserts the real service-account token into the command line. 2. The shell records the command in its history file, or terminal/session auditing captures it. 3. A local attacker or support process reads the retained history or audit data and extracts the token. Alternatively: 1. The token file is created under a permissive `umask`. 2. Before `chmod 600` completes—or if it fails—another local principal reads the file. 3. The attacker uses the recovered token to access items authorized to the 1Password service account. ### Impact Assessment Exposure grants the attacker the read privileges assigned to the 1Password service account. The resulting scope may include all vault items available to that account, not only the API credentials fetched by this script. History-based exposure can remain discoverable long after initial setup.
Remediation
## Remediation Suggestions - Replace the printed command with a secure setup helper that reads the token using a hidden prompt, such as `read -r -s`. - Set `umask 077` before creating any credential file. - Create the parent directory with restrictive permissions and verify its ownership. - Create the token file atomically with mode `0600`, rather than creating it first and changing permissions afterward. - Prevent the token from appearing in command history, process arguments, logs, or terminal output. - Validate the resulting file with checks for regular-file type, expected owner, and mode `0600` before reading it. - Advise affected users to remove prior token-bearing commands from shell history and rotate the token.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description claims secrets are injected 'without leaving plaintext keys on disk,' yet writing values into a LaunchAgent plist necessarily persists them in a local file. The mismatch is dangerous because it can mislead users into deploying the skill under false security assumptions while also introducing undeclared secret handling, configuration injection, and service restart side effects.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises shell-based behavior and execution instructions but does not declare an explicit tool scope such as permissions or allowed-tools. That increases the risk of overbroad execution in an agent environment, because consumers cannot clearly constrain what shell capabilities the skill expects or is allowed to use.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-env-injector
version: 1.0.0
description: Safely inject API keys from 1Password into macOS LaunchAgent plists using PlistBuddy. Use when running OpenClaw on macOS and storing secrets in 1Password — avoids plaintext keys on disk while keeping LaunchAgent env vars populated. Requires 1Password CLI (op).
metadata:
  {"openclaw": {"emoji": "🔐", "requires": {"bins": ["op", "bash"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"]}, "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN", "network": {"outbound": true, "reason": "Reads secrets from 1Password via op CLI (1password.com). Writes locally to plist files only."}}}
---
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The documentation explicitly asserts that plaintext keys are not left on disk, but the stated workflow injects secret values into the plist file's EnvironmentVariables section. This is dangerous because plist files are persistent artifacts that may be readable by local users, backups, EDR tools, or support bundles, exposing credentials contrary to user expectations.

Session Persistence

Medium
Category
Rogue Agent
Content
#!/usr/bin/env bash
# inject-gateway-env.sh — Bake API keys from 1Password into the OpenClaw gateway plist.
# Run whenever a key changes, or after a fresh bootstrap.
# 
# Requires: op CLI + ~/.config/openclaw/.op-service-token
Confidence
90% confidence
Finding
The script is explicitly designed to persist secrets in a LaunchAgent plist, which creates long-lived credential material on disk and in the launchd-managed environment. That persistence increases the blast radius of filesystem access, backups, local compromise, and forensic artifact leakage.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The header claims the approach avoids plaintext keys on disk, but the implementation writes secrets directly into an on-disk LaunchAgent plist. This misleading claim can cause operators to underestimate exposure and deploy the script in environments where disk persistence of credentials is unacceptable.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script silently persists multiple secrets into a LaunchAgent plist and restarts the service, but provides no explicit warning that credentials will be stored on disk and exposed through the process environment. This increases the chance of unsafe operational use, accidental disclosure during support/debugging, and misunderstanding of the threat model.

Session Persistence

Medium
Category
Rogue Agent
Content
set -euo pipefail

PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
TOKEN_FILE="$HOME/.config/openclaw/.op-service-token"

if [ ! -f "$TOKEN_FILE" ]; then
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
set -euo pipefail

PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
TOKEN_FILE="$HOME/.config/openclaw/.op-service-token"

if [ ! -f "$TOKEN_FILE" ]; then
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
set -euo pipefail

PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
TOKEN_FILE="$HOME/.config/openclaw/.op-service-token"

if [ ! -f "$TOKEN_FILE" ]; then
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
set -euo pipefail

PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
TOKEN_FILE="$HOME/.config/openclaw/.op-service-token"

if [ ! -f "$TOKEN_FILE" ]; then
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if [ ! -f "$TOKEN_FILE" ]; then
    echo "❌ No 1Password token at $TOKEN_FILE"
    echo "   Get it from 1Password and run: echo <TOKEN> > $TOKEN_FILE && chmod 600 $TOKEN_FILE"
    exit 1
fi
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
inject_key() {
    local key="$1" val="$2"
    [ -z "$val" ] && return
    $BUDDY -c "Delete :EnvironmentVariables:$key" "$PLIST" 2>/dev/null || true
    $BUDDY -c "Add :EnvironmentVariables:$key string $val" "$PLIST"
    echo "  ✅ $key"
}
Confidence
98% confidence
Finding
This line deletes any existing environment variable entry in the LaunchAgent plist as part of replacing it, confirming the script modifies launchd-managed persistent configuration. In context with the next line, it participates directly in long-term credential storage and rotation on disk.

Session Persistence

Medium
Category
Rogue Agent
Content
local key="$1" val="$2"
    [ -z "$val" ] && return
    $BUDDY -c "Delete :EnvironmentVariables:$key" "$PLIST" 2>/dev/null || true
    $BUDDY -c "Add :EnvironmentVariables:$key string $val" "$PLIST"
    echo "  ✅ $key"
}
Confidence
99% confidence
Finding
This line writes arbitrary secret values into the LaunchAgent plist under EnvironmentVariables, persisting plaintext credentials on disk and exposing them to the process environment after restart. In this skill context, that is especially dangerous because the script handles multiple API keys and a secret-management token, making local disclosure highly valuable to an attacker.

Description-Behavior Mismatch

Medium
Confidence
99% confidence
Finding
The script reads the 1Password service account token from disk and then injects it into the LaunchAgent plist as an environment variable. That persists a highly privileged secret on disk and exposes it to the gateway process environment, broadening compromise scope from individual model keys to the secret-management credential itself.

Static analysis

No suspicious patterns detected.