minio-aiops 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- minio_aiops-0.1.0/.github/workflows/mcp-publish.yml +55 -0
- minio_aiops-0.1.0/.github/workflows/publish.yml +26 -0
- minio_aiops-0.1.0/.gitignore +8 -0
- minio_aiops-0.1.0/CHANGELOG.md +54 -0
- minio_aiops-0.1.0/LICENSE +21 -0
- minio_aiops-0.1.0/PKG-INFO +193 -0
- minio_aiops-0.1.0/README.md +176 -0
- minio_aiops-0.1.0/RELEASE_NOTES.md +39 -0
- minio_aiops-0.1.0/SECURITY.md +82 -0
- minio_aiops-0.1.0/mcp_server/__init__.py +1 -0
- minio_aiops-0.1.0/mcp_server/_shared.py +105 -0
- minio_aiops-0.1.0/mcp_server/server.py +36 -0
- minio_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
- minio_aiops-0.1.0/mcp_server/tools/bucket_writes.py +304 -0
- minio_aiops-0.1.0/mcp_server/tools/buckets.py +129 -0
- minio_aiops-0.1.0/mcp_server/tools/capacity.py +36 -0
- minio_aiops-0.1.0/mcp_server/tools/exposure.py +43 -0
- minio_aiops-0.1.0/mcp_server/tools/healing.py +47 -0
- minio_aiops-0.1.0/mcp_server/tools/health.py +74 -0
- minio_aiops-0.1.0/mcp_server/tools/undo.py +121 -0
- minio_aiops-0.1.0/minio_aiops/__init__.py +14 -0
- minio_aiops-0.1.0/minio_aiops/cli/__init__.py +9 -0
- minio_aiops-0.1.0/minio_aiops/cli/_common.py +84 -0
- minio_aiops-0.1.0/minio_aiops/cli/_root.py +63 -0
- minio_aiops-0.1.0/minio_aiops/cli/bucket.py +230 -0
- minio_aiops-0.1.0/minio_aiops/cli/capacity.py +39 -0
- minio_aiops-0.1.0/minio_aiops/cli/doctor.py +21 -0
- minio_aiops-0.1.0/minio_aiops/cli/heal.py +45 -0
- minio_aiops-0.1.0/minio_aiops/cli/health.py +35 -0
- minio_aiops-0.1.0/minio_aiops/cli/init.py +152 -0
- minio_aiops-0.1.0/minio_aiops/cli/overview.py +16 -0
- minio_aiops-0.1.0/minio_aiops/cli/secret.py +103 -0
- minio_aiops-0.1.0/minio_aiops/cli/undo.py +62 -0
- minio_aiops-0.1.0/minio_aiops/config.py +155 -0
- minio_aiops-0.1.0/minio_aiops/connection.py +644 -0
- minio_aiops-0.1.0/minio_aiops/doctor.py +123 -0
- minio_aiops-0.1.0/minio_aiops/governance/__init__.py +40 -0
- minio_aiops-0.1.0/minio_aiops/governance/audit.py +377 -0
- minio_aiops-0.1.0/minio_aiops/governance/budget.py +225 -0
- minio_aiops-0.1.0/minio_aiops/governance/decorators.py +482 -0
- minio_aiops-0.1.0/minio_aiops/governance/paths.py +23 -0
- minio_aiops-0.1.0/minio_aiops/governance/patterns.py +378 -0
- minio_aiops-0.1.0/minio_aiops/governance/policy.py +432 -0
- minio_aiops-0.1.0/minio_aiops/governance/sanitize.py +45 -0
- minio_aiops-0.1.0/minio_aiops/governance/undo.py +218 -0
- minio_aiops-0.1.0/minio_aiops/ops/__init__.py +1 -0
- minio_aiops-0.1.0/minio_aiops/ops/_util.py +61 -0
- minio_aiops-0.1.0/minio_aiops/ops/bucket_writes.py +215 -0
- minio_aiops-0.1.0/minio_aiops/ops/buckets.py +123 -0
- minio_aiops-0.1.0/minio_aiops/ops/capacity.py +195 -0
- minio_aiops-0.1.0/minio_aiops/ops/exposure.py +176 -0
- minio_aiops-0.1.0/minio_aiops/ops/healing.py +238 -0
- minio_aiops-0.1.0/minio_aiops/ops/health.py +86 -0
- minio_aiops-0.1.0/minio_aiops/ops/ilm.py +192 -0
- minio_aiops-0.1.0/minio_aiops/ops/overview.py +42 -0
- minio_aiops-0.1.0/minio_aiops/prom.py +78 -0
- minio_aiops-0.1.0/minio_aiops/secretstore.py +304 -0
- minio_aiops-0.1.0/pyproject.toml +61 -0
- minio_aiops-0.1.0/server.json +21 -0
- minio_aiops-0.1.0/skills/minio-aiops/SKILL.md +113 -0
- minio_aiops-0.1.0/skills/minio-aiops/references/capabilities.md +63 -0
- minio_aiops-0.1.0/skills/minio-aiops/references/cli-reference.md +62 -0
- minio_aiops-0.1.0/skills/minio-aiops/references/setup-guide.md +111 -0
- minio_aiops-0.1.0/smithery.yaml +9 -0
- minio_aiops-0.1.0/tests/conftest.py +48 -0
- minio_aiops-0.1.0/tests/test_bucket_writes.py +278 -0
- minio_aiops-0.1.0/tests/test_buckets.py +88 -0
- minio_aiops-0.1.0/tests/test_capacity.py +90 -0
- minio_aiops-0.1.0/tests/test_cli_writes.py +103 -0
- minio_aiops-0.1.0/tests/test_doctor.py +207 -0
- minio_aiops-0.1.0/tests/test_exposure.py +91 -0
- minio_aiops-0.1.0/tests/test_governance_persistence.py +177 -0
- minio_aiops-0.1.0/tests/test_healing.py +104 -0
- minio_aiops-0.1.0/tests/test_ilm.py +96 -0
- minio_aiops-0.1.0/tests/test_init.py +150 -0
- minio_aiops-0.1.0/tests/test_prom.py +59 -0
- minio_aiops-0.1.0/tests/test_secretstore.py +99 -0
- minio_aiops-0.1.0/tests/test_smoke.py +334 -0
- minio_aiops-0.1.0/tests/test_undo_executor.py +138 -0
- minio_aiops-0.1.0/uv.lock +1221 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: mcp-publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
release:
|
|
6
|
+
types: [published]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish-mcp:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Wait for PyPI
|
|
18
|
+
# The release event also triggers the PyPI publish workflow; the MCP
|
|
19
|
+
# registry validates that the package version exists on PyPI, so poll
|
|
20
|
+
# until it has propagated (every 15s, up to 10 minutes).
|
|
21
|
+
run: |
|
|
22
|
+
python3 - <<'EOF'
|
|
23
|
+
import json
|
|
24
|
+
import sys
|
|
25
|
+
import time
|
|
26
|
+
import urllib.error
|
|
27
|
+
import urllib.request
|
|
28
|
+
|
|
29
|
+
with open("server.json", encoding="utf-8") as f:
|
|
30
|
+
package = json.load(f)["packages"][0]
|
|
31
|
+
name, version = package["identifier"], package["version"]
|
|
32
|
+
url = f"https://pypi.org/pypi/{name}/{version}/json"
|
|
33
|
+
deadline = time.monotonic() + 600
|
|
34
|
+
while True:
|
|
35
|
+
try:
|
|
36
|
+
with urllib.request.urlopen(url, timeout=10):
|
|
37
|
+
print(f"{name}=={version} is available on PyPI.")
|
|
38
|
+
sys.exit(0)
|
|
39
|
+
except (urllib.error.URLError, OSError) as exc:
|
|
40
|
+
print(f"{name}=={version} not on PyPI yet ({exc}); "
|
|
41
|
+
"retrying in 15s...")
|
|
42
|
+
if time.monotonic() >= deadline:
|
|
43
|
+
sys.exit(f"Timed out after 10 minutes waiting for "
|
|
44
|
+
f"{name}=={version} to appear on PyPI. "
|
|
45
|
+
"Check the PyPI publish workflow, then re-run "
|
|
46
|
+
"this workflow via workflow_dispatch.")
|
|
47
|
+
time.sleep(15)
|
|
48
|
+
EOF
|
|
49
|
+
- name: Install mcp-publisher
|
|
50
|
+
run: |
|
|
51
|
+
curl -sL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
|
|
52
|
+
- name: Login to MCP Registry (GitHub OIDC)
|
|
53
|
+
run: ./mcp-publisher login github-oidc
|
|
54
|
+
- name: Publish server.json
|
|
55
|
+
run: ./mcp-publisher publish
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Trusted Publishing (OIDC) — publishes from GitHub's runners with no API token,
|
|
4
|
+
# sidestepping the local-IP / account new-project rate limit. Configure a matching
|
|
5
|
+
# "trusted publisher" for this package on PyPI (see the repo release notes).
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
publish:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
permissions:
|
|
18
|
+
id-token: write # required for PyPI Trusted Publishing (OIDC)
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Set up uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
- name: Build sdist + wheel
|
|
24
|
+
run: uv build
|
|
25
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
26
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **minio-aiops** are documented here.
|
|
4
|
+
|
|
5
|
+
## v0.1.0 — 2026-07-17
|
|
6
|
+
|
|
7
|
+
Initial preview release: governed AI-ops for **MinIO** object storage over the
|
|
8
|
+
S3 API (official SDK), the admin API, the unauthenticated health endpoints,
|
|
9
|
+
and the cluster metrics endpoint — with a bundled governance harness.
|
|
10
|
+
|
|
11
|
+
### Highlights
|
|
12
|
+
|
|
13
|
+
- **Four flagship analyses** (cause + suggested action, thresholds as named
|
|
14
|
+
constants):
|
|
15
|
+
- `capacity_rca` — usable capacity vs used, offline drives/nodes, per-drive
|
|
16
|
+
hotspots, fill imbalance.
|
|
17
|
+
- `bucket_exposure_audit` — ranked findings: anonymous/public policy
|
|
18
|
+
statements (read/write), missing default encryption, versioning off, no
|
|
19
|
+
lifecycle.
|
|
20
|
+
- `lifecycle_gap_analysis` — unbounded noncurrent versions, incomplete
|
|
21
|
+
multipart uploads with no abort rule, large buckets with no lifecycle —
|
|
22
|
+
with a labelled reclaimable estimate.
|
|
23
|
+
- `healing_health` — heal backlog/errors + per-erasure-set write-quorum
|
|
24
|
+
risk and remaining drive-failure tolerance.
|
|
25
|
+
- **29 MCP tools** (21 read, 8 write), every one wrapped with the bundled
|
|
26
|
+
`@governed_tool` harness (audit / budget / risk-tier / undo).
|
|
27
|
+
- **Guarded writes**: `set_bucket_policy`, `delete_bucket_policy`,
|
|
28
|
+
`set_versioning`, `set_lifecycle`, `delete_lifecycle`, `set_bucket_quota`
|
|
29
|
+
(all reversible — real prior state captured, undo recorded);
|
|
30
|
+
`bucket_delete` (high risk, refused unless verifiably empty, irreversible);
|
|
31
|
+
`remove_incomplete_uploads` (age-gated, priorState only). All writes take
|
|
32
|
+
`dry_run`.
|
|
33
|
+
- **CLI**: `init` wizard (encrypted secret store, TLS prompts with lab hints,
|
|
34
|
+
seeds a secure-by-default `rules.yaml`), `doctor` (live/ready + S3 auth +
|
|
35
|
+
metrics reachability), `overview`, read groups (`health`, `capacity`,
|
|
36
|
+
`heal`, `bucket`) and guarded write commands with `--dry-run` +
|
|
37
|
+
double-confirm, delegated to the governed MCP twins (CLI writes are
|
|
38
|
+
audited).
|
|
39
|
+
- **Metrics auth, both modes**: `MINIO_PROMETHEUS_AUTH_TYPE=public` scraped
|
|
40
|
+
directly; default `jwt` mode uses a bearer token derived from the stored
|
|
41
|
+
credentials.
|
|
42
|
+
- **Encrypted credentials**: secret key in `~/.minio-aiops/secrets.enc`
|
|
43
|
+
(Fernet + scrypt), master password via `MINIO_AIOPS_MASTER_PASSWORD`;
|
|
44
|
+
legacy `MINIO_<TARGET>_SECRET_KEY` env fallback with `secret migrate`.
|
|
45
|
+
|
|
46
|
+
### Known limitations
|
|
47
|
+
|
|
48
|
+
- **Preview / mock-only** — validated against mocked SDK/HTTP responses, not
|
|
49
|
+
yet against a live server. Fastest live check: a single-node MinIO server
|
|
50
|
+
running `minio-aiops doctor`.
|
|
51
|
+
- Incomplete-upload listing uses the SDK's core ListMultipartUploads call
|
|
52
|
+
(the public alias was removed upstream).
|
|
53
|
+
- Out of scope for v0.1.0: site replication, object locking/legal hold, IAM
|
|
54
|
+
(users/policies) management, remote tiering.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wei <zhouwei008@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: minio-aiops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Governed AI-ops for MinIO object storage: capacity & usage RCA, bucket exposure audit, lifecycle/ILM gap analysis, healing & erasure-set health, and guarded bucket writes with a built-in governance harness (audit, budget, undo, risk tiers)
|
|
5
|
+
Author-email: wei <zhouwei008@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: cryptography>=42.0
|
|
10
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
11
|
+
Requires-Dist: mcp[cli]<2.0,>=1.10
|
|
12
|
+
Requires-Dist: minio<8.0,>=7.2
|
|
13
|
+
Requires-Dist: pyyaml<7.0,>=6.0
|
|
14
|
+
Requires-Dist: rich<16.0,>=13.0
|
|
15
|
+
Requires-Dist: typer<1.0,>=0.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
<!-- mcp-name: io.github.AIops-tools/minio-aiops -->
|
|
19
|
+
|
|
20
|
+
# MinIO AIops (preview)
|
|
21
|
+
|
|
22
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by MinIO, Inc. or any storage vendor.** Product and trademark names belong to their owners. MIT licensed.
|
|
23
|
+
|
|
24
|
+
Governed AI-ops for **MinIO** object storage — for the homelab and small/medium
|
|
25
|
+
self-hosted deployments where MinIO actually lives. Talks to the **S3 API**
|
|
26
|
+
(official `minio` SDK, SigV4), the **admin API** (bucket quota, server info),
|
|
27
|
+
the unauthenticated **health endpoints** (`/minio/health/live|ready|cluster`),
|
|
28
|
+
and the **cluster metrics endpoint** (`/minio/v2/metrics/cluster`, bearer-token
|
|
29
|
+
or public auth) — with a **built-in governance harness**: unified audit log,
|
|
30
|
+
policy engine, token/runaway budget guard, undo-token recording, and
|
|
31
|
+
graduated-autonomy risk tiers. Self-contained: no external skill-family
|
|
32
|
+
dependency. **Preview — mock-validated only, not yet verified against a live
|
|
33
|
+
server.**
|
|
34
|
+
|
|
35
|
+
## What it does
|
|
36
|
+
|
|
37
|
+
Four flagship analyses, plus the guarded reads and writes around them:
|
|
38
|
+
|
|
39
|
+
- **`capacity_rca`** — capacity vs used, offline drives/nodes, per-drive
|
|
40
|
+
hotspots and imbalance → each finding as **cause + suggested action**
|
|
41
|
+
(nearfull/full thresholds are named constants, not magic).
|
|
42
|
+
- **`bucket_exposure_audit`** — every bucket scored and **ranked** for
|
|
43
|
+
anonymous/public policy statements (read and, far worse, write), missing
|
|
44
|
+
default encryption, versioning off, no lifecycle.
|
|
45
|
+
- **`lifecycle_gap_analysis`** — the storage ILM should be reclaiming but
|
|
46
|
+
isn't: versioned buckets with **no noncurrent expiry** (old bytes accrue
|
|
47
|
+
forever), **incomplete multipart uploads** with no abort rule (invisible
|
|
48
|
+
space), large buckets with no lifecycle — with a clearly-labelled
|
|
49
|
+
**reclaimable estimate**.
|
|
50
|
+
- **`healing_health`** — heal backlog and per-erasure-set **write-quorum
|
|
51
|
+
risk**: how many more drive failures each set can tolerate, which sets are
|
|
52
|
+
healing, where heal errors are piling up.
|
|
53
|
+
- **Governed writes.** Bucket policy / versioning / lifecycle / quota changes
|
|
54
|
+
capture the **real prior state** and record an **undo descriptor**;
|
|
55
|
+
`bucket_delete` is **refused unless the bucket is verifiably empty**
|
|
56
|
+
(including versions and delete markers) and `remove_incomplete_uploads`
|
|
57
|
+
only touches uploads older than a safety window.
|
|
58
|
+
|
|
59
|
+
## What works
|
|
60
|
+
|
|
61
|
+
- **CLI** (`minio-aiops ...`): `init`, `overview`, `doctor`, `health
|
|
62
|
+
check/status`, `capacity rca/usage`, `heal status/drives/nodes`, `bucket
|
|
63
|
+
ls/info/audit/ilm-gap/uploads` plus guarded writes (`bucket
|
|
64
|
+
versioning-set/policy-set/lifecycle-set/quota-set/purge-uploads/delete`),
|
|
65
|
+
`secret set/list/rm/migrate/rotate-password`, `mcp`. Destructive commands
|
|
66
|
+
take `--dry-run` and double-confirm.
|
|
67
|
+
- **MCP server** (`minio-aiops mcp` or `minio-aiops-mcp`): the full **29
|
|
68
|
+
tools** (21 read, 8 write), every one wrapped with the bundled
|
|
69
|
+
`@governed_tool` harness. The CLI is a convenience subset; the MCP surface
|
|
70
|
+
is the whole tool. CLI writes delegate to the same governed functions, so
|
|
71
|
+
they are audited identically.
|
|
72
|
+
- **Encrypted credentials**: the secret key lives in an encrypted store
|
|
73
|
+
`~/.minio-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on
|
|
74
|
+
disk**. Unlock with a master password from `MINIO_AIOPS_MASTER_PASSWORD`
|
|
75
|
+
(MCP/CI) or an interactive prompt (CLI).
|
|
76
|
+
- **Metrics auth, both modes**: servers running
|
|
77
|
+
`MINIO_PROMETHEUS_AUTH_TYPE=public` are scraped directly; for the default
|
|
78
|
+
(`jwt`) mode the bearer token is **derived from the stored credentials** —
|
|
79
|
+
no extra secret to manage.
|
|
80
|
+
- **Reversibility**: reversible writes capture prior state and record an
|
|
81
|
+
inverse undo descriptor (prior policy JSON, prior lifecycle XML, prior
|
|
82
|
+
versioning state, prior quota).
|
|
83
|
+
|
|
84
|
+
## Capability matrix (29 MCP tools)
|
|
85
|
+
|
|
86
|
+
| Group | Tools | Count | R/W |
|
|
87
|
+
|-------|-------|:-----:|:---:|
|
|
88
|
+
| **Health** | `health_live`, `health_ready`, `health_cluster`, `cluster_status`, `fleet_overview` | 5 | read |
|
|
89
|
+
| **Capacity** | `capacity_rca` (flagship), `usage_by_bucket` | 2 | read |
|
|
90
|
+
| **Healing** | `healing_health` (flagship), `drive_status`, `node_status` | 3 | read |
|
|
91
|
+
| **Exposure / ILM** | `bucket_exposure_audit` (flagship), `lifecycle_gap_analysis` (flagship) | 2 | read |
|
|
92
|
+
| **Buckets** | `bucket_ls`, `bucket_info`, `bucket_policy_get`, `bucket_lifecycle_get`, `bucket_versioning_get`, `bucket_quota_get`, `object_ls`, `incomplete_uploads_ls`, `server_info` | 9 | read |
|
|
93
|
+
| **Writes** | `set_bucket_policy` (med, undo), `delete_bucket_policy` (med, undo), `set_versioning` (med, undo), `set_lifecycle` (med, undo), `delete_lifecycle` (med, undo), `set_bucket_quota` (med, undo) | 6 | write |
|
|
94
|
+
| | `bucket_delete` (**high**, dry-run, empty-only, irreversible), `remove_incomplete_uploads` (med, dry-run, priorState only) | 2 | write |
|
|
95
|
+
|
|
96
|
+
Totals: **29 tools — 21 read, 8 write.**
|
|
97
|
+
|
|
98
|
+
## Quick start
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv tool install minio-aiops # or: pipx install minio-aiops
|
|
102
|
+
minio-aiops init # wizard: endpoint + access key; secret key stored encrypted
|
|
103
|
+
minio-aiops doctor # live/ready + S3 auth + metrics reachability
|
|
104
|
+
minio-aiops overview # health + capacity headline + exposure headline
|
|
105
|
+
minio-aiops capacity rca # why is storage filling up, and what to do
|
|
106
|
+
minio-aiops bucket audit # ranked bucket-exposure findings
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Run as an MCP server (stdio):
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
export MINIO_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
|
|
113
|
+
minio-aiops-mcp
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### MCP client config
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"minio-aiops": {
|
|
122
|
+
"command": "uvx",
|
|
123
|
+
"args": ["--from", "minio-aiops", "minio-aiops-mcp"],
|
|
124
|
+
"env": { "MINIO_AIOPS_MASTER_PASSWORD": "your-master-password" }
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> **Env-block caveat**: MCP clients launch the server **without a TTY and
|
|
131
|
+
> without your shell profile**, so the master password cannot be prompted for
|
|
132
|
+
> and an `export` in `~/.zshrc` is not seen — it must be passed in the client's
|
|
133
|
+
> `env` block (or the client process's environment) as above. Everything else
|
|
134
|
+
> (targets, TLS, region, metrics mode) comes from `~/.minio-aiops/config.yaml`
|
|
135
|
+
> written by `minio-aiops init`.
|
|
136
|
+
|
|
137
|
+
## Configuration
|
|
138
|
+
|
|
139
|
+
`~/.minio-aiops/config.yaml` (non-secret connection details only):
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
targets:
|
|
143
|
+
- name: lab1
|
|
144
|
+
host: 192.0.2.10
|
|
145
|
+
port: 9000
|
|
146
|
+
access_key: minio-ops # identifies the account; NOT the secret
|
|
147
|
+
secure: true # https (false for plain-http labs)
|
|
148
|
+
verify_ssl: true # false for self-signed lab certs
|
|
149
|
+
region: "" # optional
|
|
150
|
+
metrics_public: false # true when MINIO_PROMETHEUS_AUTH_TYPE=public
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The secret key is stored with `minio-aiops secret set lab1` (encrypted; a
|
|
154
|
+
legacy `MINIO_LAB1_SECRET_KEY` env var is honoured as a fallback with a
|
|
155
|
+
migration warning).
|
|
156
|
+
|
|
157
|
+
## Governance
|
|
158
|
+
|
|
159
|
+
Every MCP tool passes through the bundled `@governed_tool` harness:
|
|
160
|
+
|
|
161
|
+
- **Audit** — every call (params, result, status, duration, risk tier,
|
|
162
|
+
approver, rationale) is logged to `~/.minio-aiops/audit.db` (relocatable
|
|
163
|
+
via `MINIO_AIOPS_HOME`).
|
|
164
|
+
- **Budget / runaway guard** — token and call budgets trip a circuit breaker.
|
|
165
|
+
- **Risk tiers, secure by default** — with no `rules.yaml`, high-risk ops
|
|
166
|
+
(`bucket_delete`) **require a named approver**
|
|
167
|
+
(`MINIO_AUDIT_APPROVED_BY` / `MINIO_AUDIT_RATIONALE`); `init` seeds an
|
|
168
|
+
explicit, editable starter policy.
|
|
169
|
+
- **Undo recording** — reversible writes record an inverse descriptor built
|
|
170
|
+
from the captured prior state.
|
|
171
|
+
|
|
172
|
+
## Supported scope & limitations
|
|
173
|
+
|
|
174
|
+
- **Deployments**: any reasonably current MinIO server (single-node or
|
|
175
|
+
distributed/erasure-coded) reachable over its S3 port. Admin features
|
|
176
|
+
(quota, `server_info`) need admin-capable keys. Generic S3 services are not
|
|
177
|
+
a target: the health/metrics/admin surfaces used here are MinIO-specific.
|
|
178
|
+
- **Metrics**: the capacity/healing RCAs read the **v2 cluster metrics**
|
|
179
|
+
endpoint; both `public` and bearer-token (default) auth modes are supported.
|
|
180
|
+
- **Incomplete-upload listing** uses the SDK's core ListMultipartUploads call
|
|
181
|
+
(the public alias was removed from the SDK); it is exercised in tests and
|
|
182
|
+
documented in `connection.py`.
|
|
183
|
+
- **Preview / mock-only.** Behaviour is validated against mocked SDK/HTTP
|
|
184
|
+
responses. The cheapest **live** check is a single-node MinIO server (a
|
|
185
|
+
container or the bare binary with a data directory) running
|
|
186
|
+
`minio-aiops doctor`. Erasure-set/healing findings need a multi-drive
|
|
187
|
+
deployment to observe for real.
|
|
188
|
+
|
|
189
|
+
## Missing a capability?
|
|
190
|
+
|
|
191
|
+
Site replication status, object locking / legal-hold governance, per-user /
|
|
192
|
+
policy (IAM) management, tiering to remote storage — not here yet. **Open an
|
|
193
|
+
issue or send a PR** — feedback and contributions are welcome.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.AIops-tools/minio-aiops -->
|
|
2
|
+
|
|
3
|
+
# MinIO AIops (preview)
|
|
4
|
+
|
|
5
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by MinIO, Inc. or any storage vendor.** Product and trademark names belong to their owners. MIT licensed.
|
|
6
|
+
|
|
7
|
+
Governed AI-ops for **MinIO** object storage — for the homelab and small/medium
|
|
8
|
+
self-hosted deployments where MinIO actually lives. Talks to the **S3 API**
|
|
9
|
+
(official `minio` SDK, SigV4), the **admin API** (bucket quota, server info),
|
|
10
|
+
the unauthenticated **health endpoints** (`/minio/health/live|ready|cluster`),
|
|
11
|
+
and the **cluster metrics endpoint** (`/minio/v2/metrics/cluster`, bearer-token
|
|
12
|
+
or public auth) — with a **built-in governance harness**: unified audit log,
|
|
13
|
+
policy engine, token/runaway budget guard, undo-token recording, and
|
|
14
|
+
graduated-autonomy risk tiers. Self-contained: no external skill-family
|
|
15
|
+
dependency. **Preview — mock-validated only, not yet verified against a live
|
|
16
|
+
server.**
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
Four flagship analyses, plus the guarded reads and writes around them:
|
|
21
|
+
|
|
22
|
+
- **`capacity_rca`** — capacity vs used, offline drives/nodes, per-drive
|
|
23
|
+
hotspots and imbalance → each finding as **cause + suggested action**
|
|
24
|
+
(nearfull/full thresholds are named constants, not magic).
|
|
25
|
+
- **`bucket_exposure_audit`** — every bucket scored and **ranked** for
|
|
26
|
+
anonymous/public policy statements (read and, far worse, write), missing
|
|
27
|
+
default encryption, versioning off, no lifecycle.
|
|
28
|
+
- **`lifecycle_gap_analysis`** — the storage ILM should be reclaiming but
|
|
29
|
+
isn't: versioned buckets with **no noncurrent expiry** (old bytes accrue
|
|
30
|
+
forever), **incomplete multipart uploads** with no abort rule (invisible
|
|
31
|
+
space), large buckets with no lifecycle — with a clearly-labelled
|
|
32
|
+
**reclaimable estimate**.
|
|
33
|
+
- **`healing_health`** — heal backlog and per-erasure-set **write-quorum
|
|
34
|
+
risk**: how many more drive failures each set can tolerate, which sets are
|
|
35
|
+
healing, where heal errors are piling up.
|
|
36
|
+
- **Governed writes.** Bucket policy / versioning / lifecycle / quota changes
|
|
37
|
+
capture the **real prior state** and record an **undo descriptor**;
|
|
38
|
+
`bucket_delete` is **refused unless the bucket is verifiably empty**
|
|
39
|
+
(including versions and delete markers) and `remove_incomplete_uploads`
|
|
40
|
+
only touches uploads older than a safety window.
|
|
41
|
+
|
|
42
|
+
## What works
|
|
43
|
+
|
|
44
|
+
- **CLI** (`minio-aiops ...`): `init`, `overview`, `doctor`, `health
|
|
45
|
+
check/status`, `capacity rca/usage`, `heal status/drives/nodes`, `bucket
|
|
46
|
+
ls/info/audit/ilm-gap/uploads` plus guarded writes (`bucket
|
|
47
|
+
versioning-set/policy-set/lifecycle-set/quota-set/purge-uploads/delete`),
|
|
48
|
+
`secret set/list/rm/migrate/rotate-password`, `mcp`. Destructive commands
|
|
49
|
+
take `--dry-run` and double-confirm.
|
|
50
|
+
- **MCP server** (`minio-aiops mcp` or `minio-aiops-mcp`): the full **29
|
|
51
|
+
tools** (21 read, 8 write), every one wrapped with the bundled
|
|
52
|
+
`@governed_tool` harness. The CLI is a convenience subset; the MCP surface
|
|
53
|
+
is the whole tool. CLI writes delegate to the same governed functions, so
|
|
54
|
+
they are audited identically.
|
|
55
|
+
- **Encrypted credentials**: the secret key lives in an encrypted store
|
|
56
|
+
`~/.minio-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on
|
|
57
|
+
disk**. Unlock with a master password from `MINIO_AIOPS_MASTER_PASSWORD`
|
|
58
|
+
(MCP/CI) or an interactive prompt (CLI).
|
|
59
|
+
- **Metrics auth, both modes**: servers running
|
|
60
|
+
`MINIO_PROMETHEUS_AUTH_TYPE=public` are scraped directly; for the default
|
|
61
|
+
(`jwt`) mode the bearer token is **derived from the stored credentials** —
|
|
62
|
+
no extra secret to manage.
|
|
63
|
+
- **Reversibility**: reversible writes capture prior state and record an
|
|
64
|
+
inverse undo descriptor (prior policy JSON, prior lifecycle XML, prior
|
|
65
|
+
versioning state, prior quota).
|
|
66
|
+
|
|
67
|
+
## Capability matrix (29 MCP tools)
|
|
68
|
+
|
|
69
|
+
| Group | Tools | Count | R/W |
|
|
70
|
+
|-------|-------|:-----:|:---:|
|
|
71
|
+
| **Health** | `health_live`, `health_ready`, `health_cluster`, `cluster_status`, `fleet_overview` | 5 | read |
|
|
72
|
+
| **Capacity** | `capacity_rca` (flagship), `usage_by_bucket` | 2 | read |
|
|
73
|
+
| **Healing** | `healing_health` (flagship), `drive_status`, `node_status` | 3 | read |
|
|
74
|
+
| **Exposure / ILM** | `bucket_exposure_audit` (flagship), `lifecycle_gap_analysis` (flagship) | 2 | read |
|
|
75
|
+
| **Buckets** | `bucket_ls`, `bucket_info`, `bucket_policy_get`, `bucket_lifecycle_get`, `bucket_versioning_get`, `bucket_quota_get`, `object_ls`, `incomplete_uploads_ls`, `server_info` | 9 | read |
|
|
76
|
+
| **Writes** | `set_bucket_policy` (med, undo), `delete_bucket_policy` (med, undo), `set_versioning` (med, undo), `set_lifecycle` (med, undo), `delete_lifecycle` (med, undo), `set_bucket_quota` (med, undo) | 6 | write |
|
|
77
|
+
| | `bucket_delete` (**high**, dry-run, empty-only, irreversible), `remove_incomplete_uploads` (med, dry-run, priorState only) | 2 | write |
|
|
78
|
+
|
|
79
|
+
Totals: **29 tools — 21 read, 8 write.**
|
|
80
|
+
|
|
81
|
+
## Quick start
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uv tool install minio-aiops # or: pipx install minio-aiops
|
|
85
|
+
minio-aiops init # wizard: endpoint + access key; secret key stored encrypted
|
|
86
|
+
minio-aiops doctor # live/ready + S3 auth + metrics reachability
|
|
87
|
+
minio-aiops overview # health + capacity headline + exposure headline
|
|
88
|
+
minio-aiops capacity rca # why is storage filling up, and what to do
|
|
89
|
+
minio-aiops bucket audit # ranked bucket-exposure findings
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Run as an MCP server (stdio):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
export MINIO_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
|
|
96
|
+
minio-aiops-mcp
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### MCP client config
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"mcpServers": {
|
|
104
|
+
"minio-aiops": {
|
|
105
|
+
"command": "uvx",
|
|
106
|
+
"args": ["--from", "minio-aiops", "minio-aiops-mcp"],
|
|
107
|
+
"env": { "MINIO_AIOPS_MASTER_PASSWORD": "your-master-password" }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
> **Env-block caveat**: MCP clients launch the server **without a TTY and
|
|
114
|
+
> without your shell profile**, so the master password cannot be prompted for
|
|
115
|
+
> and an `export` in `~/.zshrc` is not seen — it must be passed in the client's
|
|
116
|
+
> `env` block (or the client process's environment) as above. Everything else
|
|
117
|
+
> (targets, TLS, region, metrics mode) comes from `~/.minio-aiops/config.yaml`
|
|
118
|
+
> written by `minio-aiops init`.
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
`~/.minio-aiops/config.yaml` (non-secret connection details only):
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
targets:
|
|
126
|
+
- name: lab1
|
|
127
|
+
host: 192.0.2.10
|
|
128
|
+
port: 9000
|
|
129
|
+
access_key: minio-ops # identifies the account; NOT the secret
|
|
130
|
+
secure: true # https (false for plain-http labs)
|
|
131
|
+
verify_ssl: true # false for self-signed lab certs
|
|
132
|
+
region: "" # optional
|
|
133
|
+
metrics_public: false # true when MINIO_PROMETHEUS_AUTH_TYPE=public
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The secret key is stored with `minio-aiops secret set lab1` (encrypted; a
|
|
137
|
+
legacy `MINIO_LAB1_SECRET_KEY` env var is honoured as a fallback with a
|
|
138
|
+
migration warning).
|
|
139
|
+
|
|
140
|
+
## Governance
|
|
141
|
+
|
|
142
|
+
Every MCP tool passes through the bundled `@governed_tool` harness:
|
|
143
|
+
|
|
144
|
+
- **Audit** — every call (params, result, status, duration, risk tier,
|
|
145
|
+
approver, rationale) is logged to `~/.minio-aiops/audit.db` (relocatable
|
|
146
|
+
via `MINIO_AIOPS_HOME`).
|
|
147
|
+
- **Budget / runaway guard** — token and call budgets trip a circuit breaker.
|
|
148
|
+
- **Risk tiers, secure by default** — with no `rules.yaml`, high-risk ops
|
|
149
|
+
(`bucket_delete`) **require a named approver**
|
|
150
|
+
(`MINIO_AUDIT_APPROVED_BY` / `MINIO_AUDIT_RATIONALE`); `init` seeds an
|
|
151
|
+
explicit, editable starter policy.
|
|
152
|
+
- **Undo recording** — reversible writes record an inverse descriptor built
|
|
153
|
+
from the captured prior state.
|
|
154
|
+
|
|
155
|
+
## Supported scope & limitations
|
|
156
|
+
|
|
157
|
+
- **Deployments**: any reasonably current MinIO server (single-node or
|
|
158
|
+
distributed/erasure-coded) reachable over its S3 port. Admin features
|
|
159
|
+
(quota, `server_info`) need admin-capable keys. Generic S3 services are not
|
|
160
|
+
a target: the health/metrics/admin surfaces used here are MinIO-specific.
|
|
161
|
+
- **Metrics**: the capacity/healing RCAs read the **v2 cluster metrics**
|
|
162
|
+
endpoint; both `public` and bearer-token (default) auth modes are supported.
|
|
163
|
+
- **Incomplete-upload listing** uses the SDK's core ListMultipartUploads call
|
|
164
|
+
(the public alias was removed from the SDK); it is exercised in tests and
|
|
165
|
+
documented in `connection.py`.
|
|
166
|
+
- **Preview / mock-only.** Behaviour is validated against mocked SDK/HTTP
|
|
167
|
+
responses. The cheapest **live** check is a single-node MinIO server (a
|
|
168
|
+
container or the bare binary with a data directory) running
|
|
169
|
+
`minio-aiops doctor`. Erasure-set/healing findings need a multi-drive
|
|
170
|
+
deployment to observe for real.
|
|
171
|
+
|
|
172
|
+
## Missing a capability?
|
|
173
|
+
|
|
174
|
+
Site replication status, object locking / legal-hold governance, per-user /
|
|
175
|
+
policy (IAM) management, tiering to remote storage — not here yet. **Open an
|
|
176
|
+
issue or send a PR** — feedback and contributions are welcome.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# MinIO AIops v0.1.0 — preview
|
|
2
|
+
|
|
3
|
+
Governed AI-ops for **MinIO** object storage for AI agents (MCP) and humans
|
|
4
|
+
(CLI), with a bundled governance harness: audit, policy, token/runaway budget,
|
|
5
|
+
undo recording, graduated risk tiers.
|
|
6
|
+
|
|
7
|
+
> **Preview**: behaviour is validated against mocked SDK/HTTP responses; it
|
|
8
|
+
> has not been run against a live MinIO server. The fastest live check is a
|
|
9
|
+
> single-node server running `minio-aiops doctor`.
|
|
10
|
+
|
|
11
|
+
## Surface
|
|
12
|
+
|
|
13
|
+
- **29 MCP tools** (21 read, 8 write) over four access paths: S3 API (official
|
|
14
|
+
SDK), admin API (quota, server info), unauthenticated health endpoints, and
|
|
15
|
+
the cluster metrics endpoint (public or bearer-token auth — the token is
|
|
16
|
+
derived from the stored credentials).
|
|
17
|
+
- **Flagship analyses**: `capacity_rca`, `bucket_exposure_audit`,
|
|
18
|
+
`lifecycle_gap_analysis`, `healing_health` — every finding is
|
|
19
|
+
cause + suggested action, thresholds are named constants.
|
|
20
|
+
- **Guarded writes**: policy / versioning / lifecycle / quota (reversible,
|
|
21
|
+
prior state captured, undo recorded), `bucket_delete` (high risk, empty-only,
|
|
22
|
+
irreversible), `remove_incomplete_uploads` (age-gated purge, priorState
|
|
23
|
+
only). All writes take `dry_run`; destructive CLI commands double-confirm.
|
|
24
|
+
|
|
25
|
+
## Governance
|
|
26
|
+
|
|
27
|
+
- Unified audit log `~/.minio-aiops/audit.db` (relocatable via
|
|
28
|
+
`MINIO_AIOPS_HOME`); CLI writes route through the same governed functions.
|
|
29
|
+
- Secure by default: with no `rules.yaml`, high-risk writes require a named
|
|
30
|
+
approver (`MINIO_AUDIT_APPROVED_BY`); `init` seeds an explicit starter
|
|
31
|
+
policy.
|
|
32
|
+
- Encrypted secret store (`secrets.enc`, Fernet + scrypt) — no plaintext
|
|
33
|
+
secrets on disk.
|
|
34
|
+
|
|
35
|
+
## Quality gates (this release)
|
|
36
|
+
|
|
37
|
+
- 114 tests green (pytest), `ruff check` clean, bandit 0 Medium+ findings.
|
|
38
|
+
- Every MCP tool carries the `_is_governed_tool` marker.
|
|
39
|
+
- Undo descriptors are replay-tested against the target tool signatures.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Disclaimer
|
|
4
|
+
|
|
5
|
+
Community-maintained open-source project. **Not affiliated with, endorsed by, or
|
|
6
|
+
sponsored by MinIO, Inc. or any storage vendor.** Product and trademark names
|
|
7
|
+
belong to their owners. Source is publicly auditable under the MIT license.
|
|
8
|
+
|
|
9
|
+
## Reporting Vulnerabilities
|
|
10
|
+
|
|
11
|
+
Report privately via a GitHub Security Advisory on
|
|
12
|
+
[github.com/AIops-tools/MinIO-AIops](https://github.com/AIops-tools/MinIO-AIops/security/advisories)
|
|
13
|
+
or email zhouwei008@gmail.com. Please do not open public issues for security
|
|
14
|
+
reports.
|
|
15
|
+
|
|
16
|
+
## Security Design
|
|
17
|
+
|
|
18
|
+
### Credential Management
|
|
19
|
+
- Per-target **secret keys** live **encrypted** in
|
|
20
|
+
`~/.minio-aiops/secrets.enc` (Fernet/AES-128 + scrypt-derived key; chmod
|
|
21
|
+
600), never in `config.yaml` and never in source. The master password is
|
|
22
|
+
never stored — only a per-store random salt and the ciphertext are on disk.
|
|
23
|
+
- A legacy plaintext env var `MINIO_<TARGET_NAME_UPPER>_SECRET_KEY` is still
|
|
24
|
+
honoured as a fallback with a deprecation warning (migrate with
|
|
25
|
+
`minio-aiops secret migrate`).
|
|
26
|
+
- S3/admin requests are **SigV4-signed** by the official SDK; the secret key
|
|
27
|
+
is held only in memory, never logged or echoed. The metrics bearer token is
|
|
28
|
+
derived from the credentials at request time (short TTL) and never stored.
|
|
29
|
+
The config file holds only host, port, access key, TLS/region/metrics
|
|
30
|
+
settings.
|
|
31
|
+
|
|
32
|
+
### Governed Operations
|
|
33
|
+
Every MCP tool runs through the bundled `@governed_tool` harness
|
|
34
|
+
(`minio_aiops.governance`):
|
|
35
|
+
- **Audit** — every call logged to a local SQLite DB under `~/.minio-aiops/`
|
|
36
|
+
(relocatable via `MINIO_AIOPS_HOME`), agent-attributed, secret-redacted.
|
|
37
|
+
- **Token/runaway budget** — hard ceilings (`MINIO_MAX_TOOL_CALLS` /
|
|
38
|
+
`MINIO_MAX_TOOL_SECONDS`) plus an on-by-default guard that trips a tight
|
|
39
|
+
poll/retry loop, preventing unbounded API consumption.
|
|
40
|
+
- **Graduated risk tiers, secure by default** — with no
|
|
41
|
+
`~/.minio-aiops/rules.yaml`, high-risk writes require a recorded approver;
|
|
42
|
+
the `init` wizard seeds an explicit, editable starter policy.
|
|
43
|
+
- **Undo-token recording** — reversible writes capture the BEFORE state and
|
|
44
|
+
record an inverse descriptor (prior policy JSON, prior lifecycle XML, prior
|
|
45
|
+
versioning state, prior quota) so the change can be rolled back.
|
|
46
|
+
|
|
47
|
+
### State-Changing Operations
|
|
48
|
+
`bucket_delete` is `risk_level=high`, accepts a `dry_run` preview, requires a
|
|
49
|
+
recorded approver (`MINIO_AUDIT_APPROVED_BY` + `MINIO_AUDIT_RATIONALE`) under
|
|
50
|
+
the default policy, and is **refused unless the bucket is verifiably empty**
|
|
51
|
+
(including noncurrent versions and delete markers) — this tool never
|
|
52
|
+
mass-deletes objects to force a bucket empty. `remove_incomplete_uploads`
|
|
53
|
+
only aborts uploads older than a safety window (default 7 days) and records
|
|
54
|
+
priorState (count + sample). The CLI double-confirms both and supports
|
|
55
|
+
`--dry-run` everywhere. All agent-supplied bucket names are validated against
|
|
56
|
+
strict S3 naming rules before any request is built (the injection gate).
|
|
57
|
+
|
|
58
|
+
### SSL/TLS Verification
|
|
59
|
+
`secure` (https) and `verify_ssl` default to true; disable verification only
|
|
60
|
+
for self-signed lab certificates.
|
|
61
|
+
|
|
62
|
+
### Output Hygiene
|
|
63
|
+
All server-returned text (bucket/object names, policy contents, error bodies,
|
|
64
|
+
metric labels) is passed through a `sanitize()` truncate + control-character
|
|
65
|
+
strip before reaching the agent.
|
|
66
|
+
|
|
67
|
+
### Network Scope
|
|
68
|
+
No webhooks, no telemetry, no outbound calls beyond the configured MinIO
|
|
69
|
+
endpoint (S3/admin/health/metrics paths on the same origin). No post-install
|
|
70
|
+
scripts or background services.
|
|
71
|
+
|
|
72
|
+
## Static Analysis
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
uvx bandit -r minio_aiops/ mcp_server/
|
|
76
|
+
uv run ruff check .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Supported Versions
|
|
80
|
+
|
|
81
|
+
The latest released version receives security fixes. This is a preview (0.x);
|
|
82
|
+
pin a version in production.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""MCP server package for minio-aiops."""
|