Chuyển tới nội dung chính

Danh mục phần mềm thượng nguồn và giấy phép

Tài liệu này làm rõ mọi thư viện, gói và phần mềm thượng nguồn mà Signet phụ thuộc vào — yêu cầu bắt buộc theo tiêu chí chấm điểm PoF #5 ("Có thông tin làm rõ các thư viện, gói đính kèm được sử dụng").

Tệp này ghi vì sao: nguyên tắc thêm phụ thuộc, lý do chọn từng thành phần, chính sách giấy phép, các gói kéo theo có giấy phép cần giải thích và các thành phần đã cân nhắc nhưng không dùng. Bảng gọn của các thành phần dùng trực tiếp (tên, phiên bản, giấy phép, mô tả, trang chủ) nằm ở COPYRIGHT.txt, sinh từ các bảng "Thành phần" dưới đây bằng make copyright; scripts/tests/test_copyright_txt.py báo đỏ khi hai tệp lệch nhau.

Nguyên tắc phụ thuộc​

  1. Không bundle. Kho mã nguồn này không chứa bản sao mã nguồn của bất kỳ dự án nào khác. Mọi phần mềm thượng nguồn được nạp lúc chạy qua image Docker chính thức có ghim thẻ phiên bản và digest, hoặc qua trình quản lý gói (npm, pip) với tệp khóa phiên bản (lockfile).
  2. Không chỉnh sửa upstream. Mã nguồn của các dự án thượng nguồn được dùng ở dạng nguyên bản. Mọi tùy biến của Signet nằm ở lớp cấu hình, plugin hoặc adapter riêng.
  3. Ưu tiên thư viện sẵn có của hệ thống thay vì đóng gói kèm bản riêng.
  4. Kiểm tra tương thích giấy phép. Mọi thành phần mới phải có giấy phép được OSI phê duyệt và tương thích với Apache-2.0 của Signet. Ngoại lệ chỉ khi ghi ở mục Kiểm tra tương thích giấy phép, kèm lý do và phạm vi: giấy phép dễ dãi tương đương một giấy phép OSI (PSF-2.0 là phần đầu của Python-2.0; MIT-CMU là một dạng HPND), hoặc dữ liệu, công cụ chỉ chạy lúc dựng (CC-BY-4.0, CC0-1.0). Không thành phần nào, kể cả tùy chọn, được đòi phần mềm nguồn đóng (#452). Ngoại lệ có ghi là bản online của đội: bước viết câu trả lời gọi một mô hình đóng qua API mở chuẩn OpenAI (#430, mục Dịch vụ quanh dự án bên dưới); gói phát hành và bản tự cài không cần mô hình đó.

Cách đọc​

  • Thành phần dẫn tới trang chủ của dự án. Vế đầu của cột Vai trò (tới dấu :, ; hay ngoặc đầu tiên) thành cột Mô tả của COPYRIGHT.txt, nên viết vế đó thành một cụm tự đứng được.
  • Phiên bản ghim: thành phần đã chạy (Phase 1) ghi đúng thẻ trong docker-compose.yml — cập nhật 18/10/2026; thành phần phase sau là bản ổn định mới nhất tại 09/10/2026, chốt lại khi đưa vào. Chỉ chọn bản đã phát hành ít nhất hai tuần.
  • Ngoại lệ vá bảo mật: bản đang ghim có lỗ hổng đã công bố (OSV-Scanner trong CI báo) mà bản vá chưa đủ hai tuần thì dùng bản vá ngay, ghi ở đây. 22/10/2026: Pillow 13.0.0 (PyPI 16/10, vá các GHSA của 12.3.0) và pypdf 6.21.1 (17/10, vá 5 GHSA của 6.19.0) — cả hai đọc tệp người dùng tải lên (svc-files); certifi 2026.10.19 (20/10, bỏ gốc emSign có CA trung gian lộ khóa, GHSA-6q48-6c7w-9gw2). 23/10/2026: brotli 1.2.1 và brotlicffi 1.2.1.0 (22/10, vá lỗi ghi tràn bộ nhớ trong bộ giải nén, PYSEC-2026-4322, PYSEC-2026-4323, CRITICAL) — gói kéo theo của fontTools mà WeasyPrint dùng trong svc-files. 24/10/2026: pypdf 6.21.2 (21/10, vá GHSA-6c7f-9265-g8fw, GHSA-gmh7-3g9r-mjh5, GHSA-jr96-gvgh-j3r4, HIGH: PDF dị dạng làm chạy rất lâu); serialize-javascript 7.1.3 (22/10, GHSA-m5mm-p8h7-m29v) và fast-uri 3.1.9 (19/10, bốn GHSA mức LOW/MODERATE) — gói kéo theo khi dựng apps/office, chọn đúng bản vá chứ không lấy bản mới hơn (serialize-javascript 7.1.4 ra 23/10). 27/10/2026: cùng serialize-javascript 7.1.3 cho trang tài liệu (website/, #349). 28/10/2026: plugin oauth của DokuWiki, commit b709c33 (21/10) cho wiki nội bộ (#367): bản trước commit 3a1666c (18/10, "fix(security): sign the login cookie") không ký cookie đăng nhập, ai biết email của một người làm được cookie đăng nhập thay người đó; b709c33 thêm bản sửa kèm theo (bỏ cookie bị từ chối trước khi DokuWiki đọc). Tác giả không công bố mã GHSA, OSV-Scanner không đọc plugin tải trong Dockerfile. 31/10/2026 (#461): pypdf 6.21.4 (28/10) trong svc-files, vá bảy GHSA công bố 30/10 (PDF cố tình làm hỏng gây vòng lặp vô hạn hay ngốn bộ nhớ); nuxt 4.6.3 (27/10, vá GHSA-9v7c-q64q-vv33 và ba GHSA của máy chủ phát triển) và node-forge 1.4.1 (27/10, mười một GHSA) cho apps/office, joi 17.13.9 (28/10, GHSA-4528-x5fx-h6hg) cho website/, đều chỉ chạy lúc dựng. Khóa npm sinh lại với npm install --package-lock-only --before=<giờ ra bản vá>, nên không gói kéo theo nào mới hơn bản vá; lần sinh lại này đưa serialize-javascript của apps/office lên 7.1.4 (23/10), website/ vẫn ép 7.1.3.
  • Digest: image bên thứ ba trong docker-compose.yml, các Dockerfile và image Playwright của make e2e ghi dạng thẻ@sha256:…. Docker kéo theo digest (bản đã chạy CI), thẻ chỉ để người đọc: thẻ bị đẩy lại (postgres:16-alpine, python:3.13.16-slim, clamav/clamav:1.5.4 đã bị đẩy lại sau khi đội kéo) thì máy mới vẫn chạy đúng bản đã kiểm. Nâng phiên bản thì đổi cả hai: digest lấy bằng docker buildx imagetools inspect <thẻ> (dòng Digest:, là index đa nền tảng).
  • Phase: thời điểm thành phần được đưa vào, theo docs/du-thi/ke-hoach-phat-trien.md. Thành phần đánh dấu Could chỉ được thêm nếu còn thời gian.
  • Copyleft (GPL, AGPL): chỉ dùng ở dạng dịch vụ độc lập giao tiếp qua mạng, không liên kết vào mã của Signet, nên giấy phép của chúng không lan sang Signet.

Công cụ dựng và vận hành​

Thành phầnPhiên bảnGiấy phépVai tròCách nạp
Docker Engine≥ 24.0Apache-2.0Đóng gói và chạy containerCài sẵn trên máy chủ
Docker Compose v2≥ 2.17Apache-2.0Điều phối đa dịch vụPlugin của Docker
Caddy≥ 2.6Apache-2.0Proxy TLS trên máy chủ: HTTPS, chứng thư Let's Encrypt tự gia hạn (docs/trien-khai.md); không nằm trong ComposeGói hệ thống của máy chủ (apt install caddy)
Python≥ 3.10PSF-2.0Chạy make seed, make smoke (chỉ thư viện chuẩn)Gói hệ thống
Node.js24.20.0MITDựng giao diện thành trang tĩnh, cài gói npm của app-ca-nhan, app-bang-tin, app-nghi-phep, app-lich-giang, app-sinh, app-tai-lieu-api và phông của theme đăng nhập (chỉ ở bước dựng image); image moc/keycloak-fonts (#305) dựng trên image này, chạy một lần mỗi lần up để chép phông vào volume (chỉ sh và lệnh chép, không chạy Node); chạy test apps/ca-nhan/tests, apps/bang-tin/tests, apps/nghi-phep/tests, apps/sinh/testsnode:24.20.0-slim
Playwright1.63.0Apache-2.0Kiểm thử trên trình duyệt thật — make e2e, tests/e2e/mcr.microsoft.com/playwright:v1.63.0-noble
axe-core, @axe-core/playwright4.13.0MPL-2.0Kiểm trợ năng tự động theo WCAG 2.0, 2.1 mức A, AA trong e2e (tests/e2e/tro-nang.spec.ts, #246); chỉ dùng trong test, dùng nguyên bản, không vào gói phát hànhnpm, tests/e2e/package-lock.json
GNU Make≥ 4.0GPL-3.0+Điều phối lệnh (công cụ dựng, không liên kết vào sản phẩm)Gói hệ thống
Git≥ 2.30GPL-2.0Quản lý mã nguồn, sinh gói phát hànhGói hệ thống
uv0.12.19Apache-2.0 / MITCài thư viện test theo băm và chạy make test, test db/tests/Tệp chạy độc lập
actionlint1.7.12MITKiểm cú pháp và lỗi thường gặp trong .github/workflows/ (CI)rhysd/actionlint:1.7.12
gitleaks8.30.1MITQuét bí mật lộ trong toàn bộ lịch sử commit (CI)ghcr.io/gitleaks/gitleaks:v8.30.1
OSV-Scanner2.6.0Apache-2.0Đối chiếu tệp khóa phụ thuộc với cơ sở dữ liệu lỗ hổng OSV (CI)ghcr.io/google/osv-scanner:v2.6.0
REUSE tool5.0.2GPL-3.0-or-laterKiểm mọi tệp đều có thông tin bản quyền và giấy phép theo chuẩn REUSE (REUSE.toml); chạy tay, chỉ đọc khouvx --from reuse==5.0.2 reuse lint
Syft1.54.1Apache-2.0Sinh SBOM CycloneDX của cây mã nguồn (make sbom, CI, bản phát hành) từ tệp khóa npm, requirements*.txt, action CI; đầu vào của make license-audit; chỉ đọc kho, hỏi PyPI giấy phép gói Pythonghcr.io/anchore/syft:v1.54.1 (image 06/10/2026)
Chromiumbản có --headless=newBSD-3-ClauseChỉ khi sửa sơ đồ kiến trúc của README: chụp từng khung SVG (python3 scripts/so_do_kien_truc.py gif); không thuộc sản phẩm, không chạy trong CIGói hệ thống
FFmpeg≥ 6.0LGPL-2.1-or-later (GPL-2.0-or-later tùy bản dựng)Chỉ khi sửa sơ đồ kiến trúc: ghép các khung thành GIF với một bảng màu chung; gọi như tiến trình độc lậpGói hệ thống

Ghi chú tương thích: Make và Git là công cụ dựng, được gọi như tiến trình độc lập và không liên kết vào sản phẩm, nên giấy phép GPL của chúng không lan sang Signet. Cả hai đều là phần mềm nguồn mở — Signet không dùng bất kỳ công cụ nguồn đóng hay tự chế nào để dựng (tiêu chí PoF #4). CI trên GitHub Actions chỉ gọi lại đúng các lệnh make ở trên, nên dựng và kiểm thử trên máy riêng không cần GitHub.

Trang tài liệu (website/)​

Trang tài liệu (#308) dựng thẳng từ docs/ và các README thành trang tĩnh, đăng lên GitHub Pages. Không thuộc sản phẩm: bản cài của Signet không chạy, không phục vụ trang này. Gói npm nạp theo website/package-lock.json.

Thành phầnPhiên bảnGiấy phépVai trò
Docusaurus (@docusaurus/core, preset-classic, theme-mermaid, utils)3.10.2MITDựng trang từ tệp .md (đọc như CommonMark), mục lục, sơ đồ Mermaid
React, React DOM19.2.8MITGiao diện của trang (qua Docusaurus)
Mermaid12.2.0MITVẽ sơ đồ Mermaid của docs/architecture.md (qua @docusaurus/theme-mermaid)
@easyops-cn/docusaurus-search-local0.55.3MITTìm kiếm: chỉ mục dựng sẵn lúc build, tìm ngay trong trình duyệt (lunr, lunr-languages có tiếng Việt), không gọi dịch vụ ngoài
Be Vietnam Pro (@fontsource/be-vietnam-pro)5.3.0OFL-1.1Phông của trang, cùng phông giao diện ứng dụng; tự phục vụ, không gọi CDN. Bản dựng kèm fonts/be-vietnam-pro/OFL.txt lấy từ gói

Quét website/package-lock.json ngày 30/10/2026: 1304 gói khác nhau. Ngoài danh sách giấy phép được nhận chỉ có bốn gói, cùng bốn gói tệp khóa không ghi giấy phép; đều có ngoại lệ ghi lý do trong .github/license-exceptions.json (caniuse-lite dùng chung với ứng dụng web, ghi ở mục Tầng 2):

GóiGiấy phépKéo theo bởiGhi chú
argparsePython-2.0js-yamlBộ giấy phép dễ dãi của Python, SPDX ghi OSI phê duyệt. Chỉ chạy lúc dựng
elkjsEPL-2.0MermaidCopyleft yếu theo từng tệp, OSI phê duyệt; dùng nguyên bản, không sửa, nên không lan sang mã của Signet. Nằm trong JS của trang; mã nguồn ở kieler/elkjs
robust-predicatesUnlicensed3-delaunay (qua Mermaid)Đưa mã vào phạm vi công cộng, OSI phê duyệt
mdn-data (2.0.28, 2.0.30)CC0-1.0css-tree (qua csso, svgo: nén CSS, SVG lúc dựng)Dữ liệu cú pháp CSS của MDN. CC0 đưa tác phẩm vào phạm vi công cộng, không thuộc danh sách OSI. Chỉ đọc lúc dựng; ứng dụng web không còn gói này từ #322
eval, require-like, format, khromaMITDocusaurus, Mermaidpackage.json không khai giấy phép hay khai bằng trường licenses kiểu cũ; tệp LICENSE trong gói là MIT

lunr-languages (MPL-1.1, copyleft yếu) dùng nguyên bản cho tìm kiếm tiếng Việt. Gói cho chọn giấy phép thì Signet dùng theo MIT: opener 1.5.2 (webpack-bundle-analyzer) và path-is-inside 1.0.2 (serve-handler) là WTFPL OR MIT, type-fest 1.4.0 và 2.19.0 (boxen; chỉ có kiểu TypeScript) là MIT OR CC0-1.0; đều chỉ chạy lúc dựng hay xem thử trang. WTFPL và CC0 không thuộc danh sách OSI nên lựa chọn này ghi ra đây.

Ba gói kéo theo có lỗ hổng mà gói cha còn ghim dải cũ được ép lên bản vá bằng overrides trong website/package.json (#349); cả ba chỉ chạy lúc dựng hay ở máy chủ phát triển, không có trong trang đăng lên. Gói cha nâng dải thì bỏ mục tương ứng.

GóiBản épGói cha ghimGhi chú
serialize-javascript7.1.3copy-webpack-plugin, css-minimizer-webpack-plugin: ^6Hai plugin gọi serialize(obj), 7.x vẫn xuất hàm CommonJS đó. Ngoại lệ vá bảo mật, xem mục Cách đọc
tinypool2.1.2@docusaurus/core 3.10.2: ^1Docusaurus chỉ nạp khi bật future.faster.ssgWorkerThreads; trang không bật. Muốn bật thì dựng thử trước
uuid (chỉ dưới sockjs)11.1.1sockjs 0.3.24 (máy chủ của npm start): ^8.3.2sockjs gọi require('uuid').v4, 11.x còn bản CommonJS

Tầng 1 — Lõi nền tảng​

Thành phầnPhiên bản ghimGiấy phépVai tròCách nạpPhase
Keycloak26.7.5Apache-2.0Định danh tập trung: SSO, MFA, vai trò người dùngquay.io/keycloak/keycloak:26.7.5, nguyên bản; theme đăng nhập signet gắn từ repo, phông của theme do dịch vụ chạy một lần keycloak-fonts (platform/keycloak/fonts/, #305) chép từ gói npm vào volume1
Apache APISIX3.18.0Apache-2.0Cổng API: cửa duy nhất ra Internet, kiểm JWT tại biên, giới hạn tốc độapache/apisix:3.18.0-debian, dựng thành moc/apisix chỉ thêm tệp WAF (platform/apisix/Dockerfile, F3.15)1
PostgreSQL16PostgreSQL LicenseCơ sở dữ liệu quan hệ chính (QĐ-002)postgres:16-alpine1
Hasura GraphQL Engine (CE)v2.51.0Apache-2.0Tự sinh API GraphQL, phân quyền cấp dòng, Actions, Event Triggers (luồng core.app_events tới webhook của ứng dụng cài bằng moc app install; hasura-cli có sẵn trong image áp metadata trộn)hasura/graphql-engine:v2.51.0-ce.cli-migrations-v31
PostgRESTv14.18MITAPI REST /rest/v1 tự sinh từ schema sinh (bảng tạo trong Studio); quyền theo GRANT và RLS của khung sinh_khung, token Keycloak kiểm bằng JWKS do rest-init ghi ra tệp (#566)postgrest/postgrest:v14.184
Supabase Studio2026.10.12Apache-2.0Trình tạo bảng, cột cho người vận hành nền tảng (profile studio, chỉ nghe 127.0.0.1, không qua APISIX); nối CSDL bằng vai trò moc_studio, tắt telemetry và trợ lý AI (#566)supabase/studio:2026.10.12-sha-36992784
postgres-metav0.100.0Apache-2.0API quản lý schema mà Studio gọi (profile studio), nối bằng vai trò moc_studio (#566)supabase/postgres-meta:v0.100.04
Flowable (REST)8.0.0Apache-2.0Động cơ quy trình BPMNflowable/flowable-rest:8.0.01
SeaweedFS4.48Apache-2.0Lưu trữ đối tượng chuẩn S3chrislusf/seaweedfs:4.481
ClamAV1.5.4GPL-2.0Quét mã độc tệp tải lên (dịch vụ độc lập)clamav/clamav:1.5.41
Meilisearch (Community Edition)v1.54.3MITTìm kiếm toàn văn; chỉ mục đoạn chunks của trợ lý hỏi đáp (F4.2): tìm lai từ khóa + véc-tơ trong bản CE, embedder userProvided (véc-tơ do svc-files tính bằng Ollama, Meilisearch không gọi mô hình nào, không vào mạng ai)getmeili/meilisearch:v1.54.31
nginx (unprivileged)1.30.6BSD-2-ClausePhục vụ trang tĩnh của app-office, app-ca-nhan sau APISIXnginxinc/nginx-unprivileged:1.30.6-alpine1
Centrifugov6.9.7Apache-2.0Đẩy thông báo thời gian thực qua WebSocketcentrifugo/centrifugo:v6.9.72

Ghi chú:

  • Hasura: bắt buộc dùng thẻ -ce. Thẻ không có hậu tố -ce chứa thành phần Enterprise độc quyền.
  • Meilisearch: chỉ dùng getmeili/meilisearch, bản community (MIT). Từ khi có Enterprise Edition, kho nguồn ghi SPDX-License-Identifier: MIT AND BUSL-1.1: phần BUSL-1.1 là các module enterprise_edition, chỉ biên dịch khi bật feature enterprise (#[cfg(feature = "enterprise")] trong crates/meilisearch-types/src/lib.rs và crates/index-scheduler/src/scheduler/mod.rs). Workflow publish-docker-images.yml của v1.54.3 dựng getmeili/meilisearch với edition community, không thêm --features enterprise; bản có cờ đó đăng riêng thành getmeili/meilisearch-enterprise, Signet không dùng. Kiểm 31/10/2026.
  • Centrifugo: chỉ dùng bản mã nguồn mở. Bản PRO là phần mềm thương mại.
  • Flowable: từ bản 7 chỉ còn bản REST, không có giao diện — phù hợp yêu cầu "lõi không giao diện".

Tầng 2 — Ứng dụng web​

Thư viện được cài qua npm với package-lock.json; phiên bản dưới đây là dòng chính đang dùng.

Thành phầnPhiên bảnGiấy phépVai tròCách nạpPhase
Nuxt4.6.3MITKhung ứng dụng web (chế độ SPA, dựng thành trang tĩnh)npm1
Vue3.5MITThư viện giao diện (qua Nuxt)npm1
oidc-client-ts3.5.0Apache-2.0Đăng nhập OIDC (Authorization Code + PKCE) với Keycloak; app-ca-nhan, app-bang-tin, app-nghi-phep, app-lich-giang, app-sinh, app-tai-lieu-api dùng bản dựng sẵn cho trình duyệt của cùng gói (dist/browser/oidc-client-ts.min.js, đã gồm jwt-decode 4.0.0, MIT) — không thêm gói nàonpm1
Swagger UI (swagger-ui-dist)5.33.2Apache-2.0Trang Tài liệu API /tai-lieu-api/ (app-tai-lieu-api, #357): đọc và gọi thử API lõi, API Văn phòng điện tử từ OpenAPI. Dùng nguyên swagger-ui-bundle.js, swagger-ui.css của gói, kèm LICENSE, NOTICE; bản dựng sẵn đã gồm các thư viện swagger-ui dùng: React, Redux, Immutable và đa số còn lại MIT, swagger-client Apache-2.0, DOMPurify MPL-2.0 hoặc Apache-2.0, sha.js, ieee754 BSD-3-Clause, zenscroll Unlicense (đều được OSI phê duyệt). Gói kéo theo @scarf/scarf 1.4.0 (Apache-2.0), chỉ có bước postinstall gửi số liệu sử dụng: cài bằng npm ci --ignore-scripts nên không chạy, không vào image. Trang không gọi CDNnpm, ghim trong package-lock.json của apps/tai-lieu-api3
vue-i18n11.4.14MITSong ngữ Việt / Anhnpm1
Tailwind CSS (+ @tailwindcss/vite)4.3.3MITĐịnh dạng giao diệnnpm1
Ajv8.20.0MITBiên dịch JSON Schema dùng chung (schemas/) thành mã kiểm form lúc dựng; chỉ dùng lúc dựng, không vào bundlenpm2
Apache ECharts6.1.0Apache-2.0Biểu đồ dashboard điều hành (F3.11), chỉ nạp biểu đồ cột, vẽ SVG. Kéo theo zrender 6.1.0 (BSD-3-Clause) và tslib 2.3.0 (0BSD), cùng nằm trong bundlenpm3
Be Vietnam Pro (@fontsource/be-vietnam-pro)5.3.0 (phông 1.002)OFL-1.1Phông giao diện của nhận diện Liền mạch (#116), đủ dấu tiếng Việt. Bốn độ đậm 400, 500, 600, 700, kiểu thường; gói chia mỗi độ đậm theo bộ ký tự latin, latin-ext, vietnamese (tệp woff2, woff, CSS có unicode-range), dùng nguyên như gói phát hành, kèm giấy phép của gói (OFL.txt); trình duyệt tải từ chính máy chủ, không gọi Google Fonts. Repo không chứa tệp phông nào (#305)npm, ghim trong package-lock.json của apps/office (Vite đưa vào /_nuxt/), apps/ca-nhan và platform/keycloak/fonts (image keycloak-fonts chép vào volume keycloak_fonts, Keycloak gắn vào themes/signet/login/resources/fonts/be-vietnam-pro/)3

Thư viện gián tiếp (khoảng 650 gói, đều chỉ dùng lúc dựng; trang phát hành chỉ còn tệp JS/CSS tĩnh) mang giấy phép MIT, ISC, Apache-2.0, BSD-2/3-Clause, BlueOak-1.0.0, MPL-2.0 hoặc 0BSD, đều được OSI phê duyệt. Quét package-lock.json ngày 30/10/2026, ngoài danh sách đó chỉ có bốn gói dưới đây. Không gói nào trong số này nằm trong trang phát hành (đã tìm trong thư mục trang tĩnh của image app-office).

GóiGiấy phépKéo theo bởiGhi chú
caniuse-liteCC-BY-4.0browserslist, autoprefixerBảng dữ liệu trình duyệt nào hỗ trợ tính năng nào, chỉ đọc lúc dựng CSS. CC-BY-4.0 là giấy phép mở cho dữ liệu, không thuộc danh sách OSI (OSI chỉ duyệt giấy phép phần mềm)
@speed-highlight/coreCC0-1.0youch (trang báo lỗi của máy chủ phát triển Nuxt)Chỉ chạy lúc phát triển
node-forgeBSD-3-Clause OR GPL-2.0listhen (máy chủ phát triển của Nuxt)Gói cho chọn giấy phép, Signet dùng theo BSD-3-Clause. Chỉ chạy lúc phát triển
type-festMIT OR CC0-1.0dot-propChỉ có kiểu TypeScript, Signet dùng theo MIT

Quét lại: python3 -c "import json,collections;p=json.load(open('apps/office/package-lock.json'))['packages'];print(collections.Counter(v.get('license') for k,v in p.items() if k))", hoặc kiểm cả gói npm lẫn Python theo chính sách bằng make sbom && make license-audit (mục cuối).

Ghi chú: BTC gợi ý "Nuxt 3 / Vue 3". Signet dùng Nuxt 4 (vẫn chạy trên Vue 3) vì đây là dòng chính hiện tại; dòng Nuxt 3 chỉ còn nhận bản vá bảo trì. Dùng vue-i18n trực tiếp thay cho @nuxtjs/i18n: ứng dụng chạy hoàn toàn trên trình duyệt, không cần định tuyến theo ngôn ngữ. Nhận thông báo từ Centrifugo bằng WebSocket có sẵn của trình duyệt (app/composables/useRealtime.ts, theo giao thức JSON công khai của Centrifugo), không dùng thư viện centrifuge: nó kéo theo protobufjs (có script chạy lúc cài) và hơn chục gói khác, trong khi giao diện chỉ cần nhận tin.

Dịch vụ tự viết (services/)​

Thư viện Python cài qua pip với tệp khóa phiên bản.

Thành phầnPhiên bảnGiấy phépVai tròCách nạpPhase
FastAPI0.143MITKhung viết svc-files, svc-workflow (kéo theo Starlette, Pydantic — BSD-3, MIT)pip1
uvicorn0.54BSD-3-ClauseMáy chủ ASGI chạy các dịch vụpip1
httpx2 (+ httpcore2, truststore)2.13BSD-3-Clause (truststore: MIT)Gọi Hasura, Flowable, Keycloak, Meilisearchpip1
python-multipart0.0.32Apache-2.0Đọc tệp tải lên (svc-files)pip1
boto31.43Apache-2.0Gọi SeaweedFS qua giao thức S3 (svc-files)pip1
PyJWT (+ cryptography)2.15 · 50.0MIT (cryptography: Apache-2.0 / BSD)Kiểm JWT Keycloak trong svc-files và ở API quy trình cho ứng dụng của svc-workflow (/api/workflow); mã hóa con trỏ trang tìm kiếmpip1
WeasyPrint (+ pydyf, tinycss2, cssselect2, tinyhtml5, webencodings)70.0BSD-3-Clause (tinyhtml5: MIT)Dựng PDF văn bản đi đúng thể thức NĐ 30 từ khuôn HTML (svc-files)pip2
fontTools (+ Brotli, zopfli)4.66MIT (zopfli: Apache-2.0)Nhúng và nén phông vào PDF (WeasyPrint kéo theo)pip2
Pillow13.0MIT-CMU (HPND)Xử lý ảnh khi dựng PDF (WeasyPrint kéo theo). Từ F4.1 khai trực tiếp: chuẩn bị ảnh chụp, ảnh trang scan trước khi nhận dạng chữ (xoay theo EXIF, đổi xám, tăng tương phản, có trần điểm ảnh), chạy trong tiến trình con có giới hạnpip2
Pyphen0.18GPL-2.0+ / LGPL-2.1+ / MPL-1.1, Signet dùng theo MPL-1.1Ngắt từ khi dàn chữ (WeasyPrint kéo theo), dùng nguyên bản không sửapip2
segno1.6BSD-3-ClauseMã QR in trên văn bản phát hành, dẫn tới cổng xác thựcpip2
pypdf6.21.4BSD-3-ClauseĐọc lớp chữ của PDF đính kèm để tìm theo nội dung (svc-files, F2.7); F4.1 đọc chữ giữ bố cục (extraction_mode="layout") và lấy ảnh nhúng của trang scan để nhận dạng chữ. Thuần Python, không kéo thêm góipip2
pytest9.1MITTest đơn vị và tích hợp (chỉ khi phát triển)pip1
jsonschema (+ referencing, jsonschema-specifications, rpds-py, attrs)4.26MITsvc-workflow kiểm lại dữ liệu form theo JSON Schema dùng chung (schemas/)pip2
DuckDB1.5.6MITNộp lưu hồ sơ (F3.8, svc-files): ghi bảng văn bản, giao việc, dòng thời gian thành Parquet (nén zstd) và đọc lại cho phòng đọc. Một wheel nhúng, không kéo thêm gói Python, không chạy máy chủ riêngpip3
pyHanko (+ pyhanko-certvalidator, asn1crypto, tzlocal, lxml, aiohttp và 7 gói con, oscrypto, uritools, certifi; tzdata chỉ trên Windows)0.37.0 · 0.32.1MIT (lxml BSD-3, aiohttp Apache-2.0/MIT, certifi MPL-2.0, aiohappyeyeballs PSF-2.0)Ký số PAdES bản phát hành bằng khóa trong Transit, kiểm chữ ký (svc-files, F4.5, chỉ minh họa)pip4
OpenTelemetry Python (SDK, exporter OTLP/HTTP, instrumentation FastAPI và httpx2, kéo theo protobuf, requests, wrapt…)1.45.1 · 0.66b1Apache-2.0 (protobuf BSD-3, wrapt BSD-2, asgiref BSD-3, urllib3 MIT)Truy vết phân tán (#364): svc-files, svc-workflow ghi span của yêu cầu APISIX đã chọn, che theo danh sách trắng rồi gửi Jaeger (tracing.py). Chỉ nạp khi MOC_TRACE_RATIO > 0pip4

Ký số văn bản đi (F4.5, chỉ minh họa) thêm một gói khai trực tiếp, pyHanko, cùng các gói nó kéo theo. Ghim bản mới nhất phát hành trước 06/10/2026 (quy tắc hai tuần); ngày lấy từ PyPI (lần tải lên đầu tiên của bản đó), giấy phép từ METADATA của gói. Không thêm image, gói npm hay route gateway.

GóiBảnPhát hànhGiấy phépVì sao có
pyHanko0.37.031/08/2026MIT (kèm pdf_utils/LICENSE.PyPDF2, BSD-3)Khai trực tiếp: dựng chữ ký CMS/PAdES, ghi PDF, kiểm chữ ký; 0.38.0 (17/10) quá mới
pyhanko-certvalidator0.32.110/09/2026MITpyHanko đòi >=0.32.0,<0.33 — kiểm chuỗi chứng thư
asn1crypto1.5.115/03/2022MITpyHanko, certvalidator — cấu trúc ASN.1
tzlocal5.4.429/06/2026MITpyHanko
lxml6.1.302/09/2026BSD-3-ClausepyHanko (bắt buộc; Signet không dùng phần XMP)
aiohttp3.14.405/10/2026Apache-2.0 AND MITpyHanko, certvalidator đều bắt buộc; không dùng tới: không tải chứng thư, CRL, OCSP qua mạng, không TSA. 3.14.5 (11/10) quá mới
aiohappyeyeballs2.7.101/07/2026PSF-2.0aiohttp
aiosignal1.4.003/07/2025Apache-2.0aiohttp
attrs26.1.019/03/2026MITaiohttp
frozenlist1.8.006/10/2025Apache-2.0aiohttp
multidict6.9.121/09/2026Apache-2.0aiohttp, yarl. aiohttp 3.14.4 đòi multidict<7.0, nên không dùng 7.0.0 (26/09)
propcache0.5.416/09/2026Apache-2.0aiohttp, yarl
yarl1.25.115/09/2026Apache-2.0aiohttp
oscrypto1.3.018/03/2022MITcertvalidator; không nạp lúc chạy (kiểm chữ ký dùng cryptography)
uritools6.1.323/07/2026MITcertvalidator
certifi2026.10.1920/10/2026MPL-2.0certvalidator (gói CA công cộng, Signet không dùng: chỉ tin CA nội bộ của két). Nâng từ 2026.7.22 theo ngoại lệ vá bảo mật: GHSA-6q48-6c7w-9gw2, gốc emSign có CA trung gian lộ khóa
tzdata2026.503/10/2026Apache-2.0tzlocal, chỉ trên Windows (sys_platform == 'win32'): có trong tệp khóa, không cài vào image

Gói đã có trong khóa, giữ nguyên bản: cryptography 50.0.2 (pyHanko đòi ≥ 48), idna 3.20, typing-extensions 4.16.0. Image svc-files nặng thêm khoảng 15 MB (lxml, aiohttp; có wheel manylinux cho CPython 3.13). Khóa ký và CA không phải gói: chúng nằm trong két OpenBao sẵn có (mount transit, pki).

Truy vết phân tán (#364) thêm bốn gói khai trực tiếp vào cả svc-files và svc-workflow, ghim đúng bản (==). Gói nó kéo theo ghim bản mới nhất phát hành trước 13/10/2026 (--exclude-newer-package, quy tắc hai tuần); ngày lấy từ PyPI, giấy phép từ METADATA. Tắt (mặc định) thì không gói nào được nạp lúc chạy.

GóiBảnPhát hànhGiấy phépVì sao có
opentelemetry-sdk1.45.106/10/2026Apache-2.0Khai trực tiếp: TracerProvider, lấy mẫu theo cha, xử lý lô
opentelemetry-exporter-otlp-proto-http1.45.106/10/2026Apache-2.0Khai trực tiếp: gửi span tới Jaeger qua OTLP/HTTP
opentelemetry-instrumentation-fastapi0.66b106/10/2026Apache-2.0Khai trực tiếp: span cho mỗi route
opentelemetry-instrumentation-httpx0.66b106/10/2026Apache-2.0Khai trực tiếp: span cho lời gọi httpx2 (HTTPX2ClientInstrumentor)
opentelemetry-exporter-otlp-proto-common, opentelemetry-proto1.45.106/10/2026Apache-2.0Exporter: mã hóa span sang protobuf
opentelemetry-exporter-http-transport, opentelemetry-exporter-otlp-common0.66b106/10/2026Apache-2.0Exporter
opentelemetry-instrumentation, -instrumentation-asgi, -semantic-conventions, -util-http0.66b106/10/2026Apache-2.0Instrumentation FastAPI, httpx
asgiref3.12.114/07/2026BSD-3-ClauseInstrumentation ASGI; 3.13.0 (23/10) quá mới
protobuf7.36.217/09/2026BSD-3-Clauseopentelemetry-proto
googleapis-common-protos1.75.529/09/2026Apache-2.0Exporter; 1.76.0 (22/10) quá mới
requests2.34.214/05/2026Apache-2.0Exporter gửi HTTP bằng requests
charset-normalizer3.5.230/09/2026MITrequests
urllib32.8.015/09/2026MITrequests (svc-files đã có qua botocore)
certifi2026.10.1920/10/2026MPL-2.0requests, chỉ mới ở svc-workflow; cùng bản và cùng ngoại lệ vá bảo mật như svc-files ở bảng trên. Span đi http://jaeger:4318, không dùng TLS
wrapt2.5.027/09/2026BSD-2-ClauseInstrumentation; 2.5.1 (14/10) quá mới
packaging26.304/08/2026Apache-2.0 OR BSD-2-ClauseInstrumentation

opentelemetry-api 1.45.1 đã có trong khóa từ trước (FastAPI kéo theo), giữ nguyên.

Phiên bản cụ thể kèm băm nằm ở requirements.txt của từng dịch vụ; image dịch vụ dựng từ python:3.13.16-slim (PSF-2.0). Image svc-files cài thêm từ kho Debian: Pango (LGPL-2.1+, nạp động lúc chạy, không sửa), HarfBuzz (MIT) và phông Liberation 2.1 (SIL OFL 1.1) — cùng số đo với Times New Roman mà NĐ 30/2020 quy định, có đủ dấu tiếng Việt; từ F4.1 thêm Tesseract cùng dữ liệu tiếng Việt (mục Trí tuệ nhân tạo), gọi bằng dòng lệnh trong tiến trình con, không thêm gói Python. pip của image nền chỉ dùng lúc dựng: cài xong thư viện thì gỡ khỏi image, cùng các bản sao thư viện nó mang theo (pip/_vendor: certifi, urllib3, msgpack, setuptools bản cũ có lỗ hổng đã có bản sửa). Còn lại wheel pip trong ensurepip/_bundled của image nền (cùng các bản sao đó, nằm trong tệp nén): không cài, không nạp lúc chạy; lần quét image bằng Trivy chạy tay ngày 23/10/2026 không báo chúng. CI không chạy Trivy, chỉ quét tệp khóa bằng OSV-Scanner.

Phần máy chủ của Bảng tin (apps/bang-tin), máy chủ trang của Đơn nghỉ phép (apps/nghi-phep), của Đổi, bù lịch giảng (apps/lich-giang) và của Ứng dụng sinh từ bảng (apps/sinh) dựng từ cùng image python:3.13.16-slim, chỉ thư viện chuẩn, không cài gói nào. moc app đọc manifest bằng bộ đọc YAML tự viết, chỉ thư viện chuẩn (scripts/yaml_nho.py): không thêm PyYAML vào thư mục cài; test so kết quả với PyYAML khi máy có sẵn.

Vận hành và bốn nguyên lý thiết kế​

Thành phầnPhiên bản ghimGiấy phépVai tròCách nạpPhase
OpenBao2.7.1MPL-2.0Két bí mật và khóa (thay HashiCorp Vault): svc-files, svc-workflow lấy bí mật qua AppRole, static seal tự mở khóa, khóa transit cho tệp mã hóa; PKI nội bộ (CA minh họa) và khóa ký transit của từng đơn vị cho văn bản đi (F4.5). Image nguyên bản, chỉ thêm tệp cấu hình và script khởi động của đội (platform/openbao/)openbao/openbao:2.7.1 (image 01/10/2026)3
Scorpio Broker6.0.2BSD-3-ClauseContext broker NGSI-LD cho dữ liệu cảm biến (F3.10, profile iot): bản sao số, lịch sử đo, subscription báo svc-workflow khi vượt ngưỡng. Bản java mặc định (không Kafka), không mở cổng ra ngoàiscorpiobroker/all-in-one-runner:java-6.0.2 (image 03/07/2026)3
PostGIS16-3.5GPL-2.0CSDL riêng của Scorpio (broker bắt buộc phần mở rộng postgis); dịch vụ độc lập, mạng riêng chỉ broker nối được, Signet không liên kết mãpostgis/postgis:16-3.5-alpine, ghim digest (image 31/08/2026)3
Prometheusv3.15.0Apache-2.0Thu chỉ số của cổng API (plugin prometheus của APISIX) và trạng thái từng thành phần (GET /metrics của svc-files) mỗi 15 giây, tính luật cảnh báo (promtool cùng image kiểm luật trong CI); không mở cổng ra ngoài (F3.13)prom/prometheus:v3.15.03
Alertmanagerv0.34.1Apache-2.0Nhận cảnh báo đang bật của Prometheus, gom theo luật, chống gửi dồn rồi gọi svc-workflow (POST /ops/alerts, token riêng) để thành thông báo ở chuông của quản trị đơn vị, kèm email, webhook nếu đã bật kênh (#284, F3.13; amtool cùng image kiểm cấu hình trong CI); không mở cổng ra ngoài, không giữ trạng thái (tmpfs)prom/alertmanager:v0.34.1, ghim digest (image 17/09/2026)3
Grafana (OSS)13.2.3AGPL-3.0Hiển thị giám sát: bảng điều khiển nạp từ platform/monitoring/ (dịch vụ độc lập, chỉ nghe 127.0.0.1, chỉ xem, không tài khoản) (F3.13)grafana/grafana:13.2.33
cloudflared2026.10.0Apache-2.0Cloudflare Tunnel (F1.9, profile tunnel, tùy chọn): máy không có IP công khai ra Internet có HTTPS mà không mở cổng — gọi ra Cloudflare, chuyển yêu cầu vào APISIX qua mạng Docker; token để ngoài repocloudflare/cloudflared:2026.10.0 (image 05/10/2026)1
Mailpitv1.31.4MITHộp thư thử cho thông báo email của svc-workflow (profile mail, chỉ để demo, kiểm thử): nhận mọi thư qua SMTP trong mạng Docker, không chuyển tiếp ra ngoài, giao diện web chỉ nghe 127.0.0.1; không hỏi bản mới. Cài thật thì gửi qua máy chủ thư của đơn vịaxllent/mailpit:v1.31.4, ghim digest (image 03/10/2026)4
restic0.19.1BSD-2-ClauseSao lưu, khôi phục CSDL và tệp (moc backup): mã hóa, khử trùng lặp; chỉ chạy khi gọi, không mạngrestic/restic:0.19.13
Vector0.59.0MPL-2.0Thu log của 9 dịch vụ qua driver fluentd của Docker, che lần hai, gửi Parseable (F3.14, profile logs, tắt mặc định): chạy uid 65534, không gắn docker.sock, cổng nhận chỉ nghe 127.0.0.1; mật khẩu Parseable qua compose secrettimberio/vector:0.59.0-distroless-static, ghim digest (image 06/10/2026)3
Parseable3.2.4AGPL-3.0Lưu và tra log tập trung (F3.14, profile logs): dịch vụ độc lập, chỉ nghe 127.0.0.1, chạy root nhưng bỏ mọi capability, basic auth (mật khẩu rỗng thì không mở cổng), giữ MOC_LOGS_RETENTION_DAYS ngày, tắt kiểm bản mới và gửi số liệu sử dụngquay.io/parseablehq/parseable:v3.2.4, ghim digest (image 02/10/2026)3
Jaeger2.22.0Apache-2.0Nhận và hiện trace (#364, profile trace, tắt mặc định): span OTLP/HTTP của APISIX (plugin opentelemetry), svc-files, svc-workflow; giữ 10 000 trace trong RAM, giao diện chỉ nghe 127.0.0.1, không tài khoản; bỏ chuỗi truy vấn trước khi lưu (platform/trace/jaeger.yaml)jaegertracing/jaeger:2.22.0, ghim digest (image 06/10/2026)4
DokuWiki2026-07-14cGPL-2.0Wiki nội bộ ([H] Quản trị tri thức, #367, profile wiki, tắt mặc định): mỗi đơn vị một không gian don-vi:<mã> chỉ người của đơn vị đọc và sửa (scripts/wiki.py ghi danh sách quyền), đăng nhập chỉ qua Keycloak, không tài khoản quản trị; dịch vụ độc lập trong mạng apps, chạy uid 33, bỏ mọi capability, 256 MiBdokuwiki/dokuwiki:2026-07-14c, ghim digest (DokuWiki phát hành 02/09/2026), bỏ install.php; volume wiki_data nằm trong moc backup4
Plugin oauth của DokuWiki2026-10-20 (commit b709c33)GPL-2.0 (kèm lusitanian/oauth 0.8.11, MIT)Đăng nhập DokuWiki bằng OAuth: tạo tài khoản ở lần đăng nhập đầu, lấy lại nhóm (đơn vị) mỗi lần đăng nhập. Ngoại lệ vá bảo mật, xem mục Cách đọcTải trong platform/wiki/Dockerfile theo commit, kiểm sha256, nguyên bản4
Plugin oauthgeneric của DokuWiki2025-10-02 (commit b5a5653)GPL-2.0Dịch vụ OAuth chung cho plugin oauth: nối client wiki của Keycloak, đọc tên, email, nhóm từ userinfoNhư plugin oauth4
Node-RED5.0.8Apache-2.0Tự động hóa không sửa mã (#366, profile tu-dong, tắt mặc định): trình soạn flow ở /tu-dong/, đăng nhập chỉ qua Keycloak, chỉ vai trò operator của client tu-dong (scripts/tu_dong.py); không node exec, không cài node từ trình soạn; dịch vụ độc lập trong mạng apps, rootfs chỉ đọc, bỏ mọi capability, 256 MiBnodered/node-red:5.0.8-minimal, ghim digest (phát hành 08/10/2026), cộng platform/tu-dong/settings.js; volume tu_dong_data nằm trong moc backup4
openid-client (kèm jose 6.2.12, oauth4webapi 3.8.8)6.8.8MITPassport strategy cho đăng nhập Keycloak của Node-RED: luồng code + PKCE, kiểm chữ ký, iss, aud của ID tokennpm ci --omit=dev --ignore-scripts theo platform/tu-dong/package-lock.json (sha512), cả ba phát hành 05/09/20264
Coraza + OWASP CRSCoraza v3.3.3, CRS v4.14.0 (trong coraza-proxy-wasm 0.6.0)Apache-2.0Tường lửa ứng dụng web ở cổng API (F3.15): mọi yêu cầu qua CRS paranoia 1 trước khi kiểm token, tải tấn công → 403; nội dung tệp vẫn do ClamAV soighcr.io/corazawaf/coraza-proxy-wasm:0.6.0 (phát hành 06/07/2025), ghim digest, kiểm sha256 tệp .wasm; APISIX nạp bằng wasm.plugins3

Ghi chú:

  • Grafana: chỉ dùng grafana/grafana (AGPL-3.0). grafana/grafana-enterprise là bản độc quyền.
  • Scorpio Broker: compose ghim java-6.0.2; thẻ này chỉ có trên Docker Hub (03/07/2026), GitHub chưa có thẻ tương ứng, nên giấy phép đối chiếu với nhánh development-quarkus, nơi phát triển dòng 6.x: BSD-3-Clause ở bản phát hành 6.0.1 (commit 5967583) và ở đầu nhánh lúc kiểm 31/10/2026. Nhánh master cũ (mã 2019) còn BSD-4-Clause, có điều khoản quảng cáo, không thuộc danh sách OSI; Signet không dùng mã nhánh đó. Profile iot tắt mặc định.
  • Parseable: bản 3.x chỉ phát hành trên Quay (quay.io/parseablehq/parseable); parseable/parseable trên Docker Hub dừng ở 2.8.0 (29/05/2026).
  • Marquez: bản phát hành gần nhất là 0.51.1 (03/2025), mã nguồn vẫn có commit năm 2026 nhưng nhịp chậm. Theo dõi trong Phase 3; nếu gặp lỗi chặn thì chuyển sang chỉ lưu sự kiện OpenLineage vào PostgreSQL. F3.9 đã làm theo hướng đó (core.lineage_events): tránh thêm máy chủ Java và CSDL riêng (~1 GB RAM) cho một job mỗi giờ.
  • Coraza: coraza-proxy-wasm 0.6.0 là bản phát hành mới nhất và nhánh main vẫn dùng Coraza v3.3.3 (20/03/2025), nên không có bản WebAssembly nào mang Coraza đã vá (3.8.1). 3.3.3 có 12 GHSA công bố 02/10/2026: hai mức high áp dụng ở Signet có biện pháp ở cổng (JSON lồng sâu bị chặn trước WAF; quá 1000 tham số thì chặn), các lỗi lẩn WAF mức medium ghi ở platform/apisix/README.md, mục WAF. Gói Go biên dịch trong tệp .wasm (proxy-wasm-go-sdk, gjson, libinjection-go, go-re2, aho-corasick…) là Apache-2.0, MIT, BSD-3-Clause. SBOM và OSV-Scanner không đọc tệp .wasm: lỗ hổng mới của Coraza phải theo dõi tay (GitHub Security Advisories của corazawaf/coraza). Khi có bản phát hành mang Coraza ≥ 3.8.1 thì đổi digest và băm trong Dockerfile; hướng thay nếu cần bản vá sớm hơn: coraza-caddy (Coraza 3.8.1) thành một container đứng trước APISIX — so sánh ở README đó.
  • DokuWiki: thẻ 2026-07-14c của image được đẩy lại khi dựng lại; digest đang ghim là bản đẩy 24/10/2026, mã DokuWiki vẫn của bản phát hành 02/09/2026. Hai plugin của CosmoCode (nhóm làm DokuWiki) không có bản phát hành, chỉ có commit và ngày trong plugin.info.txt: ghim commit và sha256 của tệp nén. Plugin oauth mang sẵn thư viện lusitanian/oauth 0.8.11 (MIT, 14/02/2018, không còn bản mới) trong vendor/. Tệp duy nhất của Signet mà DokuWiki đọc là platform/wiki/signet.protected.php (chỉ gán cấu hình); wiki nói chuyện với Signet qua HTTP (OpenID Connect qua APISIX), không liên kết mã.

Trí tuệ nhân tạo​

Thành phầnPhiên bản ghimGiấy phépVai tròCách nạpPhase
Ollama0.35.1MITChạy mô hình ngôn ngữ cục bộ (profile ai, tùy chọn): viết trích yếu khi quy tắc không ra trích yếu tin cậy (F4.1); nhúng đoạn văn bản và câu hỏi (/api/embed), viết câu trả lời có trích dẫn cho trợ lý hỏi đáp (F4.2) — giữ cùng lúc mô hình viết và mô hình nhúng (OLLAMA_MAX_LOADED_MODELS=2); mạng nội bộ riêng, không mở cổng, tắt tính năng đám mây (OLLAMA_NO_CLOUD). Bản ổn định mới nhất trước 06/10/2026, có think và format theo JSON Schema. Chỉ chạy CPU: image chính thức kèm thư viện CUDA của NVIDIA (cuBLAS, cudart; giấy phép riêng của NVIDIA, không phải nguồn mở) cho máy có GPU, Signet không cấp GPU cho ollama nên không dùng chúng (#452)ollama/ollama:0.35.1@sha256:292ee7945dfc3d5840a181f3ab86fedb1e66703e02c8af98b50f4da56b7e278c (image 02/10/2026)4
Qwen3-1.7Bqwen3:1.7b (Q4_K_M, khoảng 1,36 GB)Apache-2.0 (đã kiểm model card và tệp LICENSE trên Hugging Face của đúng cỡ 1.7B; cỡ 4B cũng Apache-2.0)Trọng số mô hình viết trích yếu (F4.1) và câu trả lời có trích dẫn của trợ lý hỏi đáp (F4.2, chỉ từ các đoạn đã lọc theo quyền người hỏi; svc-files kiểm trích dẫn, con số trước khi trả). Phát hành 04/2025. Máy đủ nhanh thì đổi MOC_AI_MODEL=qwen3:4b hoặc chỉ riêng trợ lý MOC_ASK_MODEL=qwen3:4bTải một lần qua Ollama (make ai-model, profile ai-pull); bản kê sha256:8f68893c685c3ddff2aa3fffce2aa60a30bb2da65ca488b61fff134a4d1730e7 — so với ollama list4
Qwen3-Embedding-0.6Bqwen3-embedding:0.6b (Q8_0, 639 MB, 1024 chiều, ngữ cảnh 32K)Apache-2.0 (khai trong model card Qwen/Qwen3-Embedding-0.6B và bản GGUF chính thức trên Hugging Face; kho không kèm tệp LICENSE, bản kê Ollama không có lớp giấy phép)Mô hình nhúng đoạn văn bản và câu hỏi cho tìm theo nghĩa của trợ lý hỏi đáp (F4.2, MOC_AI_EMBED_MODEL; câu hỏi mang tiền tố Instruct: …\nQuery: …). Phát hành 05/06/2025 (bài báo arXiv 2506.05176); có trong thư viện Ollama từ 23/09/2025, Ollama hỗ trợ từ 0.12.1. MMTEB đa ngữ: trung bình 64,33, truy xuất 64,64 (bge-m3: 59,56 / 54,60 — bảng trong model card). Đổi MOC_AI_EMBED_MODEL=bge-m3 được, cùng 1024 chiều, svc-files tự nhúng lạiTải một lần qua Ollama (make ai-model, profile ai-pull); bản kê sha256:ac6da0dfba84a81fdbfbaf330198c33cd77c4cdfc53e8bc50eb581914a15621d — so với ollama list4
Tesseract OCR (+ dữ liệu vie)5.5.0 (gói Debian trixie tesseract-ocr 5.5.0-1+b1, tesseract-ocr-vie 1:4.1.0-2)Apache-2.0Nhận dạng chữ trên công văn scan, ảnh chụp khi tiếp nhận (F4.1, svc-files). Dữ liệu vie là bản tessdata_fast 4.1.0 (mô hình LSTM nhanh). Phiên bản gói lấy từ kho Debian theo image gốc — kiểm lại bằng dpkg-query -W 'tesseract-ocr*' trong image svc-files sau khi dựngGói hệ thống (apt)4

Ghi chú: trọng số mô hình có giấy phép riêng, tách khỏi giấy phép của Ollama. Trước khi dùng phải đọc giấy phép trên model card của đúng kích cỡ đã chọn. Không dùng Llama hoặc Gemma vì giấy phép trọng số không được OSI phê duyệt. F4.1 đã kiểm Qwen3-1.7B và Qwen3-4B (Apache-2.0); lớp giấy phép trong bản kê qwen3:1.7b của thư viện Ollama cũng là văn bản Apache-2.0. Ollama ghim theo ngày image lên Docker Hub (02/10/2026): trang GitHub ghi ngày bản thử nghiệm đầu tiên nên sớm hơn ngày phát hành thật. F4.2 đã kiểm Qwen3-Embedding-0.6B: model card (license: apache-2.0) của Qwen/Qwen3-Embedding-0.6B và của bản GGUF chính thức Qwen/Qwen3-Embedding-0.6B-GGUF; khác qwen3:1.7b, bản kê qwen3-embedding:0.6b của thư viện Ollama chỉ có lớp trọng số (bản kê và lớp cấu hình Q8_0, họ qwen3, 595,78M tham số đã đối chiếu với registry của Ollama). Trợ lý hỏi đáp không thêm image, không thêm gói Python: đường ống truy xuất, lọc quyền, trích dẫn, kiểm câu trả lời tự viết trong svc-files (httpx2 sẵn có), kho véc-tơ là Meilisearch đã chạy.

Mở trọng số, chưa phải AI nguồn mở. Qwen3 công bố trọng số theo Apache-2.0 nhưng không công bố mã huấn luyện và thông tin đủ chi tiết về dữ liệu huấn luyện, nên theo Định nghĩa AI nguồn mở của OSI (OSAID 1.0) đây là mô hình mở trọng số. Tài liệu của Signet gọi là "mô hình mở trọng số (Apache-2.0)", không gọi là "AI nguồn mở".

F4.3 không thêm phụ thuộc — không gói Python, gói npm, image hay route gateway nào. Tác tử gợi ý giao việc moc-assigner (svc-workflow) dùng lại: phần truy xuất của trợ lý hỏi đáp trong svc-files (chỉ mục đoạn chunks trên Meilisearch v1.54.3, tìm lai với Qwen3-Embedding qua Ollama khi bật profile ai, chỉ từ khóa khi không), gọi qua route nội bộ bằng httpx2 sẵn có; Pydantic cho thân yêu cầu; Flowable REST 8.0.0 cho nhánh song song (parallelGateway, boundary timer — BPMN chuẩn) và việc giao ra ngoài (external worker, như nhắc hạn); bỏ phiếu và hạn đề xuất tính bằng thư viện chuẩn Python (statistics.median_low). Không mô hình nào chọn đơn vị: CI không bật profile ai vẫn chạy đủ.

F4.4 không thêm phụ thuộc — không gói Python, gói npm, image hay route gateway nào. Bộ che thông tin cá nhân pii.py (svc-files, bản chép y hệt trong svc-workflow) chỉ dùng thư viện chuẩn Python (re, unicodedata, logging); test dùng uvicorn 0.54.0 (AccessFormatter thật) và pypdf (đọc kho mẫu) sẵn có. Nhật ký truy cập bỏ chuỗi truy vấn bằng khóa cấu hình sẵn có của APISIX 3.18.0 (access_log_format, http_configuration_snippet) và map, log_format của nginx trong image giao diện; giao diện chỉ thêm một biểu thức chính quy nhận nhãn che.

Thành phần đã cân nhắc nhưng không dùng​

Thành phầnLý doThay bằng
HashiCorp VaultBUSL-1.1 từ v1.15 (08/2023) — không phải OSIOpenBao
Chạy mô hình bằng GPU NVIDIA (CUDA)Bắt buộc driver NVIDIA và thư viện CUDA (cuBLAS, cudart), đều là phần mềm đóng; với card NVIDIA không có đường GPU nào hoàn toàn nguồn mở. Đã thêm ở #443, gỡ ở #452 (30/10/2026)Ollama chạy trên CPU
n8nSustainable Use License — không phải OSIVòng nền trong svc-files cho việc chạy định kỳ; Node-RED cho tự động hóa (#366, dòng cuối bảng)
RedpandaBSL-1.1 — không phải OSIChưa thay: sự kiện ghi vào bảng PostgreSQL trong cùng giao dịch (office.document_events, core.lineage_events, hộp thư đi core.notification_deliveries), Centrifugo đẩy tới trình duyệt; trục sự kiện dự kiến dùng Hasura Event Triggers, chưa khai (ROADMAP.md)
MongoDBSSPL-1.0 — không phải OSIPostgreSQL
immudbBUSL-1.1 từ 12/2023 — không phải OSISổ kiểm toán chuỗi băm trong PostgreSQL
FIWARE Orion / Orion-LDBắt buộc MongoDB (SSPL); Orion cổ điển không hỗ trợ NGSI-LDScorpio Broker
MinIOĐã ngừng phát triển, không còn phát hành imageSeaweedFS
DirectusBSL-1.1 / MSCL — không phải OSIHasura + PostgreSQL
MetabaseBản mã nguồn mở không hỗ trợ đăng nhập OIDC (Keycloak); đọc thẳng CSDL, bỏ qua phân quyền thuê ướcDashboard trong ứng dụng (ECharts)
bpmn-jsMIT kèm điều khoản bắt buộc giữ watermark — không thuộc danh sách OSIHiển thị tiến trình do đội tự vẽ
PaddleOCR, VietOCRKéo theo PaddlePaddle hoặc PyTorch (hàng trăm MB), image và CI chậm hẳn; Tesseract đủ cho công văn inTesseract + quy tắc bố cục NĐ 30 (F4.1)
Qdrant (Apache-2.0)Thêm một image và RAM; kho véc-tơ thứ hai phải đồng bộ thuộc tính quyền với CSDL; không tìm theo từ khóa tiếng Việt nên khi không có mô hình (CI) vẫn cần đường tìm khác. Meilisearch đã chạy, đã có tìm lai từ khóa + véc-tơ trong bản CEChỉ mục đoạn chunks trong Meilisearch (F4.2)
LlamaIndex (MIT)llama-index-core 0.14 kéo 28 gói phụ thuộc trực tiếp (numpy, SQLAlchemy, NLTK, tiktoken…); NLTK, tiktoken tải dữ liệu từ Internet lúc chạy, mà mạng ai không ra Internet; không làm hộ phần lọc quyền của Signet, trích dẫn và kiểm câu trả lời — đúng phần phải tự viếtĐường ống tự viết trong svc-files (svc_files/assist/, F4.2)
bge-m3 (MIT, 01/2024)Phương án thay, không phải bị loại: bge-m3:567m F16 khoảng 1,2 GB (gấp đôi RAM), điểm truy xuất đa ngữ MMTEB thấp hơn (54,60 so với 64,64). Dùng được bằng MOC_AI_EMBED_MODEL=bge-m3, cùng 1024 chiều, không cần tiền tố câu hỏiQwen3-Embedding-0.6B (F4.2)
scikit-learn (BSD-3-Clause)Thêm gói (kéo numpy, SciPy) vào svc-workflow cho một bộ phân loại học từ vài chục văn bản đã giao; phải huấn luyện lại mỗi khi thêm đơn vị hay có văn bản mới, và khó chỉ ra vì sao chọn đơn vị đóBỏ phiếu theo các văn bản tương tự đã giao (kNN có trọng số trên phần truy xuất của F4.2), căn cứ hiện kèm gợi ý (F4.3)
Mô hình sinh (Qwen3) chọn đơn vị chủ trì15–45 giây CPU mỗi văn bản; CI không có mô hình; không giải thích được vì sao chọn đơn vị đó, lại có thể bịa đơn vị không có lãnh đạo phòngBỏ phiếu như trên — không cần mô hình, tốt dần khi có thêm văn bản đã giao (F4.3)
Cấp khóa ký bằng pki/issue của OpenBaoKét sinh khóa rồi trả cả khóa riêng: khóa nằm trong RAM và đĩa của svc-files, dịch vụ phải tự giữ kínKhóa ký trong Transit, không rời két; chứng thư qua pki/sign cho CSR do Transit ký (F4.5)
Dịch vụ dấu thời gian TSA (PAdES B-T)Cần một dịch vụ TSA ngoài; demo phải chạy không có mạng ngoàiPAdES B-B, giờ ký tự khai, CLI và cổng xác thực ghi rõ (F4.5)
Trình kiểm PAdES bằng JavaScript ở cổng xác thựcThêm một thư viện lớn vào trang công khai, trong khi trình duyệt chỉ cần băm tệpTrình duyệt băm như F2.13; kiểm mật mã đầy đủ bằng pyHanko trong svc-files (python -m svc_files.signing verify) (F4.5)
Presidio (MIT)presidio-analyzer 2.2 bắt buộc kéo spaCy, numpy, phonenumbers, tldextract, regex, pydantic, PyYAML, click; bộ máy NLP spaCy cần tải thêm mô hình ngôn ngữ (không có pipeline tiếng Việt chính thức); bộ nhận dạng dựng sẵn không có định dạng Việt Nam (CCCD, đầu số di động, số tài khoản) nên vẫn phải tự viết regexpii.py tự viết, chỉ thư viện chuẩn, nhận theo cấu trúc (mã tỉnh, đầu số đã cấp), chạy được trong bộ lọc nhật ký (F4.4)
phonenumbers (Apache-2.0)Metadata lớn phải ghim và cập nhật theo bản phát hành; không biết CCCD, CMND hay số tài khoản; luật số di động Việt Nam chỉ là "10 số, đầu số đã cấp"Danh sách MOBILE_PREFIXES có ngày và nguồn trong pii.py (F4.4)
Kestra (Apache-2.0)Nộp lưu nóng → lạnh (F3.8) là một job mỗi giờ: không đáng thêm một máy chủ Java ~1 GB RAMVòng nền trong svc-files
n8n, Windmill, Activepieces, Kestra cho tự động hóa (#366)n8n theo Sustainable Use License (không phải OSI); đăng nhập SSO của Kestra, Activepieces chỉ ở bản trả phí, Windmill bản Community tối đa 10 người dùng SSO; Kestra đòi tối thiểu 4 GiB RAMNode-RED (Apache-2.0), profile tu-dong
Marquez (Apache-2.0)Thêm một máy chủ chỉ để lưu và xem phả hệ, trong khi Signet tự lưu và hiển thị phả hệBảng core.lineage_events và trang phả hệ (F3.9); đặt MOC_OPENLINEAGE_URL thì svc-files gửi sự kiện sang Marquez có sẵn
openlineage-python (Apache-2.0)Chỉ cần dựng sự kiện OpenLineage 2-0-2, thư viện chuẩn đủsvc_files.lineage (thư viện chuẩn)
Typer (MIT)Lệnh moc đủ dùng với thư viện chuẩn, không cần thêm góiargparse
Gotenberg (MIT)Thêm một image chỉ để sinh PDFWeasyPrint trong svc-files dựng PDF văn bản đi

Kiểm tra tương thích giấy phép​

Giấy phép được chấp nhận trong Signet (tương thích với Apache-2.0 ở vai trò dịch vụ độc lập):

  • ✅ Apache-2.0, MIT, MIT-0, BSD-2/3-Clause, 0BSD, ISC, BlueOak-1.0.0, PostgreSQL License, MPL-2.0 (giấy phép dễ dãi được OSI phê duyệt) và PSF-2.0 (giấy phép dễ dãi của chính Python và image python; aiohappyeyeballs qua aiohttp của pyHanko ở F4.5, typing-extensions qua Pydantic, FastAPI). SPDX đánh dấu OSI phê duyệt cho Python-2.0, bộ giấy phép của Python mở đầu bằng PSF-2.0, chứ không cho riêng PSF-2.0.
  • ✅ MIT-CMU chỉ cho Pillow (ngoại lệ có lý do): một dạng HPND, dễ dãi, chỉ đòi giữ thông báo bản quyền; SPDX đánh dấu OSI phê duyệt cho HPND nhưng chưa cho riêng MIT-CMU.
  • ✅ MPL-1.1, LGPL-2.1+, SIL OFL 1.1 cho thư viện và phông dùng nguyên bản, không sửa: Pyphen (chọn MPL-1.1 trong ba giấy phép), Pango (nạp động), phông Liberation, phông giao diện Be Vietnam Pro (gói npm @fontsource/be-vietnam-pro, không nằm trong repo; mỗi bản dựng kèm OFL.txt lấy từ gói), lunr-languages của trang tài liệu.
  • ✅ Python-2.0, Unlicense (OSI phê duyệt) và EPL-2.0 (copyleft yếu, dùng nguyên bản) chỉ cho gói của trang tài liệu website/, qua ngoại lệ có lý do: argparse, robust-predicates, elkjs (mục Trang tài liệu).
  • ✅ CC-BY-4.0, CC0-1.0 chỉ cho dữ liệu và công cụ chạy lúc dựng, lúc phát triển, không vào sản phẩm: caniuse-lite, @speed-highlight/core (mục Tầng 2), mdn-data (mục Trang tài liệu). Gói cho chọn giấy phép thì chọn giấy phép OSI: node-forge theo BSD-3-Clause; type-fest, opener, path-is-inside theo MIT.
  • ⚠️ GPL-2.0/3.0, AGPL-3.0 — chấp nhận được khi chạy như dịch vụ độc lập giao tiếp qua mạng, không liên kết mã. Hiện gồm: ClamAV, PostGIS, DokuWiki cùng hai plugin oauth, oauthgeneric (GPL-2.0), Grafana và Parseable (AGPL-3.0).
  • ❌ Mọi giấy phép không được OSI phê duyệt, giấy phép "source-available" (BUSL, SSPL, Elastic License, Sustainable Use License), hoặc bất kỳ thành phần nguồn đóng nào, kể cả thành phần tùy chọn (#452).
  • Dữ liệu công khai trong seed/du-lieu-mo/ (nguồn A #424, nguồn B #427) không mang giấy phép nguồn mở: đó là văn bản nhà nước và tin thời sự thuần túy, không thuộc phạm vi bảo hộ quyền tác giả theo Điều 15 Luật Sở hữu trí tuệ. REUSE.toml khai là LicenseRef-VN-SHTT-Dieu-15; nguồn và căn cứ dùng lại từng tệp ở manifest.json cùng thư mục.
  • Logo các dự án trong sơ đồ kiến trúc (docs/anh/logo/, ảnh docs/anh/kien-truc-tong-the*.gif) không phải thành phần phần mềm: là nhãn hiệu của chủ sở hữu, chỉ dùng để nhận diện phần mềm nguồn mở mà Signet sử dụng hoặc gửi thông báo tới, không thuộc giấy phép Apache-2.0 của Signet; khai riêng trong REUSE.toml (LicenseRef-Logos), nguồn ghi ở docs/anh/logo/NGUON.md.

Kiểm tự động, cả gói gián tiếp. make sbom sinh SBOM CycloneDX của cây mã nguồn bằng Syft (tệp khóa npm kể cả gói chỉ dùng lúc dựng, requirements*.txt, action trong .github/workflows/; giấy phép gói Python hỏi PyPI vì requirements.txt không ghi). make license-audit (scripts/license_audit.py) xét từng gói theo đúng danh sách trên: biểu thức A OR B qua khi một nhánh được nhận, A AND B phải qua cả hai; copyleft yếu qua nhưng được liệt kê riêng; GPL, AGPL, giấy phép khác và giấy phép chưa rõ thì không qua, trừ khi có ngoại lệ ghi lý do trong .github/license-exceptions.json. Ngoại lệ cho gói ngoài danh sách phải trùng giấy phép SBOM ghi (gói đổi giấy phép thì ngoại lệ hết tác dụng); ngoại lệ cho gói SBOM không rõ giấy phép ghi giấy phép đội đã đọc trong gói và phiên bản đã đọc. CI (job "Giấy phép (PoF #2)") chạy hai lệnh này trên mọi pull request; từ bản sau 1.0.0, mỗi bản phát hành kèm SBOM signet-X.Y.Z.cdx.json. Syft không đọc Dockerfile, docker-compose.yml: image thượng nguồn và giấy phép của chúng là các bảng ở trên.

Lần quét 30/10/2026 trên develop (7e2bbdb, CI run 40992435806, Syft 1.54.1): 1899 gói khác nhau — npm 1799, Python 92, action CI 8 — đều đạt. Số gói npm tăng từ 690 (lần quét 23/10) chủ yếu vì từ 27/10 quét cả trang tài liệu website/ (1304 gói, chỉ dùng lúc dựng). 32 gói qua nhờ ngoại lệ: 4 gói npm dữ liệu và công cụ dựng mang CC-BY-4.0, CC0-1.0 (mdn-data có hai bản), 7 gói npm của trang tài liệu (mục Trang tài liệu), Pillow (MIT-CMU), 12 gói Python mà PyPI chỉ khai giấy phép bằng classifier hay chữ tự do (WeasyPrint và các gói nó kéo theo, segno, DuckDB, protobuf, python-dateutil, colorama — giấy phép đọc từ tệp LICENSE trong wheel) và 8 action CI (giấy phép đọc ở đúng thẻ đã ghim). Hai gói PSF-2.0 (aiohappyeyeballs, typing-extensions) nằm trong danh sách được nhận nên không cần ngoại lệ. Copyleft yếu: Pyphen (chọn MPL-1.1), lunr-languages (MPL-1.1), phông Be Vietnam Pro (OFL-1.1).

Dịch vụ quanh dự án, không phải phụ thuộc lúc chạy​

Cài và chạy Signet trên một máy (make up) không cần dịch vụ nào dưới đây. Chúng phục vụ việc phát triển, đăng bản demo của đội, hoặc là lựa chọn của đơn vị cài đặt:

  • Cloudflare Tunnel: chỉ để đưa bản online của đội ra Internet. Phần chạy trên máy là cloudflared (Apache-2.0, profile tunnel, tắt mặc định); máy có IP công khai thì dùng Caddy hay một reverse proxy khác thay thế.
  • GitHub (kho mã, Actions, Pages): nơi lưu mã, chạy CI và đăng trang tài liệu, không thuộc sản phẩm. CI chỉ gọi lại lệnh make và script trong repo, chạy được trên máy riêng; trang tài liệu dựng tại chỗ bằng npm run build trong website/.
  • API viết câu trả lời chuẩn OpenAI (#430): tắt mặc định. Giao thức mở, đích có thể là máy chủ nguồn mở của đơn vị (vLLM Apache-2.0, llama.cpp MIT); gửi tới dịch vụ đám mây là quyết định của đơn vị. Chỉ câu hỏi cùng các đoạn căn cứ rời máy, đã che số CCCD/CMND, số điện thoại, email, số tài khoản; họ tên và địa chỉ không được che (docs/van-hanh.md, mục Trợ lý hỏi đáp qua API ngoài). Khi bật, tên, phiên bản và giấy phép của mô hình phía đích do đơn vị chọn và tự chịu trách nhiệm. Gói phát hành và bản tự cài giữ mặc định, dùng Ollama tại chỗ; bản online của đội bật API này (MOC_ASK_API=openai, mô hình gpt-6-luna-wd, không phải mô hình nguồn mở), xem mục Chạy thử của README.md.
  • API nhúng chuẩn OpenAI (#498): tắt mặc định, độc lập với API viết câu trả lời. Cùng giao thức mở (/embeddings), đích có thể là vLLM, llama.cpp của đơn vị hay Azure AI Foundry, dịch vụ đám mây. Khi bật, mọi đoạn văn bản không hạn chế trong chỉ mục của trợ lý, câu hỏi và trích yếu văn bản đến, che như trên, rời máy (docs/van-hanh.md, mục Nhúng qua API ngoài); mô hình phía đích do đơn vị chọn và tự chịu trách nhiệm. Gói phát hành và bản tự cài giữ mặc định, nhúng bằng Qwen3-Embedding trong Ollama tại chỗ; bản online (v1.4.0, kiểm ngày 02/11/2026) cũng nhúng tại chỗ, chỉ bước viết câu trả lời đi API ngoài.
  • Nơi tải về: image từ Docker Hub, Quay.io; trọng số mô hình từ thư viện của Ollama, nguồn gốc là Hugging Face (mục Trí tuệ nhân tạo).