Truy cập cơ sở dữ liệu PostgreSQL cho trình tạo ứng dụng AI
Thiết lập quyền truy cập PostgreSQL cho trình tạo ứng dụng AI bằng khám phá chỉ đọc, thông tin xác thực theo phạm vi, migration được phê duyệt và pooling an toàn.

Một trình tạo ứng dụng AI có thể kết nối với cơ sở dữ liệu PostgreSQL hiện có mà không cần sở hữu schema, nhưng ranh giới đó phải được thiết lập thật sự trong PostgreSQL. Lời nhắc «không thay đổi production» không phải là biện pháp kiểm soát. Role riêng, mặc định giao dịch, quy trình duyệt migration rõ ràng và kiểm tra schema mới là biện pháp kiểm soát.
Mô hình an toàn chia công việc cơ sở dữ liệu thành ba luồng. Khám phá đọc metadata và lấy mẫu dữ liệu được phép. Ứng dụng chỉ đọc, ghi các bảng và thao tác cần thiết. Thay đổi schema chạy bằng danh tính migration riêng sau khi con người duyệt chính xác SQL. Tôi từng thấy các nhóm gộp ba luồng này vào một thông tin xác thực owner tiện dùng, rồi phát hiện agent coi một tên cột có vẻ hợp lý là quyền thiết kế lại bảng đang hoạt động. Sự tiện lợi chỉ kéo dài một buổi chiều, việc dọn dẹp kéo dài hơn nhiều.
Khám phá phải chỉ đọc ngay từ thiết kế
Kết nối khám phá cần đủ quyền để hiểu schema được phép, không cần đủ quyền để sửa nó. Tạo role đăng nhập không thể tạo cơ sở dữ liệu hay role, không thể bỏ qua bảo mật theo hàng và không thể thừa hưởng các đặc quyền bất ngờ từ nhóm rộng. PostgreSQL tạo role mới mà không có các quyền đó, nhưng khai báo rõ ràng giúp người khác dễ rà soát ý định.
CREATE ROLE app_discovery
LOGIN
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
NOINHERIT
NOBYPASSRLS
CONNECTION LIMIT 3
PASSWORD 'replace-through-secret-manager';
ALTER ROLE app_discovery SET default_transaction_read_only = on;
GRANT CONNECT ON DATABASE customer_portal TO app_discovery;
GRANT USAGE ON SCHEMA app TO app_discovery;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO app_discovery;
default_transaction_read_only chặn các thao tác ghi thông thường trong những phiên giữ mặc định này. Nó là một lớp bảo vệ hữu ích, không phải lớp duy nhất. Việc không có INSERT, UPDATE, DELETE, TRUNCATE, CREATE và quyền sở hữu mới thực sự giới hạn role nếu client thay đổi thiết lập giao dịch. Đừng cấp tư cách thành viên của role này trong nhóm owner ứng dụng và đừng đặt nó làm owner của schema.
Nên kiểm tra quyền hiện có trước khi trình tạo ứng dụng kết nối. Truy vấn dưới đây trả về một dòng cho mỗi quyền trên bảng, để người rà soát phát hiện bất kỳ quyền nào ngoài SELECT:
SELECT table_schema, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'app_discovery'
ORDER BY table_schema, table_name, privilege_type;
Kết quả ổn có dạng app | invoices | SELECT. Kết quả rỗng có thể cho thấy quá trình khám phá không thấy một bảng cần thiết, còn dòng kết thúc bằng UPDATE nghĩa là role quá mạnh. Hãy kiểm tra cả quyền schema bằng has_schema_privilege và quyền cơ sở dữ liệu bằng has_database_privilege, vì quyền bảng không cho biết role có thể tạo đối tượng ở nơi khác hay không.
Đừng lấy snapshot production làm cớ để dùng chung thông tin xác thực owner. Bản sao vẫn có thể chứa dữ liệu khách hàng, và agent có quyền sở hữu có thể sửa nó đến mức các lần so sánh sau trở nên vô ích. Hãy cấp danh tính chuyên biệt cho việc khám phá ở mọi môi trường.
Kiểm tra catalog phải nằm trong allowlist
Trình tạo ứng dụng chỉ nên khám phá các schema đã phê duyệt và ghi nhận đúng những gì PostgreSQL báo cáo. information_schema cung cấp các view di động cho bảng, cột, ràng buộc và quyền. pg_catalog hiển thị chi tiết riêng của PostgreSQL như chỉ mục, kiểu dữ liệu, biểu thức được sinh và bảo mật theo hàng. Cả hai đều đáng tin hơn trí nhớ của một LLM về một bảng khách hàng điển hình.
Bắt đầu bằng allowlist như app và reporting. Loại pg_catalog, information_schema, schema tạm, schema extension và mọi schema tenant không có trong danh sách khỏi mục tiêu ứng dụng. Truy vấn cần lọc ở cấp cơ sở dữ liệu, role và SQL. Allowlist chỉ ở cấp lời nhắc có thể biến mất trong một cuộc trò chuyện sau đó.
SELECT
c.table_schema,
c.table_name,
c.ordinal_position,
c.column_name,
c.data_type,
c.is_nullable,
c.column_default
FROM information_schema.columns AS c
WHERE c.table_schema IN ('app', 'reporting')
ORDER BY c.table_schema, c.table_name, c.ordinal_position;
Lưu kết quả thành snapshot schema cùng thời điểm truy xuất và định danh cơ sở dữ liệu. Snapshot là bằng chứng về những gì trình tạo mã đã thấy, không phải sự thật vĩnh viễn. PostgreSQL có thể thay đổi giữa lúc khám phá và tạo mã, vì vậy hãy so sánh fingerprint mới trước khi triển khai. Một fingerprint thực tế có thể băm mô tả có thứ tự của bảng, cột, kiểu, khả năng null, mặc định, ràng buộc và chỉ mục. Nếu fingerprint khác, hãy dừng và khám phá lại thay vì đoán thay đổi nào vô hại.
Lấy mẫu hàng dữ liệu là một quyết định quyền riêng. Metadata cột hiếm khi chứa dữ liệu cá nhân, còn mẫu hàng thường có. Ưu tiên không lấy mẫu hàng khi tạo mã. Nếu cần ví dụ, hãy cung cấp một view loại bỏ hoặc che giấu bí mật và định danh trực tiếp, rồi chỉ cấp SELECT cho view đó. LIMIT 10 không làm truy vấn nhạy cảm trở nên an toàn, nó chỉ khiến lượng dữ liệu lộ ra ít hơn.
search_path cũng cần được xử lý tương tự. Đặt nó thành schema đã phê duyệt cộng với pg_catalog, dùng tên bảng đầy đủ khi tạo mã, và đừng dựa vào đối tượng mà PostgreSQL tìm thấy đầu tiên. Kẻ tấn công hoặc migration bất cẩn có thể tạo đối tượng trùng tên trong schema có thể ghi. Tên đầy đủ như app.orders loại bỏ sự mơ hồ đó.
Role lúc chạy phải khớp với hành động thực tế của người dùng
Khám phá và lúc chạy là hai công việc khác nhau. Ứng dụng lúc chạy có thể cần chèn đơn hàng, cập nhật bản nháp hoặc gọi một hàm được thiết kế cẩn thận, nhưng điều đó không biện minh cho quyền ghi rộng trên toàn bộ schema đã khám phá. Hãy lập ma trận quyền từ các hành động người dùng, rồi chuyển mỗi hành động thành quyền PostgreSQL nhỏ nhất.
Ví dụ, màn hình xem hóa đơn có thể cần SELECT trên app.invoices và app.invoice_lines, còn tính năng ghi chú cần SELECT và INSERT trên app.invoice_notes. Nó có lẽ không cần DELETE trên hóa đơn, truy cập hồ sơ đặt lại mật khẩu hay tạo schema. Chỉ cấp quyền dùng sequence khi thao tác chèn thực sự phụ thuộc sequence đó. PostgreSQL coi sequence là đối tượng riêng, điều này hay làm các trình tạo mã ngạc nhiên khi chúng kiểm thử bằng tài khoản owner.
View và hàm có thể thu hẹp bề mặt hơn nữa. View có thể cung cấp các cột đã phê duyệt và ẩn trường nội bộ. Hàm SECURITY DEFINER có thể thực hiện một thao tác có kiểm soát mà quyền thông thường không biểu đạt được, nhưng cần search_path cố định, kiểm tra đầu vào nghiêm ngặt và owner không có quyền thừa. Hãy coi hàm này là mã có đặc quyền, không phải lối tắt để né mô hình quyền.
Bảo mật theo hàng thêm một ranh giới dữ liệu bên trong bảng dùng chung. Nó không thay thế quyền bảng. PostgreSQL trước hết kiểm tra role có thể thực hiện thao tác hay không, rồi mới áp dụng chính sách theo hàng khi được bật và có hiệu lực. Hãy kiểm thử với đúng role lúc chạy vì owner bảng và role có BYPASSRLS có thể vượt chính sách. Lần kiểm thử dưới owner migration hầu như không chứng minh được người dùng cuối thấy gì.
Đừng để bí mật xuất hiện trong lời nhắc, mã nguồn được tạo, gói trình duyệt, log build hay ảnh chụp màn hình. Lưu thông tin xác thực lúc chạy trong kho bí mật của môi trường hosting và chỉ đưa vào tiến trình máy chủ. Ứng dụng di động và trình duyệt không thể giữ bí mật mật khẩu PostgreSQL, nên chúng phải gọi API máy chủ thay vì kết nối trực tiếp. Xoay vòng độc lập thông tin xác thực khám phá, lúc chạy và migration. Rò rỉ ở một luồng không được mở hai luồng còn lại.
Quyền migration thuộc về một luồng phê duyệt riêng
Trình tạo ứng dụng có thể đề xuất migration, nhưng không nên chạy chúng bằng phiên khám phá hay phiên lúc chạy. Hãy cấp cho công việc migration một role riêng, hoặc để hệ thống triển khai sẵn có đảm nhận role đó cho một tác vụ đã được phê duyệt. Không để thông tin xác thực này xuất hiện trong các phiên trò chuyện và xem trước thông thường.
Phê duyệt phải bao gồm SQL chính xác, định danh cơ sở dữ liệu đích, fingerprint schema dùng để chuẩn bị và hành vi khóa hoặc ghi lại dự kiến. Phê duyệt câu mô tả tự nhiên như «thêm trạng thái khách hàng» để lại quá nhiều khoảng trống. Thay đổi thực thi có thể thêm cột văn bản cho phép null, xây dựng lại bảng lớn, tự tạo enum hoặc cập nhật mọi hàng hiện có. Đó là những thao tác khác nhau với các kiểu lỗi khác nhau.
Tôi dùng một gói migration ngắn gọn:
- Lý do thay đổi và phiên bản ứng dụng cần nó.
- SQL đi tới chính xác và, khi trung thực, SQL đảo ngược chính xác.
- Đối tượng, quyền và hàng mà lệnh có thể tác động.
- Truy vấn kiểm tra trước, kết quả mong đợi và fingerprint schema mới.
lock_timeout,statement_timeout, tham chiếu backup hoặc snapshot và người phụ trách phát hành.
Tập lệnh đảo ngược không phải lúc nào cũng là rollback. Xóa một cột mới thêm có thể đảo thay đổi trong catalog, nhưng cũng hủy dữ liệu được ghi sau khi phát hành. DDL giao dịch của PostgreSQL hỗ trợ nhiều thao tác catalog, nhưng một giao dịch không thể khôi phục tác động bên ngoài hoặc dữ liệu mà lệnh sau đã xóa. Hãy ghi rõ các thao tác đảo ngược phá hủy dữ liệu thay vì xem DOWN như từ thần chú.
Đặt lock_timeout để migration thất bại thay vì chờ sau giao dịch bận trong khi chặn công việc mới. Đặt statement_timeout theo thao tác đã được rà soát. Chạy lại truy vấn kiểm tra trước trong cửa sổ thay đổi. Nếu kích thước bảng, đối tượng xung đột, số lượng null hay fingerprint schema khác giả định đã duyệt, hãy hủy. Agent nên trả về báo cáo không khớp, không ứng biến migration mới trên production.
Đừng tự động phê duyệt migration vì kiểm thử được tạo đã đạt. Kiểm thử thường chạy trên schema nhỏ, sạch và bỏ sót hàng đợi khóa, giá trị null cũ, ràng buộc bất thường, extension và các phiên bản ứng dụng vẫn đang phục vụ lưu lượng. Phê duyệt là lúc con người đối chiếu ý định được tạo với hệ thống đang hoạt động.
Connection pool thay đổi cách tính an toàn
Pool tái sử dụng phiên cơ sở dữ liệu, nên trạng thái phiên có thể tồn tại lâu hơn yêu cầu đã tạo nó. Nếu một yêu cầu chạy SET search_path, thay role, tạo đối tượng tạm hoặc tắt timeout, người mượn kết nối tiếp theo có thể thừa hưởng kết quả. Ứng dụng phải tránh trạng thái phiên có thể thay đổi hoặc đặt lại nó một cách tin cậy khi kết nối quay về pool.
Pool theo giao dịch khiến ranh giới nghiêm ngặt hơn. Client có thể nhận một phiên máy chủ khác sau mỗi giao dịch, làm hỏng giả định về prepared statement cấp phiên, bảng tạm, advisory lock và cài đặt cấp phiên. Các trình tạo ứng dụng thường tạo mã chạy được qua kết nối trực tiếp nhưng hỏng phía sau pool vì không mô hình hóa khác biệt này. Hãy quyết định pool dùng chế độ session hay transaction, rồi đưa chế độ đó vào quá trình tạo mã và kiểm thử.
Hãy tính ngân sách kết nối trước khi triển khai. Bắt đầu với số kết nối cho phép của cơ sở dữ liệu, dành phần cho quản trị, migration, giám sát và dịch vụ khác, rồi chia phần còn lại cho các instance ứng dụng. Nếu mười instance cùng mở hai mươi kết nối, PostgreSQL thấy hai trăm phiên tiềm năng ngay cả khi lưu lượng thấp. Pool nhỏ, thận trọng có hàng đợi thường an toàn hơn việc tăng kết nối đến khi cơ sở dữ liệu từ chối.
Dùng timeout phía máy chủ làm chốt an toàn: statement_timeout giới hạn câu lệnh dài, lock_timeout giới hạn thời gian chờ khóa và idle_in_transaction_session_timeout loại các phiên giữ giao dịch mở nhưng không làm gì. Đặt giá trị cho từng role thay vì tin mọi client được tạo sẽ nhớ. Xác minh bằng SHOW dưới đúng role và thông qua đúng pool.
Health check nên nhẹ. SELECT 1 xác nhận một lượt đi về, nhưng không xác nhận ứng dụng tới được bảng đã phê duyệt hay search_path đúng. Kiểm tra sẵn sàng có thể truy vấn một view nhỏ, ổn định bằng role lúc chạy. Đừng đưa migration vào lúc khởi động ứng dụng. Nhiều instance cùng chạy đua để thay schema tạo đúng kiểu gắn kết mà thiết kế này cần loại bỏ.
Cột bịa ra phải lỗi trước khi truy vấn chạy
LLM bịa ra các định danh có vẻ hợp lý. Nếu lời nhắc nói về tên hiển thị của khách hàng, mã được tạo có thể dùng customers.display_name dù cơ sở dữ liệu lưu given_name và family_name. Cơ sở dữ liệu sẽ từ chối truy vấn đó, tốt hơn việc âm thầm đọc nhầm trường, nhưng lỗi production vẫn là cách xác thực schema tồi.
Hãy tạo một artifact schema có kiểu từ snapshot catalog đã phê duyệt và xem đó là nguồn duy nhất để dựng truy vấn. Bảng hoặc cột không có trong artifact phải gây lỗi tạo mã. Đừng để mô hình sửa lỗi bằng cách thêm migration trừ khi tác vụ đã đi vào luồng migration. Định danh thiếu có thể là khám phá cũ, lỗi chính tả, sai môi trường hoặc yêu cầu sản phẩm thật. Mỗi trường hợp cần phản hồi khác nhau.
Kiểm tra tĩnh nên phân tích SQL và đối chiếu mọi quan hệ, cột với snapshot. Sau đó chuẩn bị statement trên cơ sở dữ liệu có thể bỏ đi hoặc trong giao dịch không thể ghi. Parser của PostgreSQL phát hiện cột không tồn tại, tham chiếu mơ hồ, lỗi kiểu toán tử và nhiều ép kiểu sai mà không cần dữ liệu nghiệp vụ thành công. Chạy kiểm thử tích hợp bằng role lúc chạy để quyền và chính sách hàng cùng tham gia.
Báo cáo lỗi cần đủ chi tiết để con người quyết định. Hãy gồm vị trí SQL, định danh không giải quyết được, các định danh hợp lệ gần đó, fingerprint snapshot và định danh cơ sở dữ liệu đích. Gợi ý hữu ích, nhưng tự động thay thế mờ nguy hiểm. Đổi billing_address_id thành shipping_address_id chỉ vì tên gần nhau có thể tạo SQL hợp lệ nhưng mang ý nghĩa nghiệp vụ sai.
Với bộ lọc và sắp xếp động, hãy ánh xạ tên API công khai vào một tập đóng các biểu thức SQL đầy đủ. Đừng bao giờ chèn định danh do mô hình cung cấp vào SQL, kể cả qua tham số giá trị. Tham số bảo vệ giá trị, không bảo vệ tên bảng hay cột. Nếu người dùng chọn trường sắp xếp, hãy dịch created thành biểu thức đã biết như app.orders.created_at, và từ chối mọi token không xác định.
Schema trôi lệch phải dừng một lần phát hành, không phải kích hoạt việc hòa giải sáng tạo. Tạo lại snapshot, hiển thị khác biệt và kiểm thử lại. Sự chậm trễ này có thể có vẻ cẩn trọng quá mức, nhưng rẻ hơn việc triển khai mã mà hiểu biết về cơ sở dữ liệu chỉ tồn tại trong bản ghi trò chuyện.
SQL phá hủy cần chính sách từ chối và bằng chứng
Trình tạo ứng dụng cần phân loại SQL trước khi bất kỳ ai có thể thực thi. Chặn DROP, TRUNCATE, DELETE hoặc UPDATE diện rộng không có điều kiện đã được rà soát, thay đổi owner, leo thang quyền, thay đổi extension và lệnh nhắm ra ngoài schema được phê duyệt. Xem ALTER TABLE là cần rà soát, không mặc nhiên an toàn. Đổi kiểu cột hoặc thêm ràng buộc không null có thể quét hoặc ghi lại dữ liệu và giữ khóa đáng kể.
Chỉ khớp văn bản là yếu vì SQL có comment, định danh đặt trong dấu nháy, hàm và nhiều cách gây tác dụng phụ. Hãy phân tích statement bằng parser hiểu PostgreSQL, kiểm tra cây cú pháp của chúng và cũng dựa vào role cơ sở dữ liệu để từ chối hành động bị cấm. Bộ phân loại giúp rà soát, quyền thực thi ranh giới. Không cái nào nên gánh toàn bộ trách nhiệm.
Dùng cơ sở dữ liệu staging được khôi phục từ snapshot gần đây, được bảo vệ đúng cách khi migration phụ thuộc vào hình dạng bảng thật hoặc phân bố dữ liệu. Áp dụng chính xác gói migration ở đó, ghi nhận thời lượng và quan sát khóa, chạy kiểm thử ứng dụng bằng thông tin xác thực lúc chạy rồi hủy môi trường. Đừng âm thầm sửa SQL giữa staging và production. Mọi chỉnh sửa tạo artifact mới, cần fingerprint và phê duyệt mới.
Log cần liên kết một đề xuất với lần thực thi mà không ghi bí mật hay hàng nhạy cảm. Ghi ai đã phê duyệt artifact migration bất biến, digest của nó, định danh đích, trạng thái bắt đầu và kết thúc, cùng chi tiết lỗi PostgreSQL. Lưu phần khác biệt được tạo và kết quả kiểm tra trước. Cuộc trò chuyện với agent là ngữ cảnh hữu ích nhưng không phải hồ sơ kiểm toán vì người dùng có thể rẽ nhánh, thử lại và diễn đạt lại chỉ dẫn.
Snapshot và kiểm soát rollback giảm thời gian khôi phục, nhưng không làm SQL phá hủy trở nên chấp nhận được. Snapshot có thể khôi phục cả cơ sở dữ liệu về thời điểm trước đó khi nhu cầu thực tế là một cột bị xóa, và việc khôi phục có thể loại bỏ các ghi hợp lệ sau snapshot. Hãy kiểm thử khôi phục riêng và ghi rõ ai có thể thực hiện.
Khi dùng Koder.ai cho ứng dụng chạm vào cơ sở dữ liệu đã có, tôi giữ công việc ở chế độ lập kế hoạch đến khi đã xem xét mã nguồn xuất ra và ranh giới cơ sở dữ liệu được đề xuất. Snapshot và rollback là biện pháp khôi phục, không phải quyền bỏ qua việc rà soát đó. Quy tắc này áp dụng cho mọi trình tạo ứng dụng: sự tiện lợi của sản phẩm phải nằm sau cơ chế thực thi của cơ sở dữ liệu.
Thay đổi schema phải chịu được các phiên bản ứng dụng lẫn lộn
Migration chỉ an toàn khi cả ứng dụng cũ và mới đều có thể chạy trong cửa sổ phát hành. Production hiếm khi chuyển từ một phiên bản sang phiên bản khác trong một khoảnh khắc. Yêu cầu có thể đến instance cũ khi instance mới khởi động, tác vụ hàng đợi có thể mang payload cũ và rollback có thể đưa mã hôm qua trở lại trên schema hôm nay. Trình tạo ứng dụng chỉ xác thực mã cuối cùng với schema cuối cùng sẽ bỏ lỡ giai đoạn chồng lấp này.
Ưu tiên thay đổi cộng thêm. Thêm cột cho phép null, bảng mới hoặc chỉ mục mới mà không xóa đường cũ. Triển khai mã có thể đọc cả hai cách biểu diễn và ghi cách biểu diễn mới khi phù hợp. Điền bổ sung cho hàng hiện có bằng tác vụ được rà soát riêng, theo dõi lỗi và độ trễ, rồi mới coi trường mới là nguồn chính. Xóa cột cũ hoặc ràng buộc trong lần phát hành sau, khi bằng chứng cho thấy không còn mã đang chạy sử dụng chúng.
Trình tự này lâu hơn việc tạo một câu ALTER TABLE, nhưng cô lập lỗi. Nếu mã mới hoạt động sai trước khi xóa, đường cũ vẫn tồn tại. Nếu điền bổ sung chậm, nó có thể tạm dừng mà không giữ bản phát hành ứng dụng làm con tin. Nếu triển khai rollback, ứng dụng cũ vẫn nhận ra cơ sở dữ liệu. Một lần phát hành thêm rẻ hơn việc phát hiện trong lúc rollback rằng binary trước đó truy vấn cột mà migration đã xóa.
Đổi tên cần đặc biệt cẩn thận vì PostgreSQL đổi tên ngay lập tức. Trình tạo mã có thể đề xuất đổi customer_ref thành customer_id vì tên mới dễ đọc hơn. Instance cũ sẽ lỗi ngay khi migration commit. Hãy thêm customer_id, giữ hai trường đồng bộ trong mã ứng dụng hoặc trigger được rà soát hẹp, chuyển các trình đọc, rồi chỉ xóa customer_ref sau khi trình ghi cũ biến mất. Sự trùng lặp tạm thời là khoản nợ nhìn thấy được với điều kiện xóa rõ ràng, còn đổi tên ngay lập tức là gắn kết phát hành vô hình.
Giá trị mặc định và ràng buộc không null cũng có thể che giấu công việc. Trước khi phê duyệt SET NOT NULL, hãy đếm các giá trị null hiện có và chứng minh mọi trình ghi đang hoạt động đều cung cấp giá trị. Với bảng lớn hoặc bận, hãy rà soát phiên bản PostgreSQL xác thực ràng buộc thế nào và cần những khóa nào. Trình tạo ứng dụng nên báo các điều kiện tiên quyết này thay vì suy ra từ schema không có lưu lượng đại diện.
Việc điền bổ sung dữ liệu không nên nằm trong giao dịch schema không giới hạn. Hãy cập nhật hàng theo lô có đo lường qua worker được phê duyệt, ghi tiến độ bằng cursor ổn định và làm cho việc thử lại có tính idempotent. Một lần thử lại idempotent khi áp dụng hai lần vẫn tạo trạng thái mong muốn, không chỉ khi PostgreSQL chấp nhận truy vấn thứ hai. Với giá trị dẫn xuất, hãy ghi phiên bản cách tính nếu mã sau này có thể tính khác.
Gói phát hành nên nêu bốn điểm tương thích:
- Phiên bản ứng dụng cũ nhất được phép chạy trước migration.
- Trạng thái schema mà cả phiên bản cũ và mới chấp nhận.
- Tín hiệu cho phép lần phát hành dọn dẹp có tính phá hủy.
- Đường khôi phục nếu mã mới rollback sau khi dữ liệu đã thay đổi.
Truy vấn được tạo nên tránh SELECT * trong các giai đoạn chuyển đổi này. Thêm một cột có thể thay đổi chi phí quét, giải mã kết quả, ánh xạ theo vị trí và khả năng lộ dữ liệu dù SQL cũ vẫn phân tích được. Liệt kê rõ các cột đầy đủ và tạo decoder từ cùng snapshot schema. Việc này cũng giúp rà soát mã nguồn thấy chính xác dữ liệu nào đi qua ranh giới cơ sở dữ liệu.
Công cụ migration thường theo dõi phiên bản đã áp dụng trong một bảng, nhưng riêng số phiên bản không chứng minh tính tương thích. Hãy ghi digest của artifact SQL chính xác, vì hai tệp cùng tên thân thiện có thể chứa lệnh khác nhau. Bộ thực thi phải từ chối phiên bản đã ghi nhận nếu digest khác. Nó cũng phải từ chối migration sau nếu thiếu migration tiền đề cần thiết.
Đừng để mọi instance ứng dụng chạy migration khi khởi động. Dù công cụ migration dùng advisory lock, khởi động giờ phụ thuộc vào thông tin xác thực đặc quyền và việc schema hoàn thành trước khi health check hết hạn. Đưa migration vào một tác vụ phát hành, chờ kết quả được ghi nhận, rồi khởi động instance lúc chạy bằng danh tính không thể sửa schema. Nếu hệ thống phát hành không thể tách các giai đoạn này, hãy sửa hệ thống phát hành trước khi cấp quyền owner cho ứng dụng.
Hãy kiểm thử dòng thời gian này, không chỉ đích đến: mã cũ trên schema cũ, mã cũ trên schema đã mở rộng, mã mới trên schema đã mở rộng và mã đã rollback sau các lần ghi mới. Dọn dẹp có kiểm thử riêng về sau. Ma trận này phát hiện các thay đổi đúng cú pháp nhưng không thể đảo ngược trong vận hành.
Chứng minh ranh giới bằng kiểm thử âm
Một thiết kế an toàn chưa hoàn chỉnh cho đến khi hành động bị cấm thất bại trong kiểm thử. Kết nối với vai trò khám phá và thử chèn dữ liệu, tạo bảng và SET TRANSACTION READ WRITE. Kết nối với vai trò lúc chạy và thử truy cập bảng chưa được cấp quyền, đọc chéo tenant bị bảo mật theo hàng chặn và thay đổi schema. Kết quả mong đợi là lỗi quyền PostgreSQL, không phải lời hứa trong log agent.
Cũng hãy chạy kiểm thử dương. Khám phá vẫn phải đọc được mọi mục catalog được phép. Lúc chạy phải thực hiện được mọi hành động người dùng đã duyệt qua pool. Thực thi migration chỉ được hoạt động qua luồng phê duyệt. Ranh giới chặn công việc bình thường của sản phẩm sẽ khiến ai đó thay nó bằng thông tin xác thực owner trong lúc sự cố.
Giữ một hợp đồng truy cập nhỏ cạnh mã nguồn ứng dụng. Nó nên nêu tên cơ sở dữ liệu, schema được phép, phạm vi khám phá, thao tác lúc chạy, chế độ pool, chính sách timeout, người phê duyệt migration, cách tạo fingerprint schema và các câu lệnh bị cấm. So sánh quyền thực tế với hợp đồng này trong các lần kiểm tra liên tục. Quyền PostgreSQL trôi lệch cũng là trôi lệch cấu hình, ngay cả khi không ai sửa mã ứng dụng.
Kiểm tra lại sau khi thay role, thêm bảng mới, khôi phục cơ sở dữ liệu, nâng cấp pool và thay đổi hosting. Quyền mặc định quan trọng với đối tượng tương lai: cấp SELECT ON ALL TABLES chỉ bao phủ bảng hiện tại, không bao phủ bảng được tạo sau. Hãy quyết định đối tượng mới nên vô hình cho đến khi được rà soát hay được đưa vào qua quyền mặc định cấu hình hẹp. Tôi thích mặc định vô hình vì quyền cấp rõ ràng buộc bảng mới bước vào cuộc trao đổi về truy cập.
Đưa cả việc thu hồi vào kế hoạch kiểm thử. Vô hiệu hóa thông tin xác thực khám phá và xác nhận lưu lượng lúc chạy vẫn tiếp tục; vô hiệu hóa quyền lúc chạy và xác nhận công cụ migration không âm thầm thay bằng danh tính mạnh hơn. Sau đó xoay từng bí mật khi kết nối đang hoạt động và quan sát pool có loại các phiên cũ trong khoảng thời gian dự kiến hay không. Đổi mật khẩu không chấm dứt các phiên đã xác thực, nên quy trình xoay vòng cần tái tạo pool rõ ràng hoặc chính sách chấm dứt phiên PostgreSQL.
Rà soát thông báo lỗi để tránh lộ thông tin trong các kiểm thử này. Lỗi PostgreSQL có thể chứa tên quan hệ, đoạn SQL, tên ràng buộc và giá trị được cung cấp. Gửi lỗi chi tiết vào log máy chủ bị hạn chế, trả lỗi công khai ổn định cho client và đừng đưa toàn bộ luồng lỗi production vào cuộc trò chuyện với agent. Trình tạo ứng dụng cần vị trí statement và phản hồi cơ sở dữ liệu đã được làm sạch để sửa mã, không cần giá trị của khách hàng.
Một kiểm thử cuối cùng phát hiện rất nhiều tích hợp không an toàn: xóa hoàn toàn thông tin xác thực migration và chạy bộ kiểm thử ứng dụng. Nếu khởi động bình thường, health check, xem trước hoặc xử lý yêu cầu thất bại, quyền sở hữu schema đã rò vào đường lúc chạy. Hãy sửa sự gắn kết đó trước khi kết nối trình tạo ứng dụng với production. Trình tạo ứng dụng AI có thể làm việc với cơ sở dữ liệu mà nó không sở hữu, nhưng PostgreSQL phải có thể nói không khi mã được tạo quên thỏa thuận này.
Câu hỏi thường gặp
Trình tạo ứng dụng AI có thể dùng cơ sở dữ liệu PostgreSQL hiện có của tôi không?
Có, nếu công cụ kết nối qua các role chuyên biệt và chỉ khám phá những schema đã được phê duyệt. Hãy tách việc khám phá, truy vấn lúc chạy và migration thành các luồng quyền riêng để kết nối công cụ không đồng nghĩa với trao quyền sở hữu schema.
Người dùng PostgreSQL chỉ đọc có đảm bảo dữ liệu không bị thay đổi không?
Role chỉ có SELECT và không sở hữu đối tượng là biện pháp kiểm soát chính. default_transaction_read_only bổ sung thêm lớp bảo vệ, nhưng không thể bù cho quyền cấp quá rộng hoặc tư cách thành viên được kế thừa.
Tôi có nên đưa mật khẩu owner cơ sở dữ liệu cho trình tạo ứng dụng không?
Không. Thông tin xác thực của owner phá vỡ ranh giới và cho phép SQL được tạo sửa quyền, bảng và dữ liệu. Hãy tạo thông tin xác thực riêng cho việc khám phá, lúc chạy và tác vụ migration có kiểm soát.
Trình tạo ứng dụng có thể tìm hiểu schema của tôi an toàn bằng cách nào?
Cho công cụ truy vấn các view information_schema và pg_catalog đã được phê duyệt bằng role có phạm vi hẹp, rồi lưu snapshot có fingerprint. Tránh lấy mẫu hàng dữ liệu trừ khi đã chuẩn bị một view được che giấu dữ liệu cho mục đích đó.
Điều gì xảy ra khi AI bịa ra một cột PostgreSQL?
Quá trình tạo mã phải thất bại trước khi triển khai khi đối chiếu với snapshot schema có kiểu. Hãy báo tên không xác định và các tên hợp lệ gần đó, nhưng cần một người quyết định cách sửa là mã, khám phá lại hay migration đã được phê duyệt.
Ứng dụng có thể kết nối trực tiếp từ trình duyệt hoặc ứng dụng di động không?
Không nên kết nối trực tiếp với PostgreSQL vì các client đó không thể giữ bí mật mật khẩu cơ sở dữ liệu. Hãy đặt truy cập cơ sở dữ liệu trong tiến trình máy chủ và để trình duyệt hoặc ứng dụng di động gọi API của máy chủ.
Tôi có cần connection pool cho các ứng dụng được tạo không?
Thông thường là cần, nhưng hãy cấu hình có chủ đích. Giới hạn tổng số phiên, chọn chế độ session hoặc transaction, đặt lại trạng thái có thể thay đổi và kiểm thử mã được tạo qua đúng pool dùng trong môi trường production.
Có thể rollback migration PostgreSQL một cách an toàn không?
Một số thay đổi catalog có thể đảo ngược sạch trong giao dịch, còn mất dữ liệu và tác động bên ngoài thì không. Hãy xem xét riêng SQL đi tới và SQL đảo ngược, đồng thời coi snapshot là công cụ khôi phục chứ không phải bằng chứng thay đổi an toàn.
Làm sao ngăn trình tạo ứng dụng thay đổi các bảng chưa được phê duyệt?
Dùng allowlist schema, tên đầy đủ, quyền hẹp, chính sách SQL đã phân tích cú pháp và kiểm thử quyền âm. Role PostgreSQL phải từ chối thao tác ngay cả khi mô hình hoặc bộ kiểm tra chính sách mắc lỗi.
Trình tạo ứng dụng nên khám phá lại schema bao lâu một lần?
Khám phá lại khi fingerprint đã lưu khác đi, cũng như sau migration, khôi phục hoặc thay đổi môi trường. Đừng làm mới âm thầm trong lúc phát hành, hãy hiển thị phần khác biệt và chạy lại xác thực với snapshot mới.