zhaohai666 opened a new issue, #10825:
URL: https://github.com/apache/rocketmq/issues/10825

   ### Before Creating the Enhancement Request
   
   - [x] I have confirmed that this should be classified as an enhancement 
rather than a bug/feature.
   
   
   ### Summary
   
   # [RIP-2] Proxy Admin Standardized Management Interface
   
   ## Background
   
   RocketMQ 5.0 moved client access behind the stateless Proxy, but operations 
still
   observe clients through broker-side structures (`ConsumerManager` on the 
broker,
   Remoting-era admin commands). **gRPC clients attached to a Proxy are 
invisible to
   those tools**: the control plane cannot answer *"which SDK clients are 
online, what
   do they subscribe to, are they healthy?"* without indirect metrics 
heuristics.
   
   RIP-1 (Control Plane 5.0 dashboard, requirement `CLIENT-01`) explicitly 
depends on
   a standard server-side interface to read complete gRPC client data. **There 
is
   currently no such interface on the Proxy.**
   
   ## Problem Statement
   
   1. **No dedicated admin surface on the Proxy.** The data-plane 
`MessagingService`
      gRPC service is not designed for control-plane queries (client 
enumeration,
      runtime config, connection control, diagnostics). Operators must SSH into 
brokers
      and run Remoting-era `mqadmin` commands, which cannot see gRPC clients.
   2. **No least-privilege authorization for admin operations.** Existing admin
      operations share the broker ACL scope; there is no way to grant a 
read-only
      observer vs. a break-glass admin on the Proxy itself.
   3. **No cluster-wide client view.** Each Proxy only knows its own clients; 
there is
      no documented mechanism to aggregate client state across all proxies in a
      cluster.
   4. **No self-service observability.** Admin RPCs are not instrumented with 
their
      own RT / error-rate metrics, so admin-interface health is invisible to
      monitoring.
   5. **No stable, protocol-pure contract.** Broker-internal wire types leak 
into
      admin tooling, coupling every consumer to internal remoting classes.
   
   ## Proposal
   
   Implement **RIP-2: Proxy Admin Standardized Management Interface** — a 
dedicated,
   independent gRPC Admin service on the Proxy, isolated from the data plane, 
with a
   stable backward-compatible proto contract and fine-grained ACL 2.0 
authorization.
   
   ### Goals
   
   1. A dedicated gRPC Admin service on the Proxy, served on its own port
      (`adminGrpcPort`, default **8083**), isolated from the data-plane
      `MessagingService`. A global kill switch `proxyAdminEnabled` disables the 
whole
      surface.
   2. A stable, backward-compatible proto contract (`ProxyAdminService` +
      `AdminService` in `apache/rocketmq/v2/admin.proto`, rocketmq-apis 
**2.3.0**).
   3. First-class authorization under dedicated `proxy.admin.*` ACL 2.0 
resources
      with read-only (`Get`/`List`) / high-privilege (`Update`/`Delete`/`Pub`)
      action separation.
   4. The service exposes its own call RT and error-rate metrics 
(OpenTelemetry).
   5. Multi-Proxy semantics: a documented, predictable story for cluster-wide 
views.
   
   ### Non-Goals (this iteration)
   
   - Broker-side quota storage.
   - Remoting client kick (Remoting clients remain observable via existing 
broker
     channels; the proto carries a `protocol` field for future coverage).
   - A central client registry (proxies are stateless; peer-list configuration 
is
     explicit and auditable).
   
   ## Design Decisions
   
   | ID | Decision | Summary |
   |----|----------|---------|
   | D1 | Service placement | Dedicated `ProxyAdminService` on its own gRPC 
server/port (8083), separate from data plane and broker-facing `Admin`. 
Intentionally does NOT expose channelz or proto reflection. |
   | D2 | Authorization | Every RPC maps to one `proxy.admin.*` resource + one 
action. Resources modeled as cluster-typed literals 
(`cluster:proxy.admin.<module>`). Fail-closed `proxyAdminRequireAuth` mode. 
Audit logging per served RPC. |
   | D3 | Multi-proxy semantics | Each Proxy returns its LOCAL view tagged with 
`proxy_endpoint` + monotonic `epoch`. `PROXY_SCOPE_ALL_PROXIES` fans out to 
configured peers in parallel and deduplicates by `client_id`. Peer failures 
degrade gracefully. |
   | D4 | Pagination | Cursor-based `next_token` for client listings (stable 
under connection churn). Offset pagination (`page_num`/`page_size`, max 100) 
for bounded diagnostic snapshots. |
   | D5 | Protocol coverage | `ClientInstance.protocol` distinguishes GRPC vs 
REMOTING. This iteration tracks gRPC clients; the field is forward-compatible 
for Remoting coverage. |
   
   ### D2 — Authorization Matrix
   
   | Resource | RPCs | Action |
   |----------|------|--------|
   | `proxy.admin.client` | ListClients / ListClientsByGroup / 
ListClientsByTopic | List |
   | `proxy.admin.client` | DescribeClient / DescribePopReceiptHandles / 
DescribeBatchConsumeDiagnostics / ListSubscription / DescribeSubscription / 
ListConsumerConnection / DescribeGroupAccumulation / GetConsumerRunningInfo / 
QueryTimeSpan | Get |
   | `proxy.admin.config` | DescribeProxyConfig | Get |
   | `proxy.admin.config` | UpdateProxyConfig / ChangeLogLevel | Update |
   | `proxy.admin.connection` | KickClient / DisconnectChannel / 
PrintThreadStackTrace / VerifyMessage | Update (high privilege) |
   | `proxy.admin.quota` | DescribeQuota | Get |
   | `proxy.admin.quota` | UpdateQuota | Update (high privilege) |
   | `proxy.admin.route` | DescribeRouteTopology / GetTopicRoute | Get |
   | `proxy.admin.route` | SubscribeRouteEvents | List |
   | `proxy.admin.ops` | GetProxyRuntimeStats / DescribeTopicStatus / 
QueryMessage | Get |
   | `proxy.admin.ops` | ResetGroupOffset | Update (high privilege) |
   | `proxy.admin.ops` | DeleteSubscription | Delete (high privilege) |
   | `proxy.admin.ops` | AdminSendMessage | Pub (high privilege) |
   
   ### RPC Surface (14+ RPCs across two services)
   
   **`ProxyAdminService` (M1–M4):**
   - M1: `ListClients`, `DescribeClient`, `ListClientsByGroup`, 
`ListClientsByTopic`
   - M2: `DescribeProxyConfig` / `UpdateProxyConfig`, `KickClient` / 
`DisconnectChannel`, `DescribeQuota` / `UpdateQuota`
   - M3/M4: `DescribePopReceiptHandles`, `DescribeBatchConsumeDiagnostics`
   - Route observation: `SubscribeRouteEvents` (server-streaming), 
`DescribeRouteTopology`
   
   **`AdminService` (broker-facing, served through the Proxy's managed 
client):**
   - `GetProxyRuntimeStats`, `DescribeTopicStatus`, `QueryMessage`, 
`QueryTimeSpan`,
     `GetConsumerRunningInfo`, `ListConsumerConnection`, `ListSubscription`,
     `DescribeSubscription`, `DescribeGroupAccumulation`, `ResetGroupOffset`,
     `DeleteSubscription`, `AdminSendMessage`, `PrintThreadStackTrace`,
     `VerifyMessage`, `ChangeLogLevel`, `GetTopicRoute`
   
   ### Observability
   
   - `rocketmq_proxy_admin_rpc_total{rpc_method, status, error_type?}` — error 
rate
   - `rocketmq_proxy_admin_rpc_latency{rpc_method, status}` (ms histogram) — RT 
P50/P99
   
   ### Configuration Reference
   
   | Key | Default | Meaning |
   |-----|---------|---------|
   | `proxyAdminEnabled` | true | Kill switch; false = admin server not started 
|
   | `adminGrpcPort` | 8083 | Dedicated admin gRPC port (≤0 disables) |
   | `proxyAdminRequireAuth` | false | Fail-closed credential enforcement |
   | `proxyAdminPeerEndpoints` | [] | Peer admin endpoints for ALL_PROXIES 
fan-out |
   | `proxyAdminPeerTimeoutMillis` | 3000 | Per-peer fan-out timeout |
   | `proxyAdminHeartbeatHistorySize` | 16 | Heartbeat records kept per client |
   
   ## Acceptance Criteria
   
   | Criterion | Status |
   |-----------|--------|
   | RIP document + stable backward-compatible proto contract | 
`docs/rip-2-proxy-admin.md` + rocketmq-apis `admin.proto` |
   | Client query RPCs merged; pagination scales with connection churn | D4 
stable cursor; page cost O(pageSize) after sort |
   | Independent ACL control, read-only/high-risk separation, least-privilege 
doc | D2 resources/actions + `docs/rip-2-least-privilege.md` |
   | RPC RT & error-rate metrics | ProxyAdminMetricsManager instruments |
   | E2E with RIP-1 dashboard | Contract frozen for dashboard CLIENT-01 
integration (cross-repo) |
   
   ## References
   
   - RIP-1 Control Plane 5.0 dashboard (requirement `CLIENT-01`)
   - `docs/rip-2-proxy-admin.md` — full RIP proposal
   - `docs/rip-2-least-privilege.md` — least-privilege configuration guide
   - rocketmq-apis repository, branch `feature/rip-2-proxy-admin-grpc` (proto 
contract)
   
   
   ### Motivation
   
   # [RIP-2] Proxy Admin Standardized Management Interface
   
   ## Background
   
   RocketMQ 5.0 moved client access behind the stateless Proxy, but operations 
still
   observe clients through broker-side structures (`ConsumerManager` on the 
broker,
   Remoting-era admin commands). **gRPC clients attached to a Proxy are 
invisible to
   those tools**: the control plane cannot answer *"which SDK clients are 
online, what
   do they subscribe to, are they healthy?"* without indirect metrics 
heuristics.
   
   RIP-1 (Control Plane 5.0 dashboard, requirement `CLIENT-01`) explicitly 
depends on
   a standard server-side interface to read complete gRPC client data. **There 
is
   currently no such interface on the Proxy.**
   
   ## Problem Statement
   
   1. **No dedicated admin surface on the Proxy.** The data-plane 
`MessagingService`
      gRPC service is not designed for control-plane queries (client 
enumeration,
      runtime config, connection control, diagnostics). Operators must SSH into 
brokers
      and run Remoting-era `mqadmin` commands, which cannot see gRPC clients.
   2. **No least-privilege authorization for admin operations.** Existing admin
      operations share the broker ACL scope; there is no way to grant a 
read-only
      observer vs. a break-glass admin on the Proxy itself.
   3. **No cluster-wide client view.** Each Proxy only knows its own clients; 
there is
      no documented mechanism to aggregate client state across all proxies in a
      cluster.
   4. **No self-service observability.** Admin RPCs are not instrumented with 
their
      own RT / error-rate metrics, so admin-interface health is invisible to
      monitoring.
   5. **No stable, protocol-pure contract.** Broker-internal wire types leak 
into
      admin tooling, coupling every consumer to internal remoting classes.
   
   ## Proposal
   
   Implement **RIP-2: Proxy Admin Standardized Management Interface** — a 
dedicated,
   independent gRPC Admin service on the Proxy, isolated from the data plane, 
with a
   stable backward-compatible proto contract and fine-grained ACL 2.0 
authorization.
   
   ### Goals
   
   1. A dedicated gRPC Admin service on the Proxy, served on its own port
      (`adminGrpcPort`, default **8083**), isolated from the data-plane
      `MessagingService`. A global kill switch `proxyAdminEnabled` disables the 
whole
      surface.
   2. A stable, backward-compatible proto contract (`ProxyAdminService` +
      `AdminService` in `apache/rocketmq/v2/admin.proto`, rocketmq-apis 
**2.3.0**).
   3. First-class authorization under dedicated `proxy.admin.*` ACL 2.0 
resources
      with read-only (`Get`/`List`) / high-privilege (`Update`/`Delete`/`Pub`)
      action separation.
   4. The service exposes its own call RT and error-rate metrics 
(OpenTelemetry).
   5. Multi-Proxy semantics: a documented, predictable story for cluster-wide 
views.
   
   ### Non-Goals (this iteration)
   
   - Broker-side quota storage.
   - Remoting client kick (Remoting clients remain observable via existing 
broker
     channels; the proto carries a `protocol` field for future coverage).
   - A central client registry (proxies are stateless; peer-list configuration 
is
     explicit and auditable).
   
   ## Design Decisions
   
   | ID | Decision | Summary |
   |----|----------|---------|
   | D1 | Service placement | Dedicated `ProxyAdminService` on its own gRPC 
server/port (8083), separate from data plane and broker-facing `Admin`. 
Intentionally does NOT expose channelz or proto reflection. |
   | D2 | Authorization | Every RPC maps to one `proxy.admin.*` resource + one 
action. Resources modeled as cluster-typed literals 
(`cluster:proxy.admin.<module>`). Fail-closed `proxyAdminRequireAuth` mode. 
Audit logging per served RPC. |
   | D3 | Multi-proxy semantics | Each Proxy returns its LOCAL view tagged with 
`proxy_endpoint` + monotonic `epoch`. `PROXY_SCOPE_ALL_PROXIES` fans out to 
configured peers in parallel and deduplicates by `client_id`. Peer failures 
degrade gracefully. |
   | D4 | Pagination | Cursor-based `next_token` for client listings (stable 
under connection churn). Offset pagination (`page_num`/`page_size`, max 100) 
for bounded diagnostic snapshots. |
   | D5 | Protocol coverage | `ClientInstance.protocol` distinguishes GRPC vs 
REMOTING. This iteration tracks gRPC clients; the field is forward-compatible 
for Remoting coverage. |
   
   ### D2 — Authorization Matrix
   
   | Resource | RPCs | Action |
   |----------|------|--------|
   | `proxy.admin.client` | ListClients / ListClientsByGroup / 
ListClientsByTopic | List |
   | `proxy.admin.client` | DescribeClient / DescribePopReceiptHandles / 
DescribeBatchConsumeDiagnostics / ListSubscription / DescribeSubscription / 
ListConsumerConnection / DescribeGroupAccumulation / GetConsumerRunningInfo / 
QueryTimeSpan | Get |
   | `proxy.admin.config` | DescribeProxyConfig | Get |
   | `proxy.admin.config` | UpdateProxyConfig / ChangeLogLevel | Update |
   | `proxy.admin.connection` | KickClient / DisconnectChannel / 
PrintThreadStackTrace / VerifyMessage | Update (high privilege) |
   | `proxy.admin.quota` | DescribeQuota | Get |
   | `proxy.admin.quota` | UpdateQuota | Update (high privilege) |
   | `proxy.admin.route` | DescribeRouteTopology / GetTopicRoute | Get |
   | `proxy.admin.route` | SubscribeRouteEvents | List |
   | `proxy.admin.ops` | GetProxyRuntimeStats / DescribeTopicStatus / 
QueryMessage | Get |
   | `proxy.admin.ops` | ResetGroupOffset | Update (high privilege) |
   | `proxy.admin.ops` | DeleteSubscription | Delete (high privilege) |
   | `proxy.admin.ops` | AdminSendMessage | Pub (high privilege) |
   
   ### RPC Surface (14+ RPCs across two services)
   
   **`ProxyAdminService` (M1–M4):**
   - M1: `ListClients`, `DescribeClient`, `ListClientsByGroup`, 
`ListClientsByTopic`
   - M2: `DescribeProxyConfig` / `UpdateProxyConfig`, `KickClient` / 
`DisconnectChannel`, `DescribeQuota` / `UpdateQuota`
   - M3/M4: `DescribePopReceiptHandles`, `DescribeBatchConsumeDiagnostics`
   - Route observation: `SubscribeRouteEvents` (server-streaming), 
`DescribeRouteTopology`
   
   **`AdminService` (broker-facing, served through the Proxy's managed 
client):**
   - `GetProxyRuntimeStats`, `DescribeTopicStatus`, `QueryMessage`, 
`QueryTimeSpan`,
     `GetConsumerRunningInfo`, `ListConsumerConnection`, `ListSubscription`,
     `DescribeSubscription`, `DescribeGroupAccumulation`, `ResetGroupOffset`,
     `DeleteSubscription`, `AdminSendMessage`, `PrintThreadStackTrace`,
     `VerifyMessage`, `ChangeLogLevel`, `GetTopicRoute`
   
   ### Observability
   
   - `rocketmq_proxy_admin_rpc_total{rpc_method, status, error_type?}` — error 
rate
   - `rocketmq_proxy_admin_rpc_latency{rpc_method, status}` (ms histogram) — RT 
P50/P99
   
   ### Configuration Reference
   
   | Key | Default | Meaning |
   |-----|---------|---------|
   | `proxyAdminEnabled` | true | Kill switch; false = admin server not started 
|
   | `adminGrpcPort` | 8083 | Dedicated admin gRPC port (≤0 disables) |
   | `proxyAdminRequireAuth` | false | Fail-closed credential enforcement |
   | `proxyAdminPeerEndpoints` | [] | Peer admin endpoints for ALL_PROXIES 
fan-out |
   | `proxyAdminPeerTimeoutMillis` | 3000 | Per-peer fan-out timeout |
   | `proxyAdminHeartbeatHistorySize` | 16 | Heartbeat records kept per client |
   
   ## Acceptance Criteria
   
   | Criterion | Status |
   |-----------|--------|
   | RIP document + stable backward-compatible proto contract | 
`docs/rip-2-proxy-admin.md` + rocketmq-apis `admin.proto` |
   | Client query RPCs merged; pagination scales with connection churn | D4 
stable cursor; page cost O(pageSize) after sort |
   | Independent ACL control, read-only/high-risk separation, least-privilege 
doc | D2 resources/actions + `docs/rip-2-least-privilege.md` |
   | RPC RT & error-rate metrics | ProxyAdminMetricsManager instruments |
   | E2E with RIP-1 dashboard | Contract frozen for dashboard CLIENT-01 
integration (cross-repo) |
   
   ## References
   
   - RIP-1 Control Plane 5.0 dashboard (requirement `CLIENT-01`)
   - `docs/rip-2-proxy-admin.md` — full RIP proposal
   - `docs/rip-2-least-privilege.md` — least-privilege configuration guide
   - rocketmq-apis repository, branch `feature/rip-2-proxy-admin-grpc` (proto 
contract)
   
   
   ### Describe the Solution You'd Like
   
   # [RIP-2] Proxy Admin Standardized Management Interface
   
   ## Background
   
   RocketMQ 5.0 moved client access behind the stateless Proxy, but operations 
still
   observe clients through broker-side structures (`ConsumerManager` on the 
broker,
   Remoting-era admin commands). **gRPC clients attached to a Proxy are 
invisible to
   those tools**: the control plane cannot answer *"which SDK clients are 
online, what
   do they subscribe to, are they healthy?"* without indirect metrics 
heuristics.
   
   RIP-1 (Control Plane 5.0 dashboard, requirement `CLIENT-01`) explicitly 
depends on
   a standard server-side interface to read complete gRPC client data. **There 
is
   currently no such interface on the Proxy.**
   
   ## Problem Statement
   
   1. **No dedicated admin surface on the Proxy.** The data-plane 
`MessagingService`
      gRPC service is not designed for control-plane queries (client 
enumeration,
      runtime config, connection control, diagnostics). Operators must SSH into 
brokers
      and run Remoting-era `mqadmin` commands, which cannot see gRPC clients.
   2. **No least-privilege authorization for admin operations.** Existing admin
      operations share the broker ACL scope; there is no way to grant a 
read-only
      observer vs. a break-glass admin on the Proxy itself.
   3. **No cluster-wide client view.** Each Proxy only knows its own clients; 
there is
      no documented mechanism to aggregate client state across all proxies in a
      cluster.
   4. **No self-service observability.** Admin RPCs are not instrumented with 
their
      own RT / error-rate metrics, so admin-interface health is invisible to
      monitoring.
   5. **No stable, protocol-pure contract.** Broker-internal wire types leak 
into
      admin tooling, coupling every consumer to internal remoting classes.
   
   ## Proposal
   
   Implement **RIP-2: Proxy Admin Standardized Management Interface** — a 
dedicated,
   independent gRPC Admin service on the Proxy, isolated from the data plane, 
with a
   stable backward-compatible proto contract and fine-grained ACL 2.0 
authorization.
   
   ### Goals
   
   1. A dedicated gRPC Admin service on the Proxy, served on its own port
      (`adminGrpcPort`, default **8083**), isolated from the data-plane
      `MessagingService`. A global kill switch `proxyAdminEnabled` disables the 
whole
      surface.
   2. A stable, backward-compatible proto contract (`ProxyAdminService` +
      `AdminService` in `apache/rocketmq/v2/admin.proto`, rocketmq-apis 
**2.3.0**).
   3. First-class authorization under dedicated `proxy.admin.*` ACL 2.0 
resources
      with read-only (`Get`/`List`) / high-privilege (`Update`/`Delete`/`Pub`)
      action separation.
   4. The service exposes its own call RT and error-rate metrics 
(OpenTelemetry).
   5. Multi-Proxy semantics: a documented, predictable story for cluster-wide 
views.
   
   ### Non-Goals (this iteration)
   
   - Broker-side quota storage.
   - Remoting client kick (Remoting clients remain observable via existing 
broker
     channels; the proto carries a `protocol` field for future coverage).
   - A central client registry (proxies are stateless; peer-list configuration 
is
     explicit and auditable).
   
   ## Design Decisions
   
   | ID | Decision | Summary |
   |----|----------|---------|
   | D1 | Service placement | Dedicated `ProxyAdminService` on its own gRPC 
server/port (8083), separate from data plane and broker-facing `Admin`. 
Intentionally does NOT expose channelz or proto reflection. |
   | D2 | Authorization | Every RPC maps to one `proxy.admin.*` resource + one 
action. Resources modeled as cluster-typed literals 
(`cluster:proxy.admin.<module>`). Fail-closed `proxyAdminRequireAuth` mode. 
Audit logging per served RPC. |
   | D3 | Multi-proxy semantics | Each Proxy returns its LOCAL view tagged with 
`proxy_endpoint` + monotonic `epoch`. `PROXY_SCOPE_ALL_PROXIES` fans out to 
configured peers in parallel and deduplicates by `client_id`. Peer failures 
degrade gracefully. |
   | D4 | Pagination | Cursor-based `next_token` for client listings (stable 
under connection churn). Offset pagination (`page_num`/`page_size`, max 100) 
for bounded diagnostic snapshots. |
   | D5 | Protocol coverage | `ClientInstance.protocol` distinguishes GRPC vs 
REMOTING. This iteration tracks gRPC clients; the field is forward-compatible 
for Remoting coverage. |
   
   ### D2 — Authorization Matrix
   
   | Resource | RPCs | Action |
   |----------|------|--------|
   | `proxy.admin.client` | ListClients / ListClientsByGroup / 
ListClientsByTopic | List |
   | `proxy.admin.client` | DescribeClient / DescribePopReceiptHandles / 
DescribeBatchConsumeDiagnostics / ListSubscription / DescribeSubscription / 
ListConsumerConnection / DescribeGroupAccumulation / GetConsumerRunningInfo / 
QueryTimeSpan | Get |
   | `proxy.admin.config` | DescribeProxyConfig | Get |
   | `proxy.admin.config` | UpdateProxyConfig / ChangeLogLevel | Update |
   | `proxy.admin.connection` | KickClient / DisconnectChannel / 
PrintThreadStackTrace / VerifyMessage | Update (high privilege) |
   | `proxy.admin.quota` | DescribeQuota | Get |
   | `proxy.admin.quota` | UpdateQuota | Update (high privilege) |
   | `proxy.admin.route` | DescribeRouteTopology / GetTopicRoute | Get |
   | `proxy.admin.route` | SubscribeRouteEvents | List |
   | `proxy.admin.ops` | GetProxyRuntimeStats / DescribeTopicStatus / 
QueryMessage | Get |
   | `proxy.admin.ops` | ResetGroupOffset | Update (high privilege) |
   | `proxy.admin.ops` | DeleteSubscription | Delete (high privilege) |
   | `proxy.admin.ops` | AdminSendMessage | Pub (high privilege) |
   
   ### RPC Surface (14+ RPCs across two services)
   
   **`ProxyAdminService` (M1–M4):**
   - M1: `ListClients`, `DescribeClient`, `ListClientsByGroup`, 
`ListClientsByTopic`
   - M2: `DescribeProxyConfig` / `UpdateProxyConfig`, `KickClient` / 
`DisconnectChannel`, `DescribeQuota` / `UpdateQuota`
   - M3/M4: `DescribePopReceiptHandles`, `DescribeBatchConsumeDiagnostics`
   - Route observation: `SubscribeRouteEvents` (server-streaming), 
`DescribeRouteTopology`
   
   **`AdminService` (broker-facing, served through the Proxy's managed 
client):**
   - `GetProxyRuntimeStats`, `DescribeTopicStatus`, `QueryMessage`, 
`QueryTimeSpan`,
     `GetConsumerRunningInfo`, `ListConsumerConnection`, `ListSubscription`,
     `DescribeSubscription`, `DescribeGroupAccumulation`, `ResetGroupOffset`,
     `DeleteSubscription`, `AdminSendMessage`, `PrintThreadStackTrace`,
     `VerifyMessage`, `ChangeLogLevel`, `GetTopicRoute`
   
   ### Observability
   
   - `rocketmq_proxy_admin_rpc_total{rpc_method, status, error_type?}` — error 
rate
   - `rocketmq_proxy_admin_rpc_latency{rpc_method, status}` (ms histogram) — RT 
P50/P99
   
   ### Configuration Reference
   
   | Key | Default | Meaning |
   |-----|---------|---------|
   | `proxyAdminEnabled` | true | Kill switch; false = admin server not started 
|
   | `adminGrpcPort` | 8083 | Dedicated admin gRPC port (≤0 disables) |
   | `proxyAdminRequireAuth` | false | Fail-closed credential enforcement |
   | `proxyAdminPeerEndpoints` | [] | Peer admin endpoints for ALL_PROXIES 
fan-out |
   | `proxyAdminPeerTimeoutMillis` | 3000 | Per-peer fan-out timeout |
   | `proxyAdminHeartbeatHistorySize` | 16 | Heartbeat records kept per client |
   
   ## Acceptance Criteria
   
   | Criterion | Status |
   |-----------|--------|
   | RIP document + stable backward-compatible proto contract | 
`docs/rip-2-proxy-admin.md` + rocketmq-apis `admin.proto` |
   | Client query RPCs merged; pagination scales with connection churn | D4 
stable cursor; page cost O(pageSize) after sort |
   | Independent ACL control, read-only/high-risk separation, least-privilege 
doc | D2 resources/actions + `docs/rip-2-least-privilege.md` |
   | RPC RT & error-rate metrics | ProxyAdminMetricsManager instruments |
   | E2E with RIP-1 dashboard | Contract frozen for dashboard CLIENT-01 
integration (cross-repo) |
   
   ## References
   
   - RIP-1 Control Plane 5.0 dashboard (requirement `CLIENT-01`)
   - `docs/rip-2-proxy-admin.md` — full RIP proposal
   - `docs/rip-2-least-privilege.md` — least-privilege configuration guide
   - rocketmq-apis repository, branch `feature/rip-2-proxy-admin-grpc` (proto 
contract)
   
   
   ### Describe Alternatives You've Considered
   
   # [RIP-2] Proxy Admin Standardized Management Interface
   
   ## Background
   
   RocketMQ 5.0 moved client access behind the stateless Proxy, but operations 
still
   observe clients through broker-side structures (`ConsumerManager` on the 
broker,
   Remoting-era admin commands). **gRPC clients attached to a Proxy are 
invisible to
   those tools**: the control plane cannot answer *"which SDK clients are 
online, what
   do they subscribe to, are they healthy?"* without indirect metrics 
heuristics.
   
   RIP-1 (Control Plane 5.0 dashboard, requirement `CLIENT-01`) explicitly 
depends on
   a standard server-side interface to read complete gRPC client data. **There 
is
   currently no such interface on the Proxy.**
   
   ## Problem Statement
   
   1. **No dedicated admin surface on the Proxy.** The data-plane 
`MessagingService`
      gRPC service is not designed for control-plane queries (client 
enumeration,
      runtime config, connection control, diagnostics). Operators must SSH into 
brokers
      and run Remoting-era `mqadmin` commands, which cannot see gRPC clients.
   2. **No least-privilege authorization for admin operations.** Existing admin
      operations share the broker ACL scope; there is no way to grant a 
read-only
      observer vs. a break-glass admin on the Proxy itself.
   3. **No cluster-wide client view.** Each Proxy only knows its own clients; 
there is
      no documented mechanism to aggregate client state across all proxies in a
      cluster.
   4. **No self-service observability.** Admin RPCs are not instrumented with 
their
      own RT / error-rate metrics, so admin-interface health is invisible to
      monitoring.
   5. **No stable, protocol-pure contract.** Broker-internal wire types leak 
into
      admin tooling, coupling every consumer to internal remoting classes.
   
   ## Proposal
   
   Implement **RIP-2: Proxy Admin Standardized Management Interface** — a 
dedicated,
   independent gRPC Admin service on the Proxy, isolated from the data plane, 
with a
   stable backward-compatible proto contract and fine-grained ACL 2.0 
authorization.
   
   ### Goals
   
   1. A dedicated gRPC Admin service on the Proxy, served on its own port
      (`adminGrpcPort`, default **8083**), isolated from the data-plane
      `MessagingService`. A global kill switch `proxyAdminEnabled` disables the 
whole
      surface.
   2. A stable, backward-compatible proto contract (`ProxyAdminService` +
      `AdminService` in `apache/rocketmq/v2/admin.proto`, rocketmq-apis 
**2.3.0**).
   3. First-class authorization under dedicated `proxy.admin.*` ACL 2.0 
resources
      with read-only (`Get`/`List`) / high-privilege (`Update`/`Delete`/`Pub`)
      action separation.
   4. The service exposes its own call RT and error-rate metrics 
(OpenTelemetry).
   5. Multi-Proxy semantics: a documented, predictable story for cluster-wide 
views.
   
   ### Non-Goals (this iteration)
   
   - Broker-side quota storage.
   - Remoting client kick (Remoting clients remain observable via existing 
broker
     channels; the proto carries a `protocol` field for future coverage).
   - A central client registry (proxies are stateless; peer-list configuration 
is
     explicit and auditable).
   
   ## Design Decisions
   
   | ID | Decision | Summary |
   |----|----------|---------|
   | D1 | Service placement | Dedicated `ProxyAdminService` on its own gRPC 
server/port (8083), separate from data plane and broker-facing `Admin`. 
Intentionally does NOT expose channelz or proto reflection. |
   | D2 | Authorization | Every RPC maps to one `proxy.admin.*` resource + one 
action. Resources modeled as cluster-typed literals 
(`cluster:proxy.admin.<module>`). Fail-closed `proxyAdminRequireAuth` mode. 
Audit logging per served RPC. |
   | D3 | Multi-proxy semantics | Each Proxy returns its LOCAL view tagged with 
`proxy_endpoint` + monotonic `epoch`. `PROXY_SCOPE_ALL_PROXIES` fans out to 
configured peers in parallel and deduplicates by `client_id`. Peer failures 
degrade gracefully. |
   | D4 | Pagination | Cursor-based `next_token` for client listings (stable 
under connection churn). Offset pagination (`page_num`/`page_size`, max 100) 
for bounded diagnostic snapshots. |
   | D5 | Protocol coverage | `ClientInstance.protocol` distinguishes GRPC vs 
REMOTING. This iteration tracks gRPC clients; the field is forward-compatible 
for Remoting coverage. |
   
   ### D2 — Authorization Matrix
   
   | Resource | RPCs | Action |
   |----------|------|--------|
   | `proxy.admin.client` | ListClients / ListClientsByGroup / 
ListClientsByTopic | List |
   | `proxy.admin.client` | DescribeClient / DescribePopReceiptHandles / 
DescribeBatchConsumeDiagnostics / ListSubscription / DescribeSubscription / 
ListConsumerConnection / DescribeGroupAccumulation / GetConsumerRunningInfo / 
QueryTimeSpan | Get |
   | `proxy.admin.config` | DescribeProxyConfig | Get |
   | `proxy.admin.config` | UpdateProxyConfig / ChangeLogLevel | Update |
   | `proxy.admin.connection` | KickClient / DisconnectChannel / 
PrintThreadStackTrace / VerifyMessage | Update (high privilege) |
   | `proxy.admin.quota` | DescribeQuota | Get |
   | `proxy.admin.quota` | UpdateQuota | Update (high privilege) |
   | `proxy.admin.route` | DescribeRouteTopology / GetTopicRoute | Get |
   | `proxy.admin.route` | SubscribeRouteEvents | List |
   | `proxy.admin.ops` | GetProxyRuntimeStats / DescribeTopicStatus / 
QueryMessage | Get |
   | `proxy.admin.ops` | ResetGroupOffset | Update (high privilege) |
   | `proxy.admin.ops` | DeleteSubscription | Delete (high privilege) |
   | `proxy.admin.ops` | AdminSendMessage | Pub (high privilege) |
   
   ### RPC Surface (14+ RPCs across two services)
   
   **`ProxyAdminService` (M1–M4):**
   - M1: `ListClients`, `DescribeClient`, `ListClientsByGroup`, 
`ListClientsByTopic`
   - M2: `DescribeProxyConfig` / `UpdateProxyConfig`, `KickClient` / 
`DisconnectChannel`, `DescribeQuota` / `UpdateQuota`
   - M3/M4: `DescribePopReceiptHandles`, `DescribeBatchConsumeDiagnostics`
   - Route observation: `SubscribeRouteEvents` (server-streaming), 
`DescribeRouteTopology`
   
   **`AdminService` (broker-facing, served through the Proxy's managed 
client):**
   - `GetProxyRuntimeStats`, `DescribeTopicStatus`, `QueryMessage`, 
`QueryTimeSpan`,
     `GetConsumerRunningInfo`, `ListConsumerConnection`, `ListSubscription`,
     `DescribeSubscription`, `DescribeGroupAccumulation`, `ResetGroupOffset`,
     `DeleteSubscription`, `AdminSendMessage`, `PrintThreadStackTrace`,
     `VerifyMessage`, `ChangeLogLevel`, `GetTopicRoute`
   
   ### Observability
   
   - `rocketmq_proxy_admin_rpc_total{rpc_method, status, error_type?}` — error 
rate
   - `rocketmq_proxy_admin_rpc_latency{rpc_method, status}` (ms histogram) — RT 
P50/P99
   
   ### Configuration Reference
   
   | Key | Default | Meaning |
   |-----|---------|---------|
   | `proxyAdminEnabled` | true | Kill switch; false = admin server not started 
|
   | `adminGrpcPort` | 8083 | Dedicated admin gRPC port (≤0 disables) |
   | `proxyAdminRequireAuth` | false | Fail-closed credential enforcement |
   | `proxyAdminPeerEndpoints` | [] | Peer admin endpoints for ALL_PROXIES 
fan-out |
   | `proxyAdminPeerTimeoutMillis` | 3000 | Per-peer fan-out timeout |
   | `proxyAdminHeartbeatHistorySize` | 16 | Heartbeat records kept per client |
   
   ## Acceptance Criteria
   
   | Criterion | Status |
   |-----------|--------|
   | RIP document + stable backward-compatible proto contract | 
`docs/rip-2-proxy-admin.md` + rocketmq-apis `admin.proto` |
   | Client query RPCs merged; pagination scales with connection churn | D4 
stable cursor; page cost O(pageSize) after sort |
   | Independent ACL control, read-only/high-risk separation, least-privilege 
doc | D2 resources/actions + `docs/rip-2-least-privilege.md` |
   | RPC RT & error-rate metrics | ProxyAdminMetricsManager instruments |
   | E2E with RIP-1 dashboard | Contract frozen for dashboard CLIENT-01 
integration (cross-repo) |
   
   ## References
   
   - RIP-1 Control Plane 5.0 dashboard (requirement `CLIENT-01`)
   - `docs/rip-2-proxy-admin.md` — full RIP proposal
   - `docs/rip-2-least-privilege.md` — least-privilege configuration guide
   - rocketmq-apis repository, branch `feature/rip-2-proxy-admin-grpc` (proto 
contract)
   
   
   ### Additional Context
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to