Access Hub Collector
Đồng bộ từ mã nguồn lúc 10:57, 03/10/2026
Skip to content

L3 - Nền tảng giám sát máy chủ - Collector - Admin API ​

Quy ước tên: L3 - <P&L> - <Hệ thống L2> - <Thành phần>. P&L: chưa chỉ định. Hệ thống L2: Collector. Thành phần: Admin API (/internal/v1), API nội bộ để Access Hub đẩy agent, đọc trạng thái, truy vấn chuỗi thời gian và xóa dữ liệu theo tenant. Mã: internal/admin/admin.go, internal/catalog, nối dây buildAdmin trong internal/app/wiring.go.

Trạng thái
Bản nháp
Phiên bản
0.1, ngày 30/09/2026
Tài liệu cha
L2 SAD Collector
Cấp độ hệ thống
Cấp 3, đề xuất

Ghi chú: khi tài liệu và mã khác nhau, mã thắng

Đã làm nghĩa là có mã và kiểm thử trong repo. Chỉ thiết kế nghĩa là có trong tài liệu nhưng chưa có mã. Chỗ lệch được ghi ở mục nợ kỹ thuật.

Quy ước đánh dấu: "Đã làm" là có mã và kiểm thử. "Chỉ thiết kế" là chỉ có trong docs/. "Đề xuất" là ý của tác giả bản nháp. Mã thắng khi lệch tài liệu.


0. Front matter ​

Thông tin tài liệu đầy đủ
Trạng tháiBẢN NHÁP, phiên bản 0.1, 2026-09-30. Người phê duyệt: chưa chỉ định
Thành phần (Component)Admin API (router, xác thực token, handler), Catalog chỉ số
Truy vết L2L2 SAD Collector: thành phần "Admin API" (mục 2.3, 6.1), FR đẩy agent, đọc trạng thái, truy vấn, xóa dữ liệu (mục 3), NFR cô lập tenant (mục 4), mục 9 (Security), rủi ro AR-007, AR-010. Mục tiêu L1: G1, G4 (qua L2)
Tài liệu chaL2 SAD Collector
Tài liệu anh emIngest API, Registry, Enroll, Presence, Bus, Worker, TSDB, Alerting, Outbox
TierĐề xuất Cấp 3 (kế thừa L2, chưa xác nhận)
Phân loại dữ liệuNhạy cảm vừa: API có quyền xóa dữ liệu và thu hồi agent của mọi tenant. Token admin là bí mật
Blast radiusLộ token admin cho phép đọc và xóa dữ liệu mọi tenant, đẩy agent giả. Lỗi tenant ở đây lẫn dữ liệu giữa công ty
Sign-off gateChưa chỉ định. Không có ai đã sign-off

Truy vết mục L3 đến thành phần L2:

Mục L3Thành phần hoặc mục L2
1 Phạm vi2.3 Các thành phần chính
2 Yêu cầu3 Functional, 4 NFR
3 Kiến trúc6.1 Component table
4, 6 Domain, dữ liệu7.1 Data Model
5 Hợp đồng6.2 Integration (Access Hub đến Collector)
7 Thuật toán8 Key flows
8, 9 Lỗi, suy thoái6.3 Resilience
11 Bảo mật9 Security, cô lập tenant
13 Telemetry13 Observability

1. Scope and Non-Goals ​

1.1 Vai trò ​

Cổng điều khiển của Access Hub (control plane) vào Collector (data plane). Access Hub: đẩy hoặc thu hồi agent, hỏi trạng thái máy chủ và tổng hợp công ty, truy vấn chuỗi thời gian cho giao diện, xóa dữ liệu khi gỡ máy chủ hoặc công ty. Collector không có giao diện người dùng; mọi thứ người dùng thấy đều do Access Hub gọi API này.

1.2 Context diagram ​

mermaid
flowchart LR
    classDef bc fill:#1f3a5f,stroke:#4a90d9,color:#fff;
    classDef owned fill:#2d4a3e,stroke:#5fb37a,color:#fff;
    classDef entity fill:#3a3320,stroke:#d9b84a,color:#fff;
    classDef datastore fill:#3a2d4a,stroke:#a06fd9,color:#fff;

    HUB(["Access Hub (ext)"]):::entity
    ADM["Admin API"]:::owned
    RG["Registry"]:::bc
    PS["Presence"]:::bc
    TS["TSDB adapter"]:::bc
    CAT["Catalog"]:::bc
    VM[("VictoriaMetrics")]:::datastore

    HUB -->|"HTTPS Bearer"| ADM
    ADM --> RG
    ADM --> PS
    ADM --> TS
    ADM --> CAT
    TS --> VM
ChiềuBênNội dung
VàoAccess Hub9 endpoint dưới /internal/v1
RaRegistry, PresenceĐẩy, thu hồi, xóa, đếm
RaTSDB adapterLatest, Range, DeleteServer, DeleteCompany
RaCatalogKiểm tra tên chỉ số hợp lệ, danh sách chỉ số trạng thái

1.3 Trong phạm vi ​

  • Router, xác thực Bearer, định dạng phản hồi và lỗi.
  • Đẩy và thu hồi agent.
  • Trạng thái máy chủ, tổng hợp công ty, trạng thái collector.
  • Truy vấn khoảng một chỉ số của một máy chủ.
  • Xóa dữ liệu theo máy chủ và theo công ty.
  • Nạp lại cấu hình (reload): rules đã nối vào bộ đồng bộ luật (COL-8) và trả 202, settings vẫn trả 501.

1.4 Ngoài phạm vi ​

Nội dungThuộc về
Phân quyền người dùng cuối, vai trò RBACAccess Hub (Collector chỉ tin token admin)
Tạo cảnh báo, luật, thông báoAccess Hub (collector chỉ đánh giá luật, COL-8)
Nạp lại cài đặt theo công ty (reload/settings)Chưa làm (501). reload/rules đã có
Phát hiện downL3 Alerting
Ghi dữ liệuL3 Ingest, L3 Bus, Worker, TSDB

2. Requirements ​

2.1 Functional Requirements ​

#Trách nhiệmGiải thíchHiện thực ở
FR-ADM-01Mọi endpoint cần tokenSai hoặc thiếu token thì 401TestAuthRequiredEverywhere
FR-ADM-02Tham số khởi tạo hợp lệThiếu token, registry, presence, store, catalog hoặc ngưỡng thì từ chốiTestNewRejectsBadOptions
FR-ADM-03Lỗi định tuyến rõ ràng404 đường dẫn lạ, 405 sai phương thức kèm AllowTestRoutingErrors
FR-ADM-04Đẩy agentPUT /agents/{id} kiểm tra nghiêm và lưuTestPutAndRevokeAgent, TestPutAgentValidation
FR-ADM-05Thu hồi agentDELETE /agents/{id} luôn 204 (idempotent)TestPutAndRevokeAgent
FR-ADM-06Reload404 với kind lạ, 501 khi chưa hỗ trợ (settings), 202 khi hàm reload chấp nhận (rules)TestReload
FR-ADM-07Trạng thái máy chủAgent, lần thấy cuối, trạng thái online, down hoặc unknown, chỉ số mới nhấtTestServerStatusAndSummary
FR-ADM-08Tổng hợp công tyTổng, online, offlineTestServerStatusAndSummary
FR-ADM-09Truy vấn chuỗiChỉ số thuộc catalog, khoảng tối đa 31 ngày (400 ngày khi có vm-long), cắt theo retention của góiTestSeriesQuery, TestSeriesRetentionClampMaxRangeAndPlannedStep, TestSeriesDefaultMaxRange
FR-ADM-10Xóa theo tenantXóa máy chủ hoặc công ty ở cả registry và TSDBTestDeleteDataIsTenantScoped
FR-ADM-11Trạng thái collectorPhiên bản, vai trò, uptime, độ sâu bus, outbox, đếm agentTestStatus
FR-ADM-12Cô lập tenant đầu cuốiHai tenant không thấy dữ liệu của nhau qua Ingest rồi AdminTestTwoTenantIsolationThroughIngestAndAdminAPI
FR-ADM-13Catalog hợp lệTên chỉ số hợp lệ, status_metrics phải có trong catalogTestEveryDefaultNameIsValid, TestParseRejectsUnknownStatusMetric, TestDefault

2.2 Non-Functional Requirements ​

Allocated:

NFR L2TargetCách đáp ứng ở L3
NFR-12 (cô lập tenant)company_id bắt buộc ở mọi thao tác theo phạm vitenant(c) gọi tsdb.CheckTenant
NFR-05 (bảo mật API nội bộ)Token mạnh, so sánh hằng thời gianToken tối thiểu 24 ký tự, so sánh băm SHA-256 bằng ConstantTimeCompare

Inherited: giới hạn HTTP server (timeout, MaxHeaderBytes 64 KiB, TLS tối thiểu 1.2 nếu bật), httpx (request id, health), listener admin mặc định 127.0.0.1:9101.

Owned:

IDTargetParent L2-NFRSatisfied-by
NFR-ADM-01Body tối đa 64 KiBNFR-05maxBody, io.LimitReader
NFR-ADM-02Khoảng truy vấn tối đa 31 ngày, 400 ngày khi có rollupNFR-01Options.MaxRange, DefaultMaxRange, tsdb.LongRetention
NFR-ADM-03Phản hồi lỗi thống nhất, không lộ chi tiết nội bộNFR-05Mã lỗi cố định, lỗi backend thành 503 unavailable
NFR-ADM-04Mọi lời gọi truy vết đượcNFR-06X-Request-Id trả về và ghi log

2.3 Acceptance Criteria ​

ACGiven / When / ThenTest ID
AC-ADM-01Given không có header Authorization, When gọi bất kỳ endpoint, Then 401 và WWW-AuthenticateTestAuthRequiredEverywhere
AC-ADM-02Given PUT /agents/a1 với agent_id khác path, When gọi, Then 400TestPutAgentValidation
AC-ADM-03Given state=active mà token_hash không phải SHA-256 hex thường, When gọi, Then 400TestPutAgentValidation
AC-ADM-04Given agent đã thu hồi hoặc chưa tồn tại, When DELETE, Then 204TestPutAndRevokeAgent
AC-ADM-05Given truy vấn thiếu company_id, When gọi, Then 400TestServerStatusAndSummary, TestSeriesQuery
AC-ADM-06Given metric ngoài catalog, When truy vấn, Then 400TestSeriesQuery
AC-ADM-07Given khoảng dài hơn giới hạn (31 ngày, hoặc 400 ngày khi có rollup), When truy vấn, Then 400TestSeriesDefaultMaxRange, TestSeriesRetentionClampMaxRangeAndPlannedStep
AC-ADM-08Given xóa dữ liệu máy chủ công ty A, When xong, Then dữ liệu công ty B còn nguyênTestDeleteDataIsTenantScoped
AC-ADM-09Given POST /reload/rules, When worker nối Options.Reload, Then 202 và luật được kéo lại ngay (settings vẫn 501)TestReload

2.4 Quality Attribute Scenarios ​

NguồnKích thíchMôi trườngPhản hồiThước đo
Kẻ tấn công trong mạngDò token adminBình thường401, so sánh hằng thời gianKhông rò thông tin độ dài hay tiền tố qua thời gian phản hồi
Access HubGọi truy vấn khi VictoriaMetrics lỗiBình thường503 unavailableKhông rò lỗi nội bộ
Quản trịXóa nhầm công tyBình thườngXóa ngay, không hoàn tácGhi log mức warn kèm request_id, company_id (đề xuất thêm bước xác nhận ở Access Hub)
Access HubĐẩy agent với version cũBình thườngRegistry bỏ bản cũ, API vẫn trả 200Xem L3 Registry

3. Application Architecture ​

3.1 Kiến trúc thời chạy (C&C) ​

mermaid
flowchart LR
    classDef bc fill:#1f3a5f,stroke:#4a90d9,color:#fff;
    classDef owned fill:#2d4a3e,stroke:#5fb37a,color:#fff;

    AU["Auth (Bearer)"]:::owned
    RT["Router /internal/v1"]:::owned
    HD["Handlers"]:::owned
    RG["Registry"]:::bc
    PS["Presence"]:::bc
    TS["TSDB Store"]:::bc
    CT["Catalog"]:::bc

    RT --> AU
    RT --> HD
    HD --> RG
    HD --> PS
    HD --> TS
    HD --> CT
Thành phầnTrách nhiệmVòng đời
Routerhttp.ServeMux mẫu Go 1.22: mỗi đường dẫn gắn bảng phương thức, sai phương thức thì 405Theo tiến trình
AuthKiểm Authorization: Bearer, so sánh SHA-256 hằng thời gian, chạy trước khi kiểm phương thứcTheo yêu cầu
HandlersKiểm đầu vào, gọi Registry, Presence, Store, Catalog, dựng phản hồi {"data":...}Theo yêu cầu
CatalogTệp metrics.yaml nhúng: tên chỉ số, nhãn cho phép, status_metricsNạp một lần
Kết nốiKiểuChi tiết
Access Hub đến AdminĐồng bộHTTPS (triển khai) hoặc HTTP nội bộ ở dev
Admin đến Registry, PresenceĐồng bộTimeout Redis 500 ms
Admin đến StoreĐồng bộtsdb.timeout

Listener admin (mặc định 127.0.0.1:9101) cũng phục vụ /healthz và /readyz (httpx.AddHealth), không cần token.

3.2 Module view ​

mermaid
flowchart TB
    classDef bc fill:#1f3a5f,stroke:#4a90d9,color:#fff;
    classDef owned fill:#2d4a3e,stroke:#5fb37a,color:#fff;

    APP["internal/app"]:::bc
    ADM["internal/admin"]:::owned
    CAT["internal/catalog"]:::owned
    HX["internal/httpx"]:::bc
    RGS["internal/registry"]:::bc
    PRE["internal/presence"]:::bc
    TSP["internal/tsdb"]:::bc
    HCP["internal/hubclient (AgentRecord)"]:::bc

    APP --> ADM
    ADM --> CAT
    ADM --> HX
    ADM --> RGS
    ADM --> PRE
    ADM --> TSP
    ADM --> HCP

Tham số ngưỡng Threshold = max(3 x alerting.agent_interval, alerting.down_min) (cùng công thức với Detector), dùng để tính online.


4. Domain Model ​

mermaid
classDiagram
    class AgentRecord {
        <<hubclient>>
        agent_id
        company_id
        server_id
        state
        token_hash
        prev_token_hash
        version
    }
    class ServerStatus {
        <<response>>
        server_id
        company_id
        state
        last_seen
        agents[]
        latest[]
    }
    class AgentStatus {
        agent_id
        state
        agent_version
        last_seen
        down
        down_since
    }
    class SeriesResult {
        <<response>>
        metric
        agg
        step_seconds
        series[]
    }
    class Catalog {
        <<embedded>>
        metrics
        status_metrics
    }
    ServerStatus "1" --> "*" AgentStatus
    ServerStatus --> Catalog
    SeriesResult --> Catalog

Bất biến:

  • company_id bắt buộc cho mọi thao tác theo máy chủ (tham số truy vấn company_id) và mọi tạo bản ghi (trong body).
  • Trạng thái máy chủ: down nếu có agent down; online nếu có agent thấy thật trong ngưỡng; ngược lại unknown.
  • ID (agent, công ty, máy chủ) khớp tsdb.ValidID; chỉ số phải có trong catalog.

5. API Contract ​

5.1 Operations ​

Tiền tố /internal/v1. Mọi endpoint yêu cầu Authorization: Bearer <admin token>.

MethodPathMục đíchPhản hồi thành công
PUT/agents/{id}Đẩy hoặc cập nhật agent200
DELETE/agents/{id}Thu hồi agent (idempotent)204
POST/reload/{kind}Nạp lại rules hoặc settings202 cho rules, 501 cho settings
GET/servers/{id}/status?company_id=Trạng thái máy chủ200
GET/servers/{id}/series?company_id=&metric=&from=&to=&step=&agg=Truy vấn khoảng200
DELETE/servers/{id}/data?company_id=Xóa dữ liệu máy chủ200
GET/companies/{id}/summaryTổng hợp công ty200
DELETE/companies/{id}/dataXóa dữ liệu công ty200
GET/statusTrạng thái collector200

Lệch tài liệu: docs/03 và docs/06 mô tả tập endpoint khác (xem L2 TD list). Mã thắng. POST /reload/rules chạy thật (app.reload gọi Syncer.Reload khi có worker, hoặc tăng tín hiệu Redis rules:reload khi admin tách tiến trình). settings trả 501.

5.2 Request và Response schema ​

Ký hiệu ! bắt buộc, ? tùy chọn. Phản hồi thành công bọc trong {"data": ...}.

PUT /agents/{id}
  Body: AgentRecord (tối đa 64 KiB)
    agent_id?: string (nếu có phải bằng {id})
    company_id!, server_id!: ValidID
    state!: "pending" | "active" | "revoked"
    token_hash: 64 hex thường (bắt buộc khi active; tùy chọn khi pending, revoked)
    prev_token_hash?: 64 hex thường
    prev_token_expires_at?, expires_at?: timestamp
    version?: int >= 0
  200: { data: { agent_id, state, version } }

GET /servers/{id}/status?company_id=
  200: { data: { server_id, company_id, state: "online"|"down"|"unknown", last_seen,
                 agents![]: { agent_id, state, agent_version?, last_seen, down, down_since? },
                 latest![]: { metric, labels, ts_ms, value } } }
  404 nếu không có agent nào của máy chủ trong công ty.

GET /servers/{id}/series
  company_id!, metric! (trong catalog)
  from? (RFC3339 hoặc giây unix, mặc định to - 1 giờ), to? (mặc định hiện tại)
  step? ("5m" hoặc số giây), agg? (chuẩn hóa bởi tsdb.Query.Normalize)
  200: { data: { server_id, company_id, metric, agg, from, to, step_seconds,
                 series![]: { labels, points![]: [ts_ms, value] } } }

DELETE /servers/{id}/data?company_id=
  200: { data: { server_id, company_id, agents_removed, series_deleted: true } }

GET /companies/{id}/summary
  200: { data: { company_id, agents_total, online, offline } }

DELETE /companies/{id}/data
  200: { data: { company_id, agents_removed, series_deleted: true } }

GET /status
  200: { data: { collector_id, version, roles[], uptime_seconds, bus_depth,
                 outbox?: { depth, oldest_age_seconds, dead_letter },
                 agents: { total, online, down } } }

POST /reload/{kind}   kind in {rules, settings}
  202: { data: { reload, accepted: true } } (chưa có)

Lỗi: {"error": {"code": "...", "message": "..."}}.

5.3 Error codes ​

HTTPcodeKhi nào
400bad_requestID sai, body không phải JSON agent, agent_id lệch path, thiếu hoặc sai company_id, state hoặc băm sai, version âm, chỉ số ngoài catalog, thời gian, bước hoặc khoảng sai, khoảng quá 31 ngày
401unauthorizedThiếu hoặc sai token (kèm WWW-Authenticate: Bearer realm="collector-admin")
404not_foundĐường dẫn lạ (sau khi xác thực), kind reload lạ, máy chủ không có agent
405method_not_allowedSai phương thức (kèm Allow)
500server_errorKhông dựng được truy vấn
501not_implementedreload chưa hỗ trợ
503unavailableRegistry, TSDB hoặc reload lỗi tạm thời

Xác thực chạy trước kiểm phương thức, nên người chưa xác thực không thăm dò được đường dẫn (đường dẫn lạ vẫn đòi token trước khi trả 404).

5.4 Versioning ​

Đường dẫn mang phiên bản /internal/v1. Thay đổi phá vỡ thì tạo /internal/v2. Chưa có chính sách bảo trì đồng thời hai phiên bản (đề xuất ghi khi cần, OQ-ADM-4).

5.5 Authz ​

Chủ thểQuyền
Access Hub (giữ token admin)Tất cả 9 endpoint
Bất kỳ ai khácKhông có quyền (401)

Token admin là một bí mật dùng chung, không có phạm vi theo công ty: Access Hub phải tự bảo đảm company_id gửi sang khớp người dùng (xem 11).


6. Physical Data Schema ​

6.1 Mapping ​

Admin API không có kho dữ liệu riêng. Nó đọc và ghi qua các thành phần khác.

Thao tácKhoKhóa hoặc chuỗi
Đẩy, thu hồi agentRegistry (Redis hoặc bộ nhớ)reg:* (L3 Registry)
Trạng thái, tổng hợp, đếmPresencepres:*
Truy vấn, xóa dữ liệuVictoriaMetricsChuỗi ah_<tên> có nhãn company_id, server_id
CatalogTệp nhúng internal/catalog/metrics.yamlBản sao máy đọc được của catalog chỉ số phía agent: thêm chỉ số ở một nơi phải cập nhật cả hai, chỉ số thiếu sẽ bị bỏ ở ingest

6.2 Phân loại và lưu giữ ​

Dữ liệuPhân loạiLưu giữ
Token adminBí mậtTrong cấu hình (admin.token, admin.token_file, AHC_ADMIN_TOKEN); không vào log
Log thao tácTrung bìnhTheo hệ thống log (agent pushed, agent revoked, company data deleted, server data deleted)

7. Algorithms ​

7.1 Sequences (đường thành công) ​

Đẩy agent:

mermaid
sequenceDiagram
    participant HB as Access Hub (ext)
    participant AD as Admin API
    participant RG as Registry

    HB->>AD: PUT /agents/{id} (Bearer, JSON)
    AD->>AD: kiểm token, kiểm đầu vào
    AD->>RG: Put(FromRecord)
    RG-->>AD: OK
    AD-->>HB: 200 (agent_id, state, version)

Trạng thái máy chủ:

mermaid
sequenceDiagram
    participant HB as Access Hub (ext)
    participant AD as Admin API
    participant RG as Registry
    participant PS as Presence
    participant TS as TSDB

    HB->>AD: GET /servers/{id}/status?company_id=
    AD->>RG: ByServer(company, server)
    RG-->>AD: agents
    AD->>PS: Get(agent) cho từng agent
    AD->>TS: Latest(company, server, status_metrics)
    TS-->>AD: điểm mới nhất
    AD-->>HB: 200 (state, agents, latest)

7.2 Sequences (đường lỗi) ​

mermaid
sequenceDiagram
    participant HB as Access Hub (ext)
    participant AD as Admin API
    participant TS as TSDB

    HB->>AD: GET /servers/{id}/series
    alt token sai
        AD-->>HB: 401 unauthorized
    else tham số sai
        AD-->>HB: 400 bad_request
    else TSDB lỗi
        AD->>TS: Range
        TS--)AD: lỗi
        AD-->>HB: 503 unavailable
    end

7.3 State machines ​

API không giữ trạng thái. Vòng đời agent do Registry quản lý (xem L3 Registry mục 7.3). Admin chỉ kích hoạt các chuyển trạng thái:

Lời gọiChuyển trạng thái
PUT với state=activepending hoặc active đến active (phiên bản mới hơn)
PUT với state=revoked hoặc DELETEđến revoked (tombstone)
DELETE .../datađến không tồn tại (bản ghi bị xóa, chuỗi bị xóa)

7.4 Core algorithms ​

Vấn đềGiải phápTrade-off
Xác thực an toàn thời gianSo sánh băm SHA-256 của hai chuỗi bằng ConstantTimeCompareKhông lộ độ dài, nhưng token dùng chung
Không thăm dò đường dẫnXác thực trước định tuyến phương thức, đường dẫn lạ cũng đòi token
Trạng thái máy chủDuyệt agent active, lấy presence: down thắng, rồi online nếu lần thấy thật trong ngưỡngMáy chủ nhiều agent chỉ cần một down là down
Bộ chọn truy vấn an toàntsdb.CheckTenant và Query.Normalize tạo bộ chọn, ValidID chặn ký tự lạPhụ thuộc đúng đắn của adapter
XóaXóa registry trước, rồi TSDBLỗi giữa chừng để lại trạng thái nửa xóa, gọi lại xóa an toàn (idempotent)
Thu hồiGet rồi Revoke nếu có, luôn 204Không phân biệt agent không tồn tại với đã thu hồi
Giới hạn đọc bodyio.LimitReader(64 KiB) rồi giải mã JSONBody vượt 64 KiB bị cắt và lỗi giải mã thành 400, không báo lý do "quá lớn"

8. Error Handling ​

8.1 Bảng lỗi theo bước ​

Bước lỗiNguyên nhânCơ chế xử lýTrạng thái cuối
Xác thựcToken sai401, không ghi chi tiếtKhông đổi
Kiểm đầu vàoID, băm, state, thời gian sai400 với thông điệp cố địnhKhông đổi
RegistryRedis lỗi503 unavailable, log warn kèm op, request_idKhông đổi hoặc ghi dở (xem 10.1)
TSDBVictoriaMetrics lỗi503 unavailableKhông đổi
XóaRegistry xóa xong, TSDB lỗi503; agent đã xóa, chuỗi cònGọi lại xóa để hoàn tất
Truy vấnErrBadQuery400Không đổi
KhácLỗi dựng truy vấn500 server_errorKhông đổi

8.2 Fail-fast ​

  • admin.token ngắn hơn 24 ký tự khi bật vai trò admin thì collector không khởi động (mã thoát 3).
  • admin.listen rỗng thì lỗi cấu hình.
  • Thiếu thành phần phụ thuộc thì New trả lỗi (TestNewRejectsBadOptions).

8.3 Race conditions ​

Tình huốngXử lý
Hai PUT đồng thời cùng agentRegistry so sánh Version
DELETE agent trong lúc ingest tra tokenTombstone; cache nút có thể còn bản cũ tối đa cache_ttl
Xóa dữ liệu trong lúc worker đang ghiMẫu ghi sau lệnh xóa vẫn xuất hiện lại (không có khóa giữa xóa và ghi); Access Hub nên thu hồi agent trước khi xóa (đề xuất, OQ-ADM-3)

9. Degradation ​

Nguyên tắc: Admin lỗi không được ảnh hưởng đường ingest. Đây là mặt phẳng điều khiển, chấp nhận 503 khi phụ thuộc lỗi.

9.1 Dependency matrix ​

Dependency lỗiHành viKiểu suy thoáiHệ quả
RedisPUT, DELETE, trạng thái trả 503Từ chốiAccess Hub thử lại
VictoriaMetricsseries, status (phần latest), xóa trả 503Từ chốiGiao diện không có biểu đồ
Access Hub không gọi đượcCollector vẫn ingest bằng registry cacheKhông ảnh hưởngRegistry dần lệch cho đến khi đồng bộ (Syncer)
Presence lỗiTrả trạng thái thiếu hoặc unknownGiảm chức năng

9.2 Backup và recovery ​

API không giữ dữ liệu. Phục hồi dựa trên Registry và VictoriaMetrics. Xóa dữ liệu không hoàn tác; không có thùng rác. RTO và RPO chính thức: chưa định nghĩa (đề xuất, OQ-ADM-1).


10. Concurrency ​

10.1 Ranh giới giao dịch ​

Mỗi lời gọi là một thao tác độc lập; xóa theo công ty gồm hai bước (registry, rồi TSDB) không cùng giao dịch. Lỗi ở bước hai để lại trạng thái nửa xóa, gọi lại hoàn tất. Put Redis nhiều khóa: xem L3 Registry mục 10.1.

10.2 Cơ chế ​

Cơ chếMô tảMối nguy
http.ServeMux đồng thờiMỗi request một goroutineKhông có giới hạn tốc độ ở Admin (chỉ một client tin cậy, đề xuất thêm nếu mở rộng, OQ-ADM-5)
So sánh Version (Registry)Chống ghi đè cũ
io.LimitReaderChặn body lớnCắt im lặng (xem 7.4)
Xóa không khóa với ghiBia mộ purge (COL-11): ghi trước khi xóa, worker bỏ lô của tenant đã xóa, xóa TSDB lần hai sau 10 giâyWorker tách tiến trình thấy bia mộ chậm tới 2 giây, lần xóa thứ hai bù khoảng này

11. Security ​

11.1 Ba lớp ​

LớpBiện pháp
Truyền thôngListener riêng admin.listen (mặc định 127.0.0.1:9101, không công khai). Sản xuất: TLS hoặc mạng nội bộ đáng tin cậy, giới hạn nguồn truy cập ở tầng mạng (đề xuất, nội dung docs/09)
MãBearer token tối thiểu 24 ký tự, so sánh băm hằng thời gian; xác thực trước định tuyến; ID và băm kiểm định dạng; chỉ số phải có trong catalog; lỗi backend không lộ chi tiết
Dữ liệuToken từ tệp hoặc biến môi trường (AHC_ADMIN_TOKEN, admin.token_file), không có trong YAML trong repo; log thao tác không chứa token

11.2 Pipeline phân quyền năm bước ​

  1. Nhận request, đọc Authorization.
  2. Kiểm tiền tố Bearer , băm SHA-256, so sánh hằng thời gian với băm token cấu hình.
  3. Nếu sai: 401 kèm WWW-Authenticate, không thêm thông tin.
  4. Định tuyến và kiểm phương thức (405 kèm Allow).
  5. Kiểm đầu vào và company_id/ID hợp lệ, rồi mới chạm Registry, Presence hoặc TSDB.

Không có bước kiểm "người dùng này có quyền trên công ty này": niềm tin nằm hoàn toàn ở Access Hub giữ token.

11.3 Chỉ mục neo ​

Nguyên tắc L2Biện pháp nội bộ
NFR-12 cô lập tenantcompany_id bắt buộc, bộ chọn truy vấn và xóa luôn gắn công ty, ByServer theo công ty
9.1 danh tínhToken admin một bí mật duy nhất
9.3 secretsToken từ tệp hoặc biến môi trường

Rủi ro còn mở (để rà soát): (1) DELETE /agents/{id} không nhận company_id, nên agent ID toàn cục bị thu hồi chỉ bằng ID (chấp nhận được khi chỉ Access Hub giữ token, nhưng khác quy tắc "company_id bắt buộc"; OQ-ADM-2). (2) Token dùng chung, không xoay vòng và không có nhiều token (đề xuất). (3) Không có audit log riêng ngoài log chung.


12. Configuration ​

12.1 Tunables ​

Biến môi trường: AHC_ADMIN_LISTEN, AHC_ADMIN_TOKEN, AHC_ADMIN_TOKEN_FILE. Còn lại chỉ YAML.

Tham sốDefaultÝ nghĩa và tác độngMục liên quan
admin.listen127.0.0.1:9101Địa chỉ listener admin (bắt buộc khi có vai trò admin)3.1
admin.tokenrỗngToken Bearer, tối thiểu 24 ký tự11
admin.token_filerỗngĐọc token từ tệp (cắt khoảng trắng hai đầu), chỉ dùng khi token rỗng11
rolesallPhải chứa admin (hoặc all) để bật API3.1
alerting.agent_interval, alerting.down_min30 giây, 90 giâyXác định ngưỡng online (cùng công thức với Detector)7.1
tsdb.url, tsdb.timeoutxem L3 Bus, Worker, TSDBTruy vấn và xóa7.1

Hằng số cố định: body 64 KiB, khoảng truy vấn tối đa 31 ngày (400 ngày khi cấu hình có tsdb.long_url), from mặc định to - 1 giờ.

12.2 Feature flags ​

Không có. Vai trò admin bật hoặc tắt toàn bộ API. POST /reload/rules đã nối (COL-8), settings là điểm mở rộng chưa nối.


13. Telemetry ​

13.1 Metrics ​

Admin API chưa có metric riêng (theo danh sách metric đã xác minh trong mã; không có ahc_admin_*). Có các metric chung ahc_build_info, ahc_uptime_seconds, ahc_goroutines. Đề xuất: bổ sung ahc_admin_requests_total{endpoint,code} và ahc_admin_request_duration_seconds{endpoint} (OQ-ADM-6).

13.2 Log schema ​

JSON một dòng: time, level, msg, request_id, collector_id.

msgMứcTrường
agent pushedinforequest_id, agent_id, company_id, state
agent revokedinforequest_id, agent_id, company_id
server data deletedwarnrequest_id, company_id, server_id, agents
company data deletedwarnrequest_id, company_id, agents
admin backend errorwarnop, request_id, err

Không ghi token hay băm token.

13.3 Cảnh báo đến runbook ​

Chưa có luật. Đề xuất: tỷ lệ 401 tăng đột biến (dò token), 503 kéo dài, mọi lần xóa dữ liệu công ty (thông báo cho quản trị). Runbook: docs/09 mục 6.

13.4 Probes ​

/healthz và /readyz được phục vụ trên listener admin (xem 3.1). /readyz kiểm "redis" và "tsdb".

13.5 Trace propagation ​

X-Request-Id: nhận từ request hoặc sinh mới (httpx.RequestID), trả về trong header và ghi vào log. Chưa có trace phân tán.


14. Test Plan ​

LoạiKiểm thửVị trí
Xác thực, định tuyếnTestAuthRequiredEverywhere, TestNewRejectsBadOptions, TestRoutingErrorsinternal/admin/admin_test.go
AgentTestPutAndRevokeAgent, TestPutAgentValidationinternal/admin/admin_test.go
ReloadTestReloadinternal/admin/admin_test.go
ĐọcTestServerStatusAndSummary, TestSeriesQuery, TestStatusinternal/admin/admin_test.go
XóaTestDeleteDataIsTenantScopedinternal/admin/admin_test.go
CatalogTestDefault, TestEveryDefaultNameIsValid, TestParseRejectsUnknownStatusMetricinternal/catalog/catalog_test.go
Tích hợpTestTwoTenantIsolationThroughIngestAndAdminAPI, TestRoleGatingListeners, TestSilentAgentGoesDownThenUpAtAccessHubinternal/app
Chưa cóKiểm thử bảo mật thăm dò thời gian, kiểm thử tải Admin, xóa trong lúc ghi, kiểm thử hợp đồng với Access Hub thật

Bản nháp này không chạy kiểm thử.


15. Implementation Sequence ​

15.1 Milestone matrix ​

MilestoneNội dungPhụ thuộcĐóng góp nghiệm thu
COL-7API admin: đẩy registry, trạng thái, series (giá trị mới nhất), kiểm thử hai tenant qua ingest và adminCOL-3, COL-5AC-ADM-01..08
COL-8Reload luật thật (/reload/rules), GET /status có mục rules. settings chưa làmCOL-7AC-ADM-09
COL-10 (xong 2026-10-01)Rollup, API series tự chọn nguồn, khoảng tối đa 400 ngày khi có vm-long, cắt theo retention của gói (metrics_retention_days), step_seconds là bước thực dùng, /reload/settings xóa cache gói và báo worker qua RedisCOL-7AC-ADM-06, 07
COL-11 (xong 2026-10-01)Purge có bia mộ ghi trước, xóa TSDB lần hai sau 10 giây, worker bỏ lô và quên trạng thái tenant; giới hạn series theo công ty ở ingestCOL-7AC-ADM-08, TestPurgeWritesATombstoneFirstAndDeletesTwice, TestPurgeDropsSamplesInFlightAndForgetsAlerts
HUB-14 (chưa xây, đặc tả ở docs/06 mục 8.1)Access Hub gọi purge Server và CompanyCOL-11Đầu cuối
Metric Admin (đề xuất)ahc_admin_*COL-7Telemetry
Nhiều token hoặc xoay token (đề xuất)COL-7Bảo mật

Tên lấy từ docs/11-roadmap.md. Lệch tài liệu: roadmap xếp purge dữ liệu (COL-11) vào giai đoạn 2, chưa làm, nhưng mã đã có DELETE /servers/{id}/data và DELETE /companies/{id}/data (kèm TestDeleteDataIsTenantScoped). Mã thắng: roadmap cần cập nhật (OQ-ADM-7). Đã đóng ở COL-11 (2026-10-01): roadmap ghi phần bổ sung (bia mộ, xóa lần hai, quên trạng thái).

15.2 Dependency flowchart ​

mermaid
flowchart LR
    C3["COL-3 registry"] --> C7["COL-7 admin API"]
    C5["COL-5 adapter VM"] --> C7
    C7 --> C8["COL-8 reload luật (xong)"]
    C7 --> C10["COL-10 rollup (xong)"]
    C7 --> MT["metric admin (đề xuất)"]

Appendix A. Open Questions ​

#Câu hỏiHành vi tạm thờiOwnerMã theo dõi
1RTO và RPO cho API và xóa dữ liệuChưa định nghĩaChưa chỉ địnhOQ-ADM-1
2DELETE /agents/{id} có cần company_id để khớp quy tắc tenantChỉ theo IDChưa chỉ địnhOQ-ADM-2
3Quy trình xóa an toàn (thu hồi agent trước, chặn ghi, rồi xóa)Xóa không khóaChưa chỉ địnhOQ-ADM-3
4Chính sách phiên bản /internal/v1 và v2Chưa cóChưa chỉ địnhOQ-ADM-4
5Giới hạn tốc độ AdminKhông cóChưa chỉ địnhOQ-ADM-5
6Bổ sung metric ahc_admin_*Không cóChưa chỉ địnhOQ-ADM-6
7Cập nhật roadmap: DELETE .../data đã có trong mã nhưng COL-11 ghi chưa làmMã là nguồn sự thậtChưa chỉ địnhOQ-ADM-7
8Nhiều token admin, xoay tokenMột tokenChưa chỉ địnhOQ-ADM-8
9Presence có bị xóa khi DeleteServer hoặc DeleteCompany không (Redis: xác minh hook)Chưa xác minhTác giả L3OQ-ADM-9
10Nguồn đồng bộ ConfigFor và cài đặt theo công tyLuật đã xong, phần này chưa làmChưa chỉ địnhOQ-ADM-10

Appendix B. ADR nội bộ ​

Mã ADRQuyết địnhTrạng tháiDriver
ADR 0007Access Hub là nguồn sự thật agent, đẩy sang CollectorChấp nhậnTách control và data plane
ADR nội bộ (đề xuất)Một token admin dùng chung, so sánh băm hằng thời gianĐề xuất, là hành vi mãĐơn giản cho một client tin cậy
ADR nội bộ (đề xuất)Xác thực trước định tuyến, 404 cũng đòi tokenĐề xuất, là hành vi mãKhông thăm dò đường dẫn
ADR nội bộ (đề xuất)DELETE /agents idempotent, luôn 204Đề xuất, là hành vi mãThử lại an toàn
ADR nội bộ (đề xuất)company_id bắt buộc qua tham số truy vấn cho mọi thao tác theo máy chủĐề xuất, là hành vi mãNFR-12

Appendix C. Section Profile ​

Phân mụcHồ sơTrạng thái điềnGiải trình
0 đến 4Bắt buộcĐã điền
5 API contractBắt buộcĐã điềnLấy trực tiếp từ admin.go
6 Physical dataBắt buộcĐiền (không có kho riêng)Admin không có dữ liệu riêng
7.1 đến 7.4Bắt buộcĐã điền
8, 9, 10, 11, 12Bắt buộcĐã điền
13 TelemetryBắt buộcĐiền một phầnChưa có metric riêng (OQ-ADM-6)
14, 15Bắt buộcĐã điềnRoadmap lệch mã ở purge (OQ-ADM-7)
Trang này có giúp được bạn không?
Sửa trang này

Nội dung đồng bộ từ kho mã access-hub-collector lúc 10:57, 03/10/2026. Khi tài liệu và mã khác nhau, mã thắng.