mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
docs: add admin route action snapshot (#3258)
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# Admin Route Action Snapshot
|
||||
|
||||
This snapshot records the current admin routing and authorization surface before
|
||||
directory moves or crate extraction. It is a migration guardrail: later pure
|
||||
move PRs must preserve the route, handler, authorization action, public
|
||||
exception, and compatibility alias semantics listed here unless the PR is
|
||||
explicitly scoped as a behavior change.
|
||||
|
||||
## Source Of Truth
|
||||
|
||||
- Router assembly: `rustfs/src/admin/mod.rs::make_admin_route`
|
||||
- Route registration coverage: `rustfs/src/admin/route_registration_test.rs`
|
||||
- Runtime dispatch: `rustfs/src/admin/router.rs`
|
||||
- Admin auth helpers: `rustfs/src/admin/auth.rs`
|
||||
- Handler route/action ownership: `rustfs/src/admin/handlers/*.rs`
|
||||
|
||||
The route registration test intentionally covers representative paths for every
|
||||
registered route family. This document uses route patterns from the registration
|
||||
functions and action names from the handler authorization calls.
|
||||
|
||||
## Prefix And Alias Contract
|
||||
|
||||
| Prefix | Current behavior | Migration rule |
|
||||
|---|---|---|
|
||||
| `/rustfs/admin` | Canonical admin API prefix used by route registration | Keep as the single registered admin prefix |
|
||||
| `/minio/admin` | Compatibility alias accepted by `S3Router::is_match`; dispatch canonicalizes it to `/rustfs/admin` | Do not duplicate registrations; preserve canonicalization |
|
||||
| `/iceberg/v1` table catalog prefix | Registered through `table_catalog::register_table_catalog_route` and accepted by `is_admin_path` | Keep outside `/rustfs/admin` and document auth separately |
|
||||
| `/health` and `/health/ready` | Public health endpoints when `ENV_HEALTH_ENDPOINT_ENABLE` allows registration | Preserve unauthenticated health bypass |
|
||||
| `/profile/cpu` and `/profile/memory` | Registered by health handler but guarded by profile auth | Do not couple to health endpoint enablement |
|
||||
|
||||
The compatibility alias is not a second route table. `canonicalize_admin_path`
|
||||
maps `/minio/admin/...` to `/rustfs/admin/...` immediately before route lookup.
|
||||
|
||||
## Dispatch And Auth Shape
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Incoming request"] --> B{"S3Router::is_match"}
|
||||
B -->|"Replication or misc extension"| X["Extension handler"]
|
||||
B -->|"Health path"| H["Public health"]
|
||||
B -->|"OIDC public path"| O["OIDC public handler"]
|
||||
B -->|"POST / STS form"| S["STS handler"]
|
||||
B -->|"Admin or console path"| C{"S3Router::check_access"}
|
||||
C -->|"public exception"| P["No SigV4 required"]
|
||||
C -->|"admin route"| D["Credential required"]
|
||||
D --> E["canonicalize /minio/admin to /rustfs/admin"]
|
||||
E --> F["matchit route lookup"]
|
||||
F --> G["AdminOperation handler"]
|
||||
G --> I["handler-level validate_admin_request"]
|
||||
```
|
||||
|
||||
Route-level credential presence and handler-level policy authorization are
|
||||
separate contracts. The router enforces credential presence for ordinary admin
|
||||
routes. Handler rows below record whether the current handler performs a
|
||||
precise `AdminAction` or `S3Action` check, or only repeats a credential
|
||||
presence check.
|
||||
|
||||
## Public Exceptions
|
||||
|
||||
| Method | Path pattern | Handler | Auth contract |
|
||||
|---|---|---|---|
|
||||
| `GET`, `HEAD` | `/health` | `HealthCheckHandler` | Public when health routes are registered |
|
||||
| `GET`, `HEAD` | `/health/ready` | `HealthCheckHandler` | Public when health routes are registered |
|
||||
| Registered as `GET`; auth bypass is path-based | `/rustfs/admin/v3/oidc/providers` and `/minio/admin/v3/oidc/providers` | `ListOidcProvidersHandler` | Public OIDC bootstrap path; `check_access` bypasses SigV4 for any method matching this path |
|
||||
| Registered as `GET`; auth bypass is path-prefix-based | `/rustfs/admin/v3/oidc/authorize/{provider_id}` and `/minio/admin/v3/oidc/authorize/{provider_id}` | `OidcAuthorizeHandler` | Public OIDC bootstrap path; `check_access` bypasses SigV4 for any method matching this path prefix |
|
||||
| Registered as `GET`; auth bypass is path-prefix-based | `/rustfs/admin/v3/oidc/callback/{provider_id}` and `/minio/admin/v3/oidc/callback/{provider_id}` | `OidcCallbackHandler` | Public OIDC bootstrap path; `check_access` bypasses SigV4 for any method matching this path prefix |
|
||||
| Registered as `GET`; auth bypass is path-based | `/rustfs/admin/v3/oidc/logout` and `/minio/admin/v3/oidc/logout` | `OidcLogoutHandler` | Public OIDC logout path; `check_access` bypasses SigV4 for any method matching this path |
|
||||
| `POST` | `/` with `application/x-www-form-urlencoded` | `AssumeRoleHandle` | Public only for unsigned STS web identity form requests; handler validates JWT/action |
|
||||
| Any matched method | `/favicon.ico` and `/rustfs/console...` | Console router | Public only when `console_enabled` is true; router bypasses SigV4 before handing off to the console router |
|
||||
|
||||
## Registered Route Families
|
||||
|
||||
All rows with `/rustfs/admin` also accept the `/minio/admin` compatibility alias
|
||||
through router canonicalization unless the row explicitly says otherwise.
|
||||
|
||||
| Area | Methods and path patterns | Handler ownership | Authorization contract |
|
||||
|---|---|---|---|
|
||||
| STS and admin probe | `POST /`; `GET /rustfs/admin/v3/is-admin` | `sts.rs`, `is_admin.rs` | STS dispatch validates request action; is-admin checks `AllAdminActions` |
|
||||
| User lifecycle | `GET /v3/list-users`; `GET /v3/user-info`; `PUT /v3/add-user`; `PUT /v3/set-user-status`; `DELETE /v3/remove-user` | `user_lifecycle.rs`, `user.rs` | `ListUsersAdminAction`, `GetUserAdminAction`, `CreateUserAdminAction`, `EnableUserAdminAction`, `DeleteUserAdminAction` |
|
||||
| Group management | `GET /v3/groups`; `GET /v3/group`; `DELETE /v3/group/{group}`; `PUT /v3/set-group-status`; `PUT /v3/update-group-members` | `group.rs` | `ListGroupsAdminAction`, `GetGroupAdminAction`, `RemoveUserFromGroupAdminAction`, `EnableGroupAdminAction`, `AddUserToGroupAdminAction` |
|
||||
| Service accounts | `PUT /v3/add-service-account(s)`; `POST /v3/update-service-account`; `GET /v3/info-service-account`; `GET /v3/temporary-account-info`; `GET /v3/info-access-key`; `GET /v3/list-service-accounts`; `GET /v3/list-access-keys-bulk`; `DELETE /v3/delete-service-account(s)` | `service_account.rs` | create/update/list/temp-info/user-list/remove service account actions as checked in handler context |
|
||||
| IAM import/export | `GET /v3/export-iam`; `PUT /v3/import-iam` | `user_iam.rs`, `user.rs` | `ExportIAMAction`, `ImportIAMAction` |
|
||||
| IAM policies | `GET /v3/list-canned-policies`; `GET /v3/info-canned-policy`; `PUT /v3/add-canned-policy`; `DELETE /v3/remove-canned-policy`; `PUT /v3/set-user-or-group-policy`; `PUT /v3/set-policy`; `POST /v3/idp/builtin/policy/attach`; `POST /v3/idp/builtin/policy/detach`; `GET /v3/idp/builtin/policy-entities` | `policies.rs` | list/create/get/delete/attach policy actions; policy-entities combines list groups, users, and policies |
|
||||
| Account info | `GET /v3/accountinfo` | `account_info.rs` | S3 action checks for account-scoped bucket and object probes |
|
||||
| System info | `GET /v3/info`; `GET /v3/storageinfo`; `GET /v3/datausageinfo` | `system.rs` | `ServerInfoAdminAction`, `StorageInfoAdminAction`, `DataUsageInfoAdminAction` plus `ListBucketAction` for data usage |
|
||||
| Metrics stream | `GET /v3/metrics` | `metrics.rs` through `system.rs` | Router credential presence plus handler credential check; no handler-level `AdminAction` is currently enforced |
|
||||
| System service placeholders | `POST /v3/service`; `GET|POST /v3/inspect-data` | `system.rs` | Currently registered but handler returns `NotImplemented`; migration must preserve this unless behavior changes |
|
||||
| Pools | `GET /v3/pools/list`; `GET /v3/pools/status`; `POST /v3/pools/decommission`; `POST /v3/pools/cancel` | `pools.rs` | list/status accept server-info or decommission; decommission/cancel use `DecommissionAdminAction` |
|
||||
| Rebalance | `POST /v3/rebalance/start`; `GET /v3/rebalance/status`; `POST /v3/rebalance/stop` | `rebalance.rs` | `RebalanceAdminAction` |
|
||||
| Heal | `POST /v3/heal/`; `POST /v3/heal/{bucket}`; `POST /v3/heal/{bucket}/{prefix}`; `POST /v3/background-heal/status` | `heal.rs` | `HealAdminAction` |
|
||||
| Tier | `GET /v3/tier`; `GET /v3/tier-stats`; `GET /v3/tier/{tier}`; `DELETE /v3/tier/{tiername}`; `PUT /v3/tier`; `POST /v3/tier/{tiername}`; `POST /v3/tier/clear` | `tier.rs` | `ListTierAction` for reads/status; `SetTierAction` for add/edit/remove/clear |
|
||||
| Quota legacy and bucket-scoped | `PUT /v3/set-bucket-quota`; `GET /v3/get-bucket-quota`; `PUT|GET|DELETE /v3/quota/{bucket}`; `GET /v3/quota-stats/{bucket}`; `POST /v3/quota-check/{bucket}` | `quota.rs` | `SetBucketQuotaAdminAction` for writes; `GetBucketQuotaAction` for bucket-scoped reads/stats/checks |
|
||||
| Bucket metadata | `GET /export-bucket-metadata`; `GET /v3/export-bucket-metadata`; `PUT /import-bucket-metadata`; `PUT /v3/import-bucket-metadata` | `bucket_meta.rs` | `ExportBucketMetadataAction`, `ImportBucketMetadataAction` |
|
||||
| Server config | `GET /v3/get-config-kv`; `PUT /v3/set-config-kv`; `DELETE /v3/del-config-kv`; `GET /v3/help-config-kv`; `GET /v3/list-config-history-kv`; `DELETE /v3/clear-config-history-kv`; `PUT /v3/restore-config-history-kv`; `GET|PUT /v3/config` | `config_admin.rs` | `ConfigUpdateAdminAction` helper path; read/write handlers preserve current per-handler checks |
|
||||
| Scanner | `GET /v3/scanner/status` | `scanner.rs` | `ServerInfoAdminAction` |
|
||||
| Notification targets | `GET /v3/target/list`; `GET /v3/target/arns`; `PUT /v3/target/{target_type}/{target_name}`; `DELETE /v3/target/{target_type}/{target_name}/reset` | `event.rs` through `user_policy_binding.rs` | `GetBucketTargetAction` for list/ARNs; `SetBucketTargetAction` for put/delete |
|
||||
| Audit targets | `GET /v3/audit/target/list`; `PUT /v3/audit/target/{target_type}/{target_name}`; `DELETE /v3/audit/target/{target_type}/{target_name}/reset` | `audit.rs` | `GetBucketTargetAction` for list; `SetBucketTargetAction` for put/delete |
|
||||
| Module switches | `GET|PUT /v3/module-switches` | `module_switch.rs` | `ServerInfoAdminAction` for get; `ConfigUpdateAdminAction` for update |
|
||||
| Plugin catalog | `GET /v4/plugins/catalog` | `plugins_catalog.rs` | `ServerInfoAdminAction` |
|
||||
| Plugin instances | `GET /v4/plugins/instances`; `GET|PUT|DELETE /v4/plugins/instances/{id}` | `plugins_instances.rs` | read uses `GetBucketTargetAction`; write/delete use `SetBucketTargetAction` |
|
||||
| Replication target list | `GET /v3/list-remote-targets` | `replication.rs` | Router credential presence plus handler credential check; no handler-level `AdminAction` is currently enforced |
|
||||
| Replication target metrics/mutation | `GET /v3/replicationmetrics`; `PUT /v3/set-remote-target`; `DELETE /v3/remove-remote-target` | `replication.rs` | `GetReplicationMetricsAction` for metrics; `SetBucketTargetAction` for target mutation |
|
||||
| Site replication | `PUT /v3/site-replication/add`; `PUT /v3/site-replication/remove`; `GET /v3/site-replication/info`; `GET /v3/site-replication/metainfo`; `GET /v3/site-replication/status`; `POST /v3/site-replication/devnull`; `POST /v3/site-replication/netperf`; `PUT /v3/site-replication/edit`; `PUT /v3/site-replication/peer/join`; `PUT /v3/site-replication/peer/bucket-ops`; `PUT /v3/site-replication/peer/iam-item`; `PUT /v3/site-replication/peer/bucket-meta`; `GET /v3/site-replication/peer/idp-settings`; `PUT /v3/site-replication/peer/edit`; `PUT /v3/site-replication/peer/remove`; `PUT /v3/site-replication/resync/op`; `PUT /v3/site-replication/state/edit` | `site_replication.rs` | add/remove/info/operation/resync actions selected per handler |
|
||||
| Admin profiling | `GET /rustfs/admin/debug/pprof/profile`; `GET /rustfs/admin/debug/pprof/status` | `profile_admin.rs`, `profile.rs` | `ProfilingAdminAction` |
|
||||
| TLS debug | `GET /rustfs/admin/debug/tls/status` | `tls_debug.rs`, `profile.rs` | `ProfilingAdminAction` via shared profile authorization |
|
||||
| KMS legacy management | `POST /v3/kms/create-key`; `POST /v3/kms/key/create`; `GET /v3/kms/describe-key`; `GET /v3/kms/key/status`; `GET /v3/kms/list-keys`; `POST /v3/kms/generate-data-key`; `GET|POST /v3/kms/status`; `GET /v3/kms/config`; `POST /v3/kms/clear-cache` | `kms_management.rs`, `kms_keys.rs` | create/status/server-info KMS admin actions as checked per handler |
|
||||
| KMS dynamic control | `POST /v3/kms/configure`; `POST /v3/kms/start`; `POST /v3/kms/stop`; `GET /v3/kms/service-status`; `POST /v3/kms/reconfigure` | `kms_dynamic.rs` | `ServerInfoAdminAction` |
|
||||
| KMS keys | `POST /v3/kms/keys`; `DELETE /v3/kms/keys/delete`; `POST /v3/kms/keys/cancel-deletion`; `GET /v3/kms/keys`; `GET /v3/kms/keys/{key_id}` | `kms_keys.rs` | `KMSCreateKeyAdminAction`, `KMSKeyStatusAdminAction`, `ServerInfoAdminAction` per handler |
|
||||
| OIDC public | `GET /v3/oidc/providers`; `GET /v3/oidc/authorize/{provider_id}`; `GET /v3/oidc/callback/{provider_id}`; `GET /v3/oidc/logout` | `oidc.rs` | Public OIDC exception in `is_oidc_path` |
|
||||
| OIDC config | `GET /v3/oidc/config`; `PUT|DELETE /v3/oidc/config/{provider_id}`; `POST /v3/oidc/validate` | `oidc.rs` | `ServerInfoAdminAction` for read/validate; `ConfigUpdateAdminAction` for mutation |
|
||||
|
||||
## Table Catalog Routes
|
||||
|
||||
The table catalog API is registered by the admin router but is not under
|
||||
`/rustfs/admin`. It has its own prefix and Iceberg-style route shape.
|
||||
|
||||
| Method | Path pattern | Handler | Authorization action |
|
||||
|---|---|---|---|
|
||||
| `GET` | `/iceberg/v1/config` | `GET_CONFIG_HANDLER` | `GetTableCatalogAction` |
|
||||
| `GET` | `/iceberg/v1/{warehouse}/namespaces` | `LIST_NAMESPACES_HANDLER` | `GetTableNamespaceAction` |
|
||||
| `POST` | `/iceberg/v1/{warehouse}/namespaces` | `CREATE_NAMESPACE_HANDLER` | `SetTableNamespaceAction` |
|
||||
| `GET` | `/iceberg/v1/{warehouse}/namespaces/{namespace}` | `GET_NAMESPACE_HANDLER` | `GetTableNamespaceAction` |
|
||||
| `DELETE` | `/iceberg/v1/{warehouse}/namespaces/{namespace}` | `DROP_NAMESPACE_HANDLER` | `DeleteTableNamespaceAction` |
|
||||
| `GET` | `/iceberg/v1/{warehouse}/namespaces/{namespace}/tables` | `LIST_TABLES_HANDLER` | `GetTableAction` |
|
||||
| `POST` | `/iceberg/v1/{warehouse}/namespaces/{namespace}/tables` | `CREATE_TABLE_HANDLER` | `CreateTableAction` |
|
||||
| `POST` | `/iceberg/v1/{warehouse}/namespaces/{namespace}/register` | `REGISTER_TABLE_HANDLER` | `RegisterTableAction` |
|
||||
| `GET` | `/iceberg/v1/{warehouse}/namespaces/{namespace}/tables/{table}` | `LOAD_TABLE_HANDLER` | `GetTableAction` |
|
||||
| `POST` | `/iceberg/v1/{warehouse}/namespaces/{namespace}/tables/{table}` | `COMMIT_TABLE_HANDLER` | `CommitTableAction` |
|
||||
| `DELETE` | `/iceberg/v1/{warehouse}/namespaces/{namespace}/tables/{table}` | `DROP_TABLE_HANDLER` | `DeleteTableAction` |
|
||||
|
||||
## Migration Rules
|
||||
|
||||
1. Pure move PRs may move handler modules, but must not change registered
|
||||
methods, patterns, handler ownership, alias canonicalization, or public
|
||||
exception behavior.
|
||||
2. If an admin handler is wrapped to cut a dependency direction, the wrapper
|
||||
must preserve the same `AdminAction` or `S3Action` check and keep response
|
||||
compatibility unchanged.
|
||||
3. Do not duplicate `/minio/admin` registrations. The alias remains a router
|
||||
canonicalization concern.
|
||||
4. Do not move table catalog routes under `/rustfs/admin` during route cleanup.
|
||||
5. Registered-but-`NotImplemented` routes are behavior contracts too. Removing
|
||||
or implementing them requires a behavior-change PR type.
|
||||
6. Future route matrix automation should compare against this document and
|
||||
`route_registration_test.rs` before crate extraction begins.
|
||||
@@ -5,13 +5,13 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
## Current Context
|
||||
|
||||
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
|
||||
- Branch: `overtrue/arch-startup-timeline`
|
||||
- Baseline: `upstream/main` at `ae9d25879d72bc8977f08e61062c022e2142483b`
|
||||
- Branch: `overtrue/arch-admin-route-snapshot`
|
||||
- Baseline: `upstream/main` at `0f9584c8d9351c757437405ee69a4e64bbcd94b5`
|
||||
- PR type for this branch: `docs-only`
|
||||
- Runtime behavior changes: none
|
||||
- Rust code changes: none
|
||||
- Docs changes: add the binary startup timeline baseline for later
|
||||
runtime/lifecycle migration work.
|
||||
- Docs changes: add the admin route/action snapshot baseline for later
|
||||
admin module movement and route-matrix guard work.
|
||||
|
||||
## Phase 0 Tasks
|
||||
|
||||
@@ -35,6 +35,11 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
- [x] `G-007` Create startup timeline table.
|
||||
- Acceptance: [`startup-timeline.md`](startup-timeline.md) records current
|
||||
binary startup order, side effects, fatal boundaries, and readiness stages.
|
||||
- [x] `G-008` Capture admin route-action snapshot.
|
||||
- Acceptance: [`admin-route-action-snapshot.md`](admin-route-action-snapshot.md)
|
||||
records current route families, handler ownership, authorization actions,
|
||||
public exceptions, table-catalog routes, and `/minio/admin` compatibility
|
||||
alias behavior.
|
||||
- [x] `G-009` Enforce pre-push three-expert review.
|
||||
- Acceptance: [`crate-boundaries.md`](crate-boundaries.md) requires
|
||||
quality/architecture, migration-preservation, and testing/verification review
|
||||
@@ -46,18 +51,19 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
|
||||
## Next PRs
|
||||
|
||||
1. `docs-only` or `test-only`: capture admin route-action snapshot.
|
||||
2. `docs-only`: inventory `ecstore::config::{Config, KV, KVS}` consumers.
|
||||
3. `ci-gate`: add focused checks for PR type vocabulary and temporary
|
||||
1. `docs-only`: inventory `ecstore::config::{Config, KV, KVS}` consumers.
|
||||
2. `ci-gate`: add focused checks for PR type vocabulary and temporary
|
||||
compatibility marker/register consistency.
|
||||
3. `test-only`: add a mechanical admin route matrix guard from the current
|
||||
snapshot and `route_registration_test.rs`.
|
||||
|
||||
## Pre-Push Review Log
|
||||
|
||||
| Expert | Status | Notes |
|
||||
|---|---|---|
|
||||
| Quality/architecture | pass | Final review confirmed the startup, deferred IAM, readiness, and shutdown tables match current source behavior after blocker fixes |
|
||||
| Migration preservation | pass | Final review confirmed this branch is docs-only and does not touch runtime logic, storage hot paths, global-state migration, or compatibility code |
|
||||
| Testing/verification | pass | Final review accepted docs-only verification with layer guard, metrics reference guard, diff checks, and staged whitespace check |
|
||||
| Quality/architecture | pass | Final review confirmed route/action/public-exception rows are source-backed, including OIDC path-based bypass, console bypass, credential-only metrics/list-remote-targets, notification targets, table-catalog prefix, and site-replication edit |
|
||||
| Migration preservation | pass | Final review confirmed this branch is docs-only, aligned with Phase 0, and does not touch runtime logic, storage hot paths, global state, compatibility implementation, or crate boundaries |
|
||||
| Testing/verification | pass | Final review accepted docs-only verification with layer guard, metrics reference guard, diff checks, staged diff coverage, and future route-matrix handoff |
|
||||
|
||||
## Verification Notes
|
||||
|
||||
@@ -67,8 +73,9 @@ Passed:
|
||||
- `./scripts/check_metrics_migration_refs.sh`
|
||||
- `git diff --check`
|
||||
- `git diff --cached --check`
|
||||
- focused source review of `rustfs/src/main.rs`, `rustfs/src/startup_iam.rs`,
|
||||
and `rustfs/src/server/readiness.rs`
|
||||
- focused source review of `rustfs/src/admin/mod.rs`,
|
||||
`rustfs/src/admin/router.rs`, `rustfs/src/admin/route_registration_test.rs`,
|
||||
and `rustfs/src/admin/handlers/*.rs` route/action declarations
|
||||
|
||||
## Handoff Notes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user