Bạn chia việc cho mười ba agent. Paperclip thì không chia khóa.
Một đợt quét một framework agent 71.000 sao phát hiện mười hai trong số mười ba agent mang cùng một token văn bản thuần. Khi bạn vận hành một đội agent, “bí mật nằm trong config” thôi không còn là lối tắt mà trở thành một hệ số nhân.
Bạn đã làm theo cách hiện đại. Thay vì một agent lớn, bạn dựng lên một đội — một agent xử lý ticket, một agent viết nội dung, một agent chạy pipeline thiết kế, một tá agent như vậy, mỗi agent một việc và một config riêng. Cảm giác an toàn hơn theo cách đó. Phạm vi ảnh hưởng nhỏ hơn. Nhiều nguyên tắc đặc quyền tối thiểu hơn.
Rồi một đợt quét bảo mật đi qua các config của một framework agent có 71.000 sao tên Paperclip và phát hiện mười hai trong số mười ba agent của nó mang cùng một thông tin xác thực — một token giống hệt nhau, được dán ở dạng văn bản thuần vào config của từng agent [1]. Một khóa API của Anthropic nằm hardcode trong config của một agent thiết kế ở dạng rõ ràng. Một bot token vốn dành cho một agent lại có thể đọc được bởi những agent chẳng liên quan gì đến nó.
Mười ba cánh cửa. Một khóa, được sao chép vào mười hai cánh. Lấy cắp nó từ agent yếu nhất là bạn có cả mười một cái còn lại.
Chuyện gì thực sự đã xảy ra
Paperclip cấp cho mỗi agent một config MCP server — tệp cho agent biết nó có thể chạm tới những công cụ và dịch vụ nào, và xác thực với chúng bằng cách nào. Đâu đó trên đường đi, các bí mật đã đi thẳng vào những tệp đó dưới dạng văn bản thuần: một JWT của n8n, một bearer token, một khóa API của Anthropic. Không phải tham chiếu. Không được inject lúc chạy. Được gõ vào — và rồi, vì việc dựng agent tiếp theo chỉ là copy-paste, nó bị nhân bản ra khắp đội.
Đợt quét đánh dấu ba vấn đề. Các token văn bản thuần dùng chung trên mười hai agent (xếp mức HIGH). Khóa Anthropic nằm rõ ràng trong config của một agent thiết kế (xếp mức CRITICAL). Và một bot token được gán phạm vi cho những agent mà nó vốn không dành cho — một lỗi vi phạm nguyên tắc đặc quyền tối thiểu rõ ràng [1]. Phải ghi nhận rằng đội ngũ Paperclip phản ứng nhanh: họ chuyển sang dùng tham chiếu thông tin xác thực, che config khi đọc chéo giữa các agent, và bắt buộc đồng bộ binding [2]. Đúng hướng.
Không phải Paperclip bất cẩn
Đây là phần đáng để ngẫm. Paperclip làm điều mà gần như mọi framework đều làm. Đặt bí mật vào một tệp config là cách phần mềm đã xác thực suốt ba mươi năm qua. Nó hiệu quả vì chỉ có một ứng dụng, một config, một người vận hành biết khóa nằm ở đâu.
Kỷ nguyên đã đổi thay dưới chính thói quen đó. Một hệ thống đa agent không phải là một ứng dụng với một config — mà là một tá tiến trình, mỗi tiến trình một tệp, mỗi tệp là bản sao của tệp trước. Văn bản thuần trong config là một lối tắt có thể chấp nhận được khi chỉ có một chỗ để rò rỉ. Ở con số mười ba, lối tắt đó có nghĩa là một lần rò rỉ bằng mười ba lần rò rỉ — và câu hỏi “agent nào đã làm vậy?” không có câu trả lời, vì token trong log thuộc về tất cả chúng.
Tham chiếu thông tin xác thực — bản vá mà Paperclip đã đưa ra — thực sự tốt hơn. Nhưng hãy để ý điều gì được và không được thay đổi. Một tham chiếu vẫn quy về một bí mật thật ở nơi agent chạy; bản thân agent, hoặc bất cứ thứ gì xâm phạm được nó, vẫn đọc được giá trị đã quy đổi. Và hệ thống theo dõi lỗi của chính framework đó đã cho thấy kiểu hỏng tiếp theo: một tham chiếu lệch khỏi binding của nó, khiến config trông như đã điền đủ trong khi bước kiểm tra âm thầm thất bại [3]. Bí mật đã lùi lại một lớp. Nó chưa rời khỏi tòa nhà.
Không chỉ có Paperclip
Cùng tuần, cùng nguyên nhân gốc, khác repo. Một agent viết code được dùng rộng rãi bị báo cáo vì in thẳng các giá trị .env thô — mật khẩu, token, khóa API — vào đầu ra chat của nó. Một agent runner khác bị phát hiện giao toàn bộ môi trường cha cho các tiến trình con, khiến mọi khóa của nhà cung cấp đều lộ ra với tiến trình con [4]. Một voice hook ghi bản ghi hội thoại, kèm thông tin xác thực, vào /tmp mà ai cũng đọc được [5]. Các đội độc lập, các mô hình mối đe dọa độc lập, cùng một giả định: rằng bí mật sống ở nơi agent nhìn thấy là ổn. Toàn bộ lập luận mà kẻ tấn công cần đưa ra chỉ là: không.
Thiết kế cho điều này, có chủ đích
Clavitor xuất phát từ giả định ngược lại: agent không bao giờ nắm thông tin xác thực. Nó yêu cầu một hành động; yêu cầu bị chặn lại, được xác thực với một bí mật mà agent không thể đọc, rồi được thực thi. Không có config nào để dán token vào, vì không có token trong config. Không có gì để sao chép qua mười ba agent, vì môi trường của agent không bao giờ nắm thứ đáng để đánh cắp.
Mỗi agent chỉ chạm tới đúng phạm vi mà nó được đặt tên — không phải toàn bộ kho — nên một bot token không thể lọt vào tay một agent chưa từng yêu cầu nó. Và mọi hành động được ghi log theo đúng tác nhân cụ thể thực hiện, không bao giờ theo một token dùng chung mà mười hai agent cùng có — nên câu hỏi “agent nào đã làm vậy?” có câu trả lời.
Nói thẳng: điều này không khiến một agent trở nên không thể bị hack. Một agent bị xâm phạm vẫn có thể làm, trong thời điểm đó, những việc nó được phép làm. Điều nó không thể làm là ôm khóa bỏ trốn và trở thành mười hai agent còn lại — vì không có khóa nào trong tay nó để ôm.
Bài học không phải là “xoay token”
Paperclip sẽ xoay token, hoàn tất việc chuyển đổi, và đóng các issue. Tốt — họ nên làm vậy. Nhưng việc xoay token không phải là bài học. Bài học là ngay khi bạn có một đội agent thay vì một ứng dụng, “bí mật nằm trong config” thôi không còn là lối tắt mà trở thành một hệ số nhân. Bạn không sửa một hệ số nhân bằng cách làm bí mật khó đọc hơn một chút. Bạn sửa bằng cách đảm bảo bí mật chưa từng nằm trong tay agent ngay từ đầu.
Chúng tôi đã ghi lại những quy tắc mà chúng tôi cho rằng một công cụ quản lý thông tin xác thực nên giữ trong kỷ nguyên agent — trong đó có việc bí mật không bao giờ sống ở nơi code chạy, và agent chỉ chạm tới đúng phạm vi được đặt tên. Đối chiếu quy tắc của bạn với chúng: clavitor.ai/rules.
Clavitor (@clavitorai) là két lưu trữ thông tin xác thực được xây dựng cho các AI agent, và để chống lại chính chúng. clavitor.ai
Nguồn
[1] Framework agent Paperclip — các phát hiện về vệ sinh thông tin xác thực (CFG-H1 token văn bản thuần dùng chung, CFG-C1 khóa Anthropic hardcode, CFG-H2 bot token sai phạm vi): https://github.com/paperclipai/paperclip
[2] Paperclip — bắt buộc đồng bộ secret-binding của agent trên các luồng vòng đời (đã merge): https://github.com/paperclipai/paperclip/pull/8307
[3] Paperclip — các mục env secret_ref có thể lệch khỏi các dòng secret_bindings, config trông như đã điền đủ nhưng bước kiểm tra thất bại âm thầm (#8309): https://github.com/paperclipai/paperclip/issues/8309
[4] Chetter — runBatchAgent kế thừa toàn bộ môi trường của runner, để lộ khóa API của nhà cung cấp cho tiến trình con (#56): https://github.com/flatout-works/chetter/issues/56
[5] Claude Code voice hook — toàn bộ bản ghi hội thoại (kèm thông tin xác thực) được ghi vào /tmp mà ai cũng đọc được (#58): https://github.com/rodlaneedu-hash/claude-code-voice-hook/issues/58