Cargo cooldown คืออะไร: Rust 1.100 ให้หน่วงการใช้ crate รุ่นใหม่ ลดเสี่ยงห่วงโซ่ซัพพลาย
Cargo cooldown คือค่าที่ให้ Cargo ไม่เลือก crate รุ่นที่เพิ่งออกไม่ถึงเวลาที่กำหนด จะเสถียรใน Rust 1.100 วันที่ 12 พ.ย. 2026 แต่ค่าเริ่มต้นเป็น 0 ต้องเปิดใช้เอง
โดย กองบรรณาธิการ THAI DATA อ่าน 6 นาที

สรุปประเด็นสำคัญ
- Cargo cooldown หรือ minimum publish age ถูกประกาศเป็นฟีเจอร์เสถียรใน changelog ของ Cargo 1.100 ซึ่งมีกำหนดออกพร้อม Rust 1.100 วันที่ 12 พฤศจิกายน 2026
- ตั้งค่าด้วย
registry.global-min-publish-ageเช่น"7 days"หรือ"14 days"แต่ ค่าเริ่มต้นคือ "0" การอัปเกรด Rust อย่างเดียวจึงยังไม่เปิดการป้องกัน - เมื่อเปิดแล้ว resolver จะ ข้ามรุ่นที่ใหม่เกินกำหนด เว้นแต่รุ่นนั้นอยู่ใน Cargo.lock แล้ว และถ้าไม่มีรุ่นที่ผ่านเงื่อนไข Cargo จะแจ้ง error แทนการดึงรุ่นใหม่
- แนวคิดมาจาก RFC 3923 ที่เริ่มเมื่อ 23 กุมภาพันธ์ 2026 ซึ่งระบุว่าการโจมตีห่วงโซ่ซัพพลายบางแบบถูกเครื่องสแกนอัตโนมัติจับได้ภายในไม่นานหลังเผยแพร่
- Cargo 1.100 ยังเปิดใช้ ระบบ lint ของ Cargo พร้อม lint
cargo::unused_dependenciesเปลี่ยนโครงสร้างโฟลเดอร์ build และให้cargo installใช้ lockfile ในแพ็กเกจเป็นค่าเริ่มต้น
Cargo cooldown คือการตั้งอายุขั้นต่ำให้ Cargo ตัวจัดการแพ็กเกจของภาษา Rust ไม่เลือกใช้ crate รุ่นที่เพิ่งเผยแพร่ไม่ถึงระยะเวลาที่กำหนด เช่น 7 หรือ 14 วัน ฟีเจอร์นี้จะเป็นฟีเจอร์เสถียรใน Rust 1.100 ที่มีกำหนดออกวันที่ 12 พฤศจิกายน 2026 แต่ค่าเริ่มต้นคือ 0 วัน ทีมจึงต้องเปิดใช้เอง
RFC 3923 ที่เป็นต้นทางของฟีเจอร์นี้อ้างถึงการโจมตีห่วงโซ่ซัพพลายในระบบนิเวศ npm ที่ทำให้คนหันมาสนใจการรอ เพราะการโจมตีบางแบบถูกเครื่องสแกนอัตโนมัติพบได้หลังรุ่นใหม่เผยแพร่ไม่นาน การรอให้รุ่นใหม่ "เย็นลง" ก่อนใช้จึงลดโอกาสที่ build หรือเครื่องของนักพัฒนาจะดึงรุ่นนั้นไปก่อนที่ปัญหาจะถูกพบ
Cargo cooldown คืออะไร
ในเอกสารทางการ ฟีเจอร์นี้ชื่อ minimum publish age ส่วน changelog ของ Cargo 1.100 เรียกว่า dependency cooldowns หลักการคือ registry อย่าง crates.io บันทึกเวลาเผยแพร่ (pubtime) ของแต่ละรุ่นไว้ เมื่อ Cargo เลือกรุ่นของ dependency จะเทียบเวลานั้นกับอายุขั้นต่ำที่ทีมตั้งไว้ รุ่นที่ใหม่เกินจะถูกนับว่า "pubtime-incompatible" และถูกข้าม
RFC 3923 ซึ่งเริ่มเมื่อ 23 กุมภาพันธ์ 2026 ให้เหตุผลไว้ 2 ข้อ
- ลดความเสี่ยงห่วงโซ่ซัพพลาย การโจมตีบางแบบถูกเครื่องสแกนอัตโนมัติจับได้หลังรุ่นใหม่เผยแพร่ไม่นาน การรอจึงให้เวลาเครื่องสแกนเหล่านี้ทำงาน
- ทยอยรับรุ่นใหม่ทั้งระบบนิเวศ รุ่นใหม่อาจมีบั๊ก การเปลี่ยนแปลงที่ทำให้ของเดิมพัง หรือช่องโหว่ที่ไม่ได้ตั้งใจ ถ้าทุกคนอัปเกรดพร้อมกัน ความเสียหายจะกว้าง ผู้ที่รับความเสี่ยงได้เป็นผู้ทดลองก่อน ส่วนผู้ที่ต้องการความเสถียรรอได้

Cargo cooldown ทำงานอย่างไร
เอกสาร Dependency Resolution ของ Cargo Book และ RFC 3923 อธิบายพฤติกรรมไว้ดังนี้
- รุ่นที่เวลาเผยแพร่ใหม่กว่าอายุขั้นต่ำถือว่าไม่ผ่านเงื่อนไข
- ถ้า
resolver.incompatible-publish-ageเป็น"deny"ซึ่งเป็นค่าเริ่มต้น resolver จะไม่เลือกรุ่นเหล่านั้น ยกเว้นรุ่นที่อยู่ใน Cargo.lock อยู่แล้ว - ถ้าไม่มีรุ่นใดผ่านทั้งเงื่อนไขเวอร์ชันและอายุขั้นต่ำ การ resolve จะ error คล้ายกรณีที่ทุกรุ่นถูก yank ในตัวอย่างของ RFC ข้อความ error บอกว่ารุ่นนั้นเผยแพร่มากี่วันและอายุขั้นต่ำคือเท่าไร
- ถ้าตั้งเป็น
"allow"Cargo จะไม่ตรวจเงื่อนไขนี้
ข้อ 3 สำคัญที่สุด Cargo cooldown ไม่ "ยอมแพ้" แล้วดึงรุ่นใหม่มาเองเพื่อให้ build ผ่าน ผู้ดูแลต้องตัดสินใจเองว่าจะลดเงื่อนไขเวอร์ชันลงหรือยกเว้นรุ่นนั้น ส่วนหน้า Configuration ระบุว่าการตั้งค่านี้จะถูกละไว้หาก registry ไม่รองรับข้อมูลเวลาเผยแพร่
ตัวอย่างเมื่อ Cargo cooldown ข้ามรุ่นใหม่
RFC 3923 ยกตัวอย่างโปรเจกต์ที่ตั้งอายุขั้นต่ำไว้ 14 วัน เมื่อสั่ง cargo update แล้ว crate ชื่อ some-package มีรุ่น 1.3.0 ที่เพิ่งเผยแพร่มา 2 วัน Cargo จะเลือกรุ่น 1.2.3 ที่เก่ากว่าแทน และแสดงในบรรทัดผลลัพธ์ว่ามีรุ่น 1.3.0 ให้ใช้แต่เพิ่งเผยแพร่เมื่อ 2 วันก่อน นักพัฒนาจึงเห็นว่ามีรุ่นใหม่รออยู่โดยไม่ต้องรับมันมาทันที
อีกกรณีคือเมื่อไฟล์ Cargo.toml กำหนดให้ต้องใช้รุ่น 1.3 ขึ้นไป แต่รุ่นที่ตรงเงื่อนไขทั้งหมดยังใหม่เกินกำหนด ในตัวอย่างของ RFC Cargo จะหยุดพร้อมคำแนะนำ 2 ทาง คือลดเงื่อนไขเวอร์ชันลงมาเป็นรุ่นที่เก่าพอ หรือ resolve ใหม่โดยตั้งค่ายกเว้นชั่วคราว ทีมจึงต้องเลือกเองอย่างรู้ตัวทุกครั้ง
Cargo cooldown เหมาะกับโปรเจกต์แบบไหน
ฟีเจอร์นี้ให้ผลชัดที่สุดกับแอปพลิเคชันและบริการที่ build จาก Cargo.lock ของตัวเอง เช่น บริการแบ็กเอนด์ เครื่องมือบรรทัดคำสั่ง หรือระบบที่ CI สั่ง cargo update อัตโนมัติเป็นประจำ เพราะจุดที่รุ่นใหม่เข้ามาคือการ resolve ครั้งใหม่ ซึ่ง Cargo cooldown ไปตรวจตรงนั้น
ส่วนทีมที่พัฒนาไลบรารีให้คนอื่นใช้ RFC เสนอให้คิดแบบผสม คือเปิดการรอสำหรับงานประจำวันเพื่อลดความเสี่ยง แต่มีงาน CI ที่ทำหน้าที่เป็น "นกขมิ้น" คอยทดสอบกับรุ่นล่าสุดเสมอ เพื่อให้รู้ปัญหาของ dependency ก่อนผู้ใช้ปลายทาง ทีมที่ต้องการความเสถียรสูงจะตั้งช่วงรอยาวขึ้นได้ โดยแลกกับการได้รับการแก้บั๊กช้าลง
ตั้งค่า Cargo cooldown ได้ที่ไหน
ค่าที่เกี่ยวข้องอยู่ในไฟล์ .cargo/config.toml ของโปรเจกต์หรือของผู้ใช้ และตั้งผ่านตัวแปรสภาพแวดล้อมได้ทุกค่า
| ค่า | ค่าเริ่มต้น | ตัวแปรสภาพแวดล้อม | ใช้ทำอะไร |
|---|---|---|---|
registry.global-min-publish-age |
"0" |
CARGO_REGISTRY_GLOBAL_MIN_PUBLISH_AGE |
อายุขั้นต่ำที่ใช้กับทุก registry |
registries.<name>.min-publish-age |
ใช้ค่า global | CARGO_REGISTRIES_<name>_MIN_PUBLISH_AGE |
อายุขั้นต่ำเฉพาะ registry นั้น เช่น registry ภายในองค์กร |
resolver.incompatible-publish-age |
"deny" |
CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE |
ข้ามรุ่นที่ใหม่เกิน (deny) หรือไม่ตรวจ (allow) |
ค่าอายุเขียนเป็นตัวเลขตามด้วยหน่วย seconds, minutes, hours, days, weeks หรือ months และ "0" คือยอมรับทุกรุ่น เอกสารบอกว่าที่ใช้กันทั่วไปคือ "0", "N days" และ "N weeks" ทุกค่าในตารางนี้มีผลตั้งแต่ Cargo 1.100 ตัวอย่างที่ RFC ใช้คือ
[registry]
global-min-publish-age = "14 days"
องค์กรที่มี registry ภายในซึ่งเชื่อถือได้ ตั้ง min-publish-age = "0" ให้ registry นั้นโดยเฉพาะได้ เพื่อให้ crate ของทีมเองใช้ได้ทันที

เมื่อต้องรีบใช้แพตช์ที่เพิ่งออก
กรณีที่ต้องใช้รุ่นใหม่ทันที เช่น รุ่นที่แก้ช่องโหว่ RFC 3923 ให้ตั้ง CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow ชั่วคราว แล้วสั่ง cargo update พร้อม --precise ระบุรุ่นที่ต้องการ เมื่อรุ่นนั้นถูกบันทึกใน Cargo.lock แล้ว การ resolve ครั้งต่อไปจะคงรุ่นนั้นไว้
RFC ยังเสนอรูปแบบที่ใช้ได้จริงในทีม คือเปิด Cargo cooldown สำหรับงานประจำวัน แต่มี CI job แยกที่ตั้ง allow แล้วรัน cargo update, build และ test กับรุ่นล่าสุดเสมอ ทีมจะรู้ล่วงหน้าว่ารุ่นใหม่ทำให้อะไรพังหรือไม่ โดยไม่ต้องให้ทุกเครื่องรับรุ่นใหม่ในวันแรก
Cargo cooldown ป้องกันอะไรได้ และไม่ได้
RFC 3923 เขียนไว้ตรง ๆ ว่าฟีเจอร์นี้ "ไม่ใช่ทางแก้ครบวงจร" สำหรับ dependency ที่ถูกเจาะ มันช่วยกับการโจมตีบางประเภทเท่านั้น และไม่ควรใช้เป็นมาตรการความปลอดภัยเพียงอย่างเดียว ข้อจำกัดที่ทีมควรรู้มีดังนี้
- ช่วยเฉพาะกรณีที่มีคน พบปัญหาภายในช่วงที่รอ ถ้ารุ่นอันตรายไม่ถูกพบเลยภายใน 7 หรือ 14 วัน การรอก็ไม่ช่วย
- แพตช์แก้ไขก็ถูกหน่วงด้วย รุ่นที่แก้บั๊กหรือช่องโหว่จะติดเงื่อนไขเดียวกัน จึงต้องมีขั้นตอนยกเว้นที่ทีมรู้วิธีใช้
- รุ่นที่ อยู่ใน Cargo.lock แล้ว จะไม่ถูกตรวจซ้ำ การตั้งค่าจึงมีผลกับการ resolve ครั้งใหม่ ไม่ได้ย้อนตรวจของที่ล็อกไว้
- ใช้ได้กับ registry ที่ให้ข้อมูลเวลาเผยแพร่ เท่านั้น

Rust 1.100 และ Cargo 1.100 มีอะไรอีก
นอกจาก Cargo cooldown changelog ของ Cargo 1.100 มีการเปลี่ยนแปลงที่ทีม Rust ควรรู้ก่อนอัปเกรด
- ระบบ lint ของ Cargo เป็นฟีเจอร์เสถียร คำเตือนบางอย่างของ Cargo กลายเป็น lint ที่ปรับระดับได้ในตาราง
[lints.cargo]ชุดแรกมีcargo::unused_dependenciesสำหรับตรวจ dependency ที่ประกาศไว้แต่ไม่ได้ใช้ - โครงสร้างโฟลเดอร์ของไฟล์ build ระหว่างทางเปลี่ยนใหม่ เครื่องมือที่อ่านโฟลเดอร์ build โดยตรงควรเปลี่ยนไปใช้ข้อความ JSON ของ Cargo เพราะโครงสร้างนี้ไม่ใช่อินเทอร์เฟซที่รับประกันว่าจะคงที่
cargo installใช้ lockfile ที่มากับแพ็กเกจเป็นค่าเริ่มต้น ตัวเลือก--lockedจึงไม่มีผลอีก- เมื่อตั้ง
build.warnings='deny'สรุปผล build จะรายงานจำนวน error ด้วย ไม่ใช่เฉพาะคำเตือน
| เหตุการณ์ | วันที่ |
|---|---|
| เริ่ม RFC 3923 | 23 ก.พ. 2026 |
| Rust 1.100 และ Cargo 1.100 พร้อม Cargo cooldown แบบเสถียร | 12 พ.ย. 2026 (กำหนดการ) |
ผลต่อองค์กรไทยและทีมพัฒนา
- กำหนดนโยบายอายุขั้นต่ำของ dependency ทีมที่ใช้ Rust ในบริการจริงควรตกลงว่าจะใช้กี่วัน แล้วใส่ใน
.cargo/config.tomlของ repository เพื่อให้ทุกเครื่องและ CI ใช้ค่าเดียวกันหลังอัปเกรดเป็น Rust 1.100 - เขียนขั้นตอนยกเว้นไว้ล่วงหน้า เมื่อมีแพตช์ช่องโหว่ด่วน ทีมต้องรู้ว่าจะใช้
CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allowกับcargo update --preciseอย่างไร และใครเป็นผู้อนุมัติ - แยก CI job ที่ทดสอบรุ่นล่าสุด ตามแนวทางใน RFC เพื่อไม่ให้ Cargo cooldown กลายเป็นการค้างรุ่นเก่าโดยไม่รู้ตัว
- ตั้งค่า registry ภายในแยก ถ้าองค์กรมี registry ของตัวเอง ให้ตั้ง
min-publish-ageเฉพาะ registry นั้นตามความเชื่อถือ - ใช้ร่วมกับมาตรการอื่น เช่น การรีวิว dependency และเครื่องมือกรองแพ็กเกจอย่าง GitHub package firewall สำหรับระบบนิเวศอื่น ติดตามข่าวเครื่องมือนักพัฒนาได้ที่หมวดการพัฒนาซอฟต์แวร์
คำถามที่พบบ่อย
Cargo cooldown คืออะไร?
Cargo cooldown คือการตั้งอายุขั้นต่ำของ crate รุ่นที่ Cargo จะยอมเลือกใช้ เช่น 7 วันหลังเผยแพร่บน registry เพื่อให้เวลาเครื่องสแกนและชุมชนพบปัญหาในรุ่นใหม่ก่อนที่ build ของเราจะดึงไปใช้ ตั้งค่าได้ด้วย registry.global-min-publish-age และจะเสถียรใน Rust 1.100 วันที่ 12 พฤศจิกายน 2026
อัปเกรดเป็น Rust 1.100 แล้ว Cargo cooldown เปิดเองหรือไม่?
ไม่เปิดเอง เอกสารของ Cargo ระบุว่าค่าเริ่มต้นของ registry.global-min-publish-age คือ 0 ซึ่งหมายถึงยอมรับทุกรุ่น ทีมต้องตั้งค่าเองใน .cargo/config.toml หรือผ่านตัวแปรสภาพแวดล้อม CARGO_REGISTRY_GLOBAL_MIN_PUBLISH_AGE
ถ้าต้องใช้แพตช์ความปลอดภัยที่เพิ่งออกแต่ติด Cargo cooldown ทำอย่างไร?
RFC 3923 ออกแบบทางยกเว้นไว้ โดยตั้ง CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE=allow ชั่วคราวแล้วสั่ง cargo update ระบุรุ่นที่ต้องการ เมื่อรุ่นนั้นถูกบันทึกใน Cargo.lock แล้ว การ resolve ครั้งต่อไปจะคงรุ่นนั้นไว้แม้ยังใหม่กว่าที่กำหนด
Cargo cooldown กันมัลแวร์ใน crate ได้ทั้งหมดไหม?
ไม่ได้ RFC 3923 เขียนไว้ชัดว่าเป็นเพียงการลดความเสี่ยงจากการโจมตีบางแบบที่มักถูกพบเร็วหลังเผยแพร่ ไม่ใช่ทางแก้ครบวงจร และไม่ควรใช้เป็นมาตรการความปลอดภัยเพียงอย่างเดียว ทีมยังต้องรีวิว dependency และสแกนโค้ดตามปกติ
แหล่งอ้างอิง
- Cargo Changelog — Cargo 1.100 (2026-11-12) — The Rust Project
- RFC 3923: cargo_min_publish_age — The Rust Project
- Configuration — The Cargo Book — The Rust Project
- Dependency Resolution — The Cargo Book — The Rust Project
บุคคล องค์กร และสถานที่ในข่าวนี้
เลือกชื่อเพื่ออ่านข่าวทั้งหมดที่กล่าวถึง ตัวเลขคือจำนวนข่าว
พบข้อมูลคลาดเคลื่อน? แจ้งกองบรรณาธิการ