mqgov-cli 0.1.0 → 0.2.0
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.
- package/README.md +51 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Governed message-broker operations for humans _and_ AI agents.**
|
|
6
6
|
|
|
7
|
-
One safe command line for **Kafka**, **RabbitMQ**, **Pulsar**, and **RocketMQ** — list, describe, peek, produce, reset offsets, purge, and delete topics without ever fat-fingering production or silently draining a queue.
|
|
7
|
+
One safe command line for **Kafka**, **RabbitMQ**, **Pulsar**, and **RocketMQ** — list, describe, peek, tail, produce, reset offsets, inspect ACLs, purge, and delete topics without ever fat-fingering production or silently draining a queue.
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/mqgov-cli)
|
|
10
10
|
[](https://github.com/JiangHe12/mqgov-cli/actions/workflows/ci.yml)
|
|
@@ -25,7 +25,7 @@ Message brokers — **Kafka**, **RabbitMQ**, **Pulsar**, **RocketMQ** — are th
|
|
|
25
25
|
|
|
26
26
|
- 🔎 **Shows you the blast radius first** — `--dry-run` / `--plan` print the exact per-partition impact (how many messages an offset reset will replay or skip) before anything happens.
|
|
27
27
|
- 🛡️ **Refuses to do something dangerous without explicit sign-off** — risky commands need a confirmation flag, a change ticket, and an explicit `--allow-*` for the operation.
|
|
28
|
-
- 👀 **Peeks without consuming** — inspecting
|
|
28
|
+
- 👀 **Peeks/tails without consuming** — inspecting or streaming message fingerprints never advances a consumer's position or drains a queue.
|
|
29
29
|
- 📜 **Records everything in a tamper-evident audit log** — sha256 fingerprints and counts only, **never your message bodies**.
|
|
30
30
|
- 🤖 **Is safe to hand to an AI agent** — the agent can read and preview freely, but **cannot** invent the human approvals required for dangerous actions.
|
|
31
31
|
|
|
@@ -38,10 +38,10 @@ It's built on the shared [`opskit-core`](https://github.com/JiangHe12/opskit-cor
|
|
|
38
38
|
| | |
|
|
39
39
|
|---|---|
|
|
40
40
|
| 📨 **Four brokers** | **Kafka** (franz-go), **RabbitMQ** (AMQP + management API), **Pulsar** (client + admin REST), **RocketMQ** (rocketmq-client-go/v2). One backend-agnostic governance model; pick per context or override per command. |
|
|
41
|
-
| 🧱 **topic / group / message** | topics: list · describe · create · alter · delete · purge. consumer groups: list · lag · reset-offset. messages: non-destructive peek · produce. |
|
|
41
|
+
| 🧱 **topic / group / message / acl** | topics: list · describe · create · alter · delete · purge. consumer groups: list · lag · reset-offset. messages: non-destructive peek · tail · produce. ACLs: list · grant · revoke where supported. |
|
|
42
42
|
| 🔐 **R0–R3 governance** | every operation is risk-classified by the fail-closed `mqclass` engine; protected contexts and internal/system topics escalate one tier; AI callers can never self-authorize. |
|
|
43
43
|
| 🎯 **Real blast-radius preview** | `reset-offset --dry-run` and `purge --dry-run` compute the actual per-partition message delta from the live broker — no guessing. The preview is read-only and never mutates. |
|
|
44
|
-
| 👀 **Non-destructive peek** | inspect messages as fingerprints without consuming them or moving any cursor (Pulsar Reader, RabbitMQ get+requeue). Where a broker can't guarantee this,
|
|
44
|
+
| 👀 **Non-destructive peek/tail** | inspect or stream messages as fingerprints without consuming them or moving any cursor (Kafka direct partition reads, Pulsar Reader, RabbitMQ get+requeue for peek only). Where a broker can't guarantee this, the operation fails closed rather than silently consuming. |
|
|
45
45
|
| 🧭 **Honest capabilities** | brokers differ — mqgov reports what each one actually supports (`capabilities -o json`) and **fails closed with `NOT_IMPLEMENTED`** for the rest, never faking it. |
|
|
46
46
|
| 📜 **Tamper-evident audit** | hash-chained log of every action (sha256 fingerprints + counts, **no message bodies/keys/headers**); `audit verify` detects tampering. |
|
|
47
47
|
| 🩺 **Ops & DX** | backend-bound `ctx` contexts with credstore-backed secrets, `doctor` diagnostics, shell `completion`, OpenTelemetry traces/metrics, JSON output everywhere. |
|
|
@@ -54,11 +54,13 @@ It's built on the shared [`opskit-core`](https://github.com/JiangHe12/opskit-cor
|
|
|
54
54
|
| topic list / describe / create / delete | ✅ | ✅ | ✅ | ✅ |
|
|
55
55
|
| produce | ✅ | ✅ | ✅ | ✅ |
|
|
56
56
|
| **non-destructive peek** | ✅ | ✅ (Reader) | ✅ (get+requeue) | ❌ `NOT_IMPLEMENTED`¹ |
|
|
57
|
+
| **non-destructive tail** | ✅ | ✅ (Reader) | ❌ `NOT_IMPLEMENTED`² | ❌ `NOT_IMPLEMENTED`¹ |
|
|
57
58
|
| **offset lag / reset** | ✅ | ✅ (cursor) | ❌ (no offsets) | ❌ |
|
|
58
59
|
| alter partitions | ✅ | ✅ | ❌ | ❌ |
|
|
59
60
|
| purge | ✅ | ✅ | ✅ | ❌ |
|
|
61
|
+
| **ACL list / grant / revoke** | ✅ | ✅ namespace/topic permissions | ✅ user-vhost permissions | ❌ `NOT_IMPLEMENTED` |
|
|
60
62
|
|
|
61
|
-
¹ RocketMQ's Go v2 `PullConsumer` enters the consumer-group lifecycle and commits offsets, so it cannot guarantee
|
|
63
|
+
¹ RocketMQ's Go v2 `PullConsumer` enters the consumer-group lifecycle and commits offsets, so it cannot guarantee non-destructive peek/tail — mqgov fails closed instead of silently advancing offsets. ² RabbitMQ has no forward non-destructive tail because reads are consume/requeue oriented. Unsupported operations always return `NOT_IMPLEMENTED` (exit 12), never a fake success.
|
|
62
64
|
|
|
63
65
|
---
|
|
64
66
|
|
|
@@ -100,6 +102,7 @@ mqgov ctx test # ping the broker through the context
|
|
|
100
102
|
mqgov topic list -o json
|
|
101
103
|
mqgov topic describe orders -o json
|
|
102
104
|
mqgov message peek orders --count 5 -o json # fingerprints only, nothing consumed
|
|
105
|
+
mqgov message tail orders --max-messages 10 -o json
|
|
103
106
|
|
|
104
107
|
# 3. Preview the blast radius of a dangerous op — nothing is changed yet
|
|
105
108
|
mqgov group reset-offset billing orders --to latest --dry-run -o json # shows per-partition delta
|
|
@@ -121,19 +124,19 @@ Every command is sorted into one of four **risk tiers** by the fail-closed `mqcl
|
|
|
121
124
|
|
|
122
125
|
| Tier | What it covers | What you must provide |
|
|
123
126
|
|:---:|---|---|
|
|
124
|
-
| **R0** | Reads & previews (`topic list/describe`, `group list/lag`, `message peek`, `*-dry-run`, `audit query/verify`, `doctor`) | Nothing — but it's still audited |
|
|
127
|
+
| **R0** | Reads & previews (`topic list/describe`, `group list/lag`, `message peek`, `message tail`, `acl list`, `*-dry-run`, `audit query/verify`, `doctor`) | Nothing — but it's still audited |
|
|
125
128
|
| **R1** | Ordinary writes (`message produce`, `topic create`) | `--yes` (or an interactive confirmation) |
|
|
126
|
-
| **R2** | Elevated mutations (`topic alter`, `group create/delete`, produce to a **protected** topic) | `--yes` **and** a non-empty `--ticket` |
|
|
127
|
-
| **R3** | Destructive / irreversible (`group reset-offset`, `topic purge`, `topic delete`, produce to an **internal/system** topic) | The above **plus** the exact `--allow-*` flag |
|
|
129
|
+
| **R2** | Elevated mutations (`topic alter`, `group create/delete`, `acl grant`, produce to a **protected** topic) | `--yes` **and** a non-empty `--ticket` |
|
|
130
|
+
| **R3** | Destructive / irreversible (`group reset-offset`, `topic purge`, `topic delete`, broad `acl grant`, `acl revoke`, produce to an **internal/system** topic) | The above **plus** the exact `--allow-*` flag |
|
|
128
131
|
|
|
129
|
-
The R3 allow flags: `--allow-offset-reset`, `--allow-topic-purge`, `--allow-topic-delete`, `--allow-internal-produce`.
|
|
132
|
+
The R3 allow flags: `--allow-offset-reset`, `--allow-topic-purge`, `--allow-topic-delete`, `--allow-destructive-acl`, `--allow-internal-produce`.
|
|
130
133
|
|
|
131
134
|
**Protected contexts, protected topics, and internal/system topics raise the tier by one.** For example, producing to `__consumer_offsets` is treated as a destructive R3 operation and needs `--allow-internal-produce`.
|
|
132
135
|
|
|
133
136
|
Three rules keep this safe — especially for automation:
|
|
134
137
|
|
|
135
138
|
1. **Blast radius comes from the tool, not a guess.** Use `--dry-run` / `--plan` to see the exact per-partition impact. Never estimate it by reasoning.
|
|
136
|
-
2. **`mqclass` is fail-closed and structure-aware.** All offset changes, purge,
|
|
139
|
+
2. **`mqclass` is fail-closed and structure-aware.** All offset changes, purge, topic delete, ACL revoke, and broad ACL grants are pinned R3; wildcard/glob targets escalate; an unknown operation fails closed to the highest tier — it never falls to R0.
|
|
137
140
|
3. **🤖 AI agents must never invent `--ticket`, `--allow-*`, or a high-risk `--yes`.** Those are *human* authorization inputs. An agent should surface "this needs approval X" to its operator and stop.
|
|
138
141
|
|
|
139
142
|
---
|
|
@@ -179,14 +182,49 @@ Offsets are a Kafka and Pulsar concept. On RabbitMQ and RocketMQ, `group lag` /
|
|
|
179
182
|
</details>
|
|
180
183
|
|
|
181
184
|
<details>
|
|
182
|
-
<summary><b>message</b> — peek & produce</summary>
|
|
185
|
+
<summary><b>message</b> — peek, tail & produce</summary>
|
|
183
186
|
|
|
184
187
|
```bash
|
|
185
188
|
mqgov message peek <topic> [--partition N] [--offset N] [--count N] -o json # R0, non-destructive, fingerprints only
|
|
189
|
+
mqgov message tail <topic> [--partition N] [--from earliest|latest|offset:N] [--follow] [--max-messages N] [--timeout 30s] -o json
|
|
186
190
|
mqgov message produce <topic> [--key <k>] [--body <text>] --yes # R1 (R3 + --allow-internal-produce for internal topics)
|
|
187
191
|
```
|
|
188
192
|
|
|
189
|
-
`peek` never
|
|
193
|
+
`peek` and `tail` never consume a message or move a cursor, and return only sha256 fingerprints (`keySha256`, `bodySha256`, size, optional timestamp) — never the body. `tail` is bounded by `--max-messages` and `--timeout`; `--follow` streams new messages only until those bounds or cancellation. Tail is supported by Kafka and Pulsar. On RabbitMQ and RocketMQ, `tail` fails closed (`NOT_IMPLEMENTED`); on RocketMQ, `peek` also fails closed.
|
|
194
|
+
</details>
|
|
195
|
+
|
|
196
|
+
<details>
|
|
197
|
+
<summary><b>acl</b> — broker access control</summary>
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
mqgov acl list [--principal <P>] [--resource-type <T>] [--resource-name <N>] -o json
|
|
201
|
+
|
|
202
|
+
# Kafka broker ACLs
|
|
203
|
+
mqgov acl grant --principal User:svc --resource-type topic --resource-name orders \
|
|
204
|
+
--pattern literal --operation read --permission allow --yes --ticket <t>
|
|
205
|
+
|
|
206
|
+
mqgov acl revoke --principal User:svc --resource-type topic --resource-name orders \
|
|
207
|
+
--pattern literal --operation read --permission allow \
|
|
208
|
+
--yes --ticket <t> --allow-destructive-acl
|
|
209
|
+
|
|
210
|
+
# RabbitMQ native user-vhost permissions
|
|
211
|
+
mqgov acl grant --principal svc --vhost / --resource-type vhost --resource-name '^orders$' \
|
|
212
|
+
--pattern regex --operation read --permission allow --yes --ticket <t>
|
|
213
|
+
|
|
214
|
+
mqgov acl revoke --principal svc --vhost / --resource-type vhost --resource-name '^orders$' \
|
|
215
|
+
--pattern regex --operation read --permission allow \
|
|
216
|
+
--yes --ticket <t> --allow-destructive-acl
|
|
217
|
+
|
|
218
|
+
# Pulsar native namespace/topic permissions
|
|
219
|
+
mqgov acl grant --principal app-role --resource-type namespace --resource-name public/default \
|
|
220
|
+
--pattern literal --operation produce --permission allow --yes --ticket <t>
|
|
221
|
+
|
|
222
|
+
mqgov acl revoke --principal app-role --resource-type topic --resource-name orders \
|
|
223
|
+
--pattern literal --operation consume --permission allow \
|
|
224
|
+
--yes --ticket <t> --allow-destructive-acl
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`acl list` is R0 and audited. Normal `acl grant` is R2. Broad grants (Kafka prefixed pattern, wildcard principal, wildcard resource, cluster resource, `all`, `alter`, cluster-action style operations, broad RabbitMQ regexes such as `.*`, `.+`, `.`, and `orders.*`, or Pulsar `functions`/`sources`/`sinks`/`packages`) and every `acl revoke` are R3 and require `--allow-destructive-acl`. Kafka implements broker ACLs with `literal`/`prefixed` patterns. RabbitMQ maps ACLs to native per-user, per-vhost permission regexes (`configure`, `write`, `read`) and only supports `--permission allow` with `--pattern regex`. Pulsar maps ACLs to native role permissions on namespaces or topics with actions `produce`, `consume`, `functions`, `sources`, `sinks`, and `packages`; it is allow-only and uses `--pattern literal`. RocketMQ fails closed with `NOT_IMPLEMENTED`.
|
|
190
228
|
</details>
|
|
191
229
|
|
|
192
230
|
<details>
|
|
@@ -220,7 +258,7 @@ mqgov version
|
|
|
220
258
|
|
|
221
259
|
mqgov-cli is designed to be driven by autonomous agents safely:
|
|
222
260
|
|
|
223
|
-
- Run `mqgov capabilities -o json` first to discover what the bound backend supports — brokers differ, don't assume (e.g. RabbitMQ/RocketMQ have no offsets; RocketMQ has no peek).
|
|
261
|
+
- Run `mqgov capabilities -o json` first to discover what the bound backend supports — brokers differ, don't assume (e.g. Kafka, RabbitMQ, and Pulsar support `acl` with different native models; RabbitMQ/RocketMQ have no offsets; RabbitMQ/RocketMQ have no tail; RocketMQ has no peek).
|
|
224
262
|
- Use `-o json` everywhere; every command returns a stable, versioned envelope.
|
|
225
263
|
- Get blast radius from `--dry-run` / `--plan`, never from your own reasoning.
|
|
226
264
|
- **Never self-fill `--ticket`, `--allow-*`, or a high-risk `--yes`.** Surface the required human approval and stop.
|