Back to skill

Security audit

minio-aiops

Security checks for vulnerabilities and agentic risk

Overview

This skill is for legitimate MinIO administration, but it runs an unpinned external package with storage credentials and exposes powerful write operations without a built-in approval gate.

Install only after pinning the minio-aiops package to a reviewed exact version or otherwise verifying its integrity. Use a dedicated read-only MinIO access key by default, avoid putting the master password in committed config, and grant write or admin permissions only for a clearly approved maintenance window.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Error
Location
SKILL.md:14
Finding
Unpinned External Package Executes with MinIO Credentials and Administrative Access<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:14-16, 60-75`; `references/setup-guide.md:7-10, 78-84` **Vulnerability Type**: Unpinned executable dependency and mutable supply-chain source **Risk Level**: High ### Vulnerable Code `SKILL.md:14-16`: ```yaml installer: kind: uv package: minio-aiops ``` `SKILL.md:60-75`: ```bash ## Quick Install uv tool install minio-aiops minio-aiops init # interactive wizard: endpoint + access key + encrypted secret key minio-aiops doctor ``` ```bash openclaw plugins install clawhub:@zw008/minio-aiops openclaw skills info minio-aiops # expect: Visible to model: yes ``` ```text Needs `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release. ``` `references/setup-guide.md:7-10`: ```bash ## 1. Install uv tool install minio-aiops # or: pipx install minio-aiops ``` `references/setup-guide.md:78-84`: ```json { "mcpServers": { "minio-aiops": { "command": "uvx", "args": ["--from", "minio-aiops", "minio-aiops-mcp"], "env": { "MINIO_AIOPS_MASTER_PASSWORD": "your-master-password" } } } } ``` ### Technical Analysis The audited project contains documentation rather than the implementation of the `minio-aiops` executable. Its effective behavior therefore depends on a package retrieved from an external package registry at installation or MCP startup time. The installation commands and MCP configuration identify `minio-aiops` without an exact version, hash, signature, or immutable artifact reference. Consequently, the code executed by users can change after this Skill has been reviewed. This contradicts the statement in `SKILL.md:75` that the package is “pinned to this release.” The risk is elevated because the MCP process is explicitly supplied with `MINIO_AIOPS_MASTER_PASSWORD`. After unlocking the local encrypted secret store, the package can access the configured MinIO secret keys and communicate with MinIO using the permissions granted ...[truncated 2643 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the package to a reviewed exact version in every installation and execution path: ```yaml installer: kind: uv package: minio-aiops==X.Y.Z ``` ```bash uv tool install "minio-aiops==X.Y.Z" ``` ```json { "command": "uvx", "args": [ "--from", "minio-aiops==X.Y.Z", "minio-aiops-mcp" ] } ``` 2. Require cryptographic integrity verification. Use a lockfile with hashes, hash-pinned requirements, signed release artifacts, or an equivalent trusted verification mechanism. 3. Ensure the OpenClaw plugin, Skill metadata, documentation, and MCP configuration all resolve to the same audited package version. Add an automated release check that fails if any unversioned package reference remains. 4. Prefer an immutable internal artifact repository or vendored, reviewed implementation rather than resolving the latest public package during runtime. 5. Separate installation from runtime. Preinstall and verify the package in a controlled build stage, then run the fixed executable without allowing `uvx` to retrieve a new package when the MCP server starts. 6. Use a dedicated read-only MinIO access key by default. Grant write or administrative permissions only for explicitly approved operations and revoke them after use. 7. Limit access to `MINIO_AIOPS_MASTER_PASSWORD`. Supply it through a protected secret manager where possible, avoid broad process inheritance, and never place a real password directly in committed MCP configuration. 8. Run the MCP server in a sandbox with restricted filesystem access, outbound network access limited to approved MinIO endpoints, and no unnecessary local privileges. 9. Correct or remove the statement that the package is “pinned to this release” unless an enforceable version and integrity constraint is actually present. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (15)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
minio-aiops init                    # wizard: endpoint, TLS, region, access key; secret key → encrypted store
minio-aiops doctor                  # config + secrets + live/ready + S3 auth + metrics reachability
minio-aiops doctor --skip-auth      # config/secrets checks only (no network)
minio-aiops overview                # health + capacity headline + exposure headline
```
Confidence
70% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Credential Access

High
Category
Privilege Escalation
Content
minio-aiops secret set <target>     # store/replace a secret key (prompted hidden)
minio-aiops secret list             # names only — values never shown
minio-aiops secret rm <target>
minio-aiops secret migrate          # import legacy plaintext .env keys
minio-aiops secret rotate-password  # re-encrypt under a new master password
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Session Persistence

Medium
Category
Rogue Agent
Content
metadata: {"openclaw":{"requires":{"anyBins":["minio-aiops","uvx"]},"optional":{"env":["MINIO_AIOPS_CONFIG","MINIO_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/MinIO-AIops","emoji":"🪣","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed MinIO operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Works against any reasonably current MinIO server (single-node or distributed/erasure-coded); admin features (quota, server info) need admin-capable keys.
  All write operations are audited to a local SQLite DB under ~/.minio-aiops/ (relocatable via MINIO_AIOPS_HOME).
  Connection: the S3 API endpoint (host:port, default 9000; SigV4 via the official SDK), plus the unauthenticated health endpoints (/minio/health/live|ready|cluster) and the cluster metrics endpoint (/minio/v2/metrics/cluster — public mode or the default bearer-token mode; the token is derived from the stored credentials, no extra secret). The access key lives in config.yaml; the secret key is stored ENCRYPTED in ~/.minio-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'minio-aiops init' to onboard, or 'minio-aiops secret set <target>' to add one. The store is unlocked by a master password from MINIO_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MINIO_<TARGET_NAME_UPPER>_SECRET_KEY is still honoured as a fallback with a deprecation warning (migrate with 'minio-aiops secret migrate'). Secrets are held only in memory, never logged or echoed.
  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + undo + risk-tier labelling). bucket_delete is high-risk, dry-run + double-confirm, and refused unless the bucket is verifiably empty (including versions
...[truncated 25 chars]
Confidence
60% 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
Standalone, self-governed MinIO operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency. Works against any reasonably current MinIO server (single-node or distributed/erasure-coded); admin features (quota, server info) need admin-capable keys.
  All write operations are audited to a local SQLite DB under ~/.minio-aiops/ (relocatable via MINIO_AIOPS_HOME).
  Connection: the S3 API endpoint (host:port, default 9000; SigV4 via the official SDK), plus the unauthenticated health endpoints (/minio/health/live|ready|cluster) and the cluster metrics endpoint (/minio/v2/metrics/cluster — public mode or the default bearer-token mode; the token is derived from the stored credentials, no extra secret). The access key lives in config.yaml; the secret key is stored ENCRYPTED in ~/.minio-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'minio-aiops init' to onboard, or 'minio-aiops secret set <target>' to add one. The store is unlocked by a master password from MINIO_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MINIO_<TARGET_NAME_UPPER>_SECRET_KEY is still honoured as a fallback with a deprecation warning (migrate with 'minio-aiops secret migrate'). Secrets are held only in memory, never logged or echoed.
  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + undo + risk-tier labelling). bucket_delete is high-risk, dry-run + double-confirm, and refused unless the bucket is verifiably empty (including versions and delete markers); remove_incomplete_uploads only aborts uploads older than a safety window. Reversible writes (set/delete bucket policy, set_versioning, set/delete lifecycle, set_bucket_quota) capture the prior state and record an inverse undo descr
...[truncated 25 chars]
Confidence
60% 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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
Connection: the S3 API endpoint (host:port, default 9000; SigV4 via the official SDK), plus the unauthenticated health endpoints (/minio/health/live|ready|cluster) and the cluster metrics endpoint (/minio/v2/metrics/cluster — public mode or the default bearer-token mode; the token is derived from the stored credentials, no extra secret). The access key lives in config.yaml; the secret key is stored ENCRYPTED in ~/.minio-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'minio-aiops init' to onboard, or 'minio-aiops secret set <target>' to add one. The store is unlocked by a master password from MINIO_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var MINIO_<TARGET_NAME_UPPER>_SECRET_KEY is still honoured as a fallback with a deprecation warning (migrate with 'minio-aiops secret migrate'). Secrets are held only in memory, never logged or echoed.
  State-changing operations require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + undo + risk-tier labelling). bucket_delete is high-risk, dry-run + double-confirm, and refused unless the bucket is verifiably empty (including versions and delete markers); remove_incomplete_uploads only aborts uploads older than a safety window. Reversible writes (set/delete bucket policy, set_versioning, set/delete lifecycle, set_bucket_quota) capture the prior state and record an inverse undo descriptor.
  Webhooks: none — no outbound network calls beyond the configured MinIO endpoint.
  SSL: secure (https) and verify_ssl default to true; disable verification only for self-signed lab certificates.
  Transitive dependencies: the official minio SDK, httpx, and the MCP SDK. No post-install scripts or background services.
  Verification status: validated against mocked SDK/HTTP responses; no recorded end-to-end run against a live MinIO server yet. Eras
...[truncated 25 chars]
Confidence
85% confidence
Finding
The skill explicitly allows TLS certificate verification to be disabled, which weakens transport security and can enable man-in-the-middle interception of MinIO credentials and data if used outside a tightly controlled lab. Because this skill handles administrative storage operations and stored secrets, even an optional insecure mode increases risk substantially when operators copy the pattern into production-like environments.

Session Persistence

Medium
Category
Rogue Agent
Content
## Common Workflows

Each recipe starts from an RCA read and ends in a governed, reversible write.
Every write step accepts `--dry-run`; irreversible ones also double-confirm.

### 1. "Backups are failing — the cluster says it's out of space"
Confidence
60% 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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Authorization is not this tool's job — decide it where it belongs

Whether a write should happen is your decision, or the account's. The tool does
not gate it — there is no read-only switch and no approval prompt to configure.
The two right places to control read vs write:

- **The access key you connect with.** Give it a read-only IAM policy. A write
Confidence
93% confidence
Finding
The document explicitly states the tool does not gate writes and has no approval prompt or read-only switch, placing all protection on external IAM policy or the model prompt. In an agentic context, prompt-only restrictions are weak and bypassable, so a misconfigured write-capable key could allow unintended destructive changes such as policy edits, lifecycle changes, quota changes, or bucket deletion attempts.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
Lines L034-L035 say destructive operations require a dry-run-able preview and double confirmation at the CLI, implying enforced write-time safeguards. But L014-L016 explicitly state the tool does not gate writes and has no approval prompt to configure. These statements actively conflict about whether destructive confirmations are enforced by the tool.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The document enumerates governed writes, including irreversible and critical operations such as bucket deletion and object retention changes, but does not prominently pair that section with a clear warning that there is no approval gate. In this skill context, that is especially dangerous because the toolset targets live object storage administration, so an autonomous or hurried operator could execute destructive or compliance-affecting actions based on incomplete expectations about safeguards.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The capability document advertises powerful write operations including bucket creation, default retention changes, legal holds, and object retention changes that are not reflected in the higher-level skill description. This creates a documentation/expectation gap that can cause operators or downstream orchestration to treat the skill as narrower than it is, increasing the chance that destructive or irreversible storage-governance actions are invoked without appropriate scrutiny.

Intent-Code Divergence

Medium
Confidence
78% confidence
Finding
The file says IAM policy authoring is out of scope and adds that attaching existing policies is supported, but the documented write tools include `set_bucket_policy` and `delete_bucket_policy`, which apply arbitrary bucket policy JSON directly. That is broader than merely attaching an existing policy and creates a contradiction between the prose scope statement and the documented behavior.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
```bash
minio-aiops init                    # wizard: endpoint, TLS, region, access key; secret key → encrypted store
minio-aiops doctor                  # config + secrets + live/ready + S3 auth + metrics reachability
minio-aiops doctor --skip-auth      # config/secrets checks only (no network)
minio-aiops overview                # health + capacity headline + exposure headline
```
Confidence
80% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
## 4. Secrets

- Secret keys live **encrypted** in `~/.minio-aiops/secrets.enc`
  (Fernet + scrypt master password; file chmod 600). Never in config.yaml.
- Non-interactive use (MCP server, CI): export
  `MINIO_AIOPS_MASTER_PASSWORD`. MCP clients start the server **without a TTY
  and without your shell profile** — put the variable in the client's `env`
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The guide shows the master password directly embedded in an MCP client `env` block, which encourages storing a highly sensitive secret in plaintext configuration. That increases exposure through config files, backups, logs, process inspection, screenshots, or accidental commits; in this skill's context, compromise of the master password can unlock stored MinIO secrets and enable access to object-storage credentials.

Description-Behavior Mismatch

Low
Confidence
84% confidence
Finding
The manifest highlights capacity, exposure, lifecycle gaps, healing health, and per-bucket configuration, but does not mention diagnosing object-lock/default-retention misconfiguration. The documented `diagnose_retention_gaps` analysis expands the analytical scope into WORM/retention governance auditing beyond the described headline functions.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
references/agent-guardrails.md:40