ข้ามไปยังเนื้อหา

การอนุญาต — ใครทำอะไรได้ และคุณพิสูจน์เรื่องนี้อย่างไร

Control Center ตอบคำถามด้านการอนุญาตสองข้อ ซึ่งแตกต่างกันจริง ๆ “บุคคลนี้เรียกใช้การดำเนินการนี้ได้หรือไม่?” เป็นเรื่องของคน บทบาท และรีโป ส่วน “เอเจนต์นี้ก่อให้เกิดผลลัพธ์นี้ได้หรือไม่?” เป็นเรื่องของการกระทำ อาร์กิวเมนต์ และขอบเขตความเสียหาย — ข้อหลังอยู่ในกฎคุม

หน้านี้ว่าด้วยคำถามข้อแรก พร้อมทั้งบันทึกที่ทั้งสองข้อทิ้งไว้เบื้องหลัง

การตัดสินด้านการอนุญาตฝั่งมนุษย์ทุกครั้งตัดสินผ่านฟังก์ชันเดียว:

can(principal, permission, resource) → allow | deny + why

สิทธิ์หนึ่งรายการเขียนเป็น <domain>:<tier> — tickets:write, members:administer, repos:read แค็ตตาล็อกนี้ถูกอนุมานขึ้นมา ไม่ได้เขียนด้วยมือ: มันคำนวณจากพื้นผิวการดำเนินการเอง (คำนำหน้าชื่อ op บอก domain ส่วนบทบาทขั้นต่ำที่ op บังคับใช้อยู่แล้วบอกระดับ) การดำเนินการทั้งหมดราว 550 รายการจึงมีสิทธิ์กำกับอยู่ โดยไม่มีใครต้องพิมพ์กำหนดแม้แต่รายการเดียว

การอนุมานเช่นนี้คือคุณสมบัติที่คุ้มค่าแก่การปกป้อง มันหมายความว่าการดำเนินการใหม่ถูกกั้นไว้โดยค่าเริ่มต้น — จุดล้มเหลวของโมเดลที่กำกับด้วยมือคือมีใครสักคนลืม และสิ่งที่เขาลืมก็คือด่านกั้นนั่นเอง มีการทดสอบแบบแรตเช็ตที่ตรึงชุดโดเมนอันเป็นผลลัพธ์ไว้ การเพิ่มการดำเนินการภายใต้คำนำหน้าใหม่จึงเป็นการตัดสินใจตั้งชื่อที่มนุษย์ตั้งใจเลือก ไม่ใช่ความบังเอิญ

ระดับทั้งสี่แมปกับบทบาทในตัวแบบพอดี:

ระดับ บทบาทขั้นต่ำ ตัวอย่าง
read แขก tickets:read
write สมาชิก tickets:write
administer แอดมิน members:administer
own เจ้าของ workspace:own

บทบาทในตัวห้าบทบาท — เจ้าของ, แอดมิน, สมาชิก, ผู้ดู, แขก — เป็นพรีเซ็ตบนแค็ตตาล็อกนั้น ความเป็นเจ้าของมีได้เพียงตำแหน่งเดียวต่อเวิร์กสเปซ และโอนกันอย่างชัดเจนด้วย โอนความเป็นเจ้าของ (เจ้าของที่จากไปจะลบออกไม่ได้เลยหากไม่ทำเช่นนั้น: การถอนผู้ใช้ด้วย SCIM ปฏิเสธเจ้าของเวิร์กสเปซทุกคน — ต้องโอนก่อน)

บทบาทที่กำหนดเองทำงานแบบลบออก บทบาทที่กำหนดเองระบุพรีเซ็ตฐาน (admin, member, viewer หรือ guest — ไม่มีทางเป็น owner) พร้อมชุดสิทธิ์ที่ถูกนำออกจากพรีเซ็ตนั้น — “เป็นแอดมิน แต่จัดการสมาชิกไม่ได้” มันให้สิทธิ์เกินฐานไม่ได้เลย นี่คือเหตุผลที่นำมาใช้กับระบบที่ติดตั้งอยู่แล้วได้อย่างปลอดภัย: การตรวจสอบเดิมทุกจุดยังคงเป็นขอบเขตบนที่เชื่อถือได้ สมาชิกถือบทบาทเหล่านี้ในชื่อ custom:<id> และไคลเอนต์ที่เก่าเกินกว่าจะเข้าใจค่านั้นจะถอยกลับไปใช้แขกแทนที่จะเดา

ใต้บทบาทลงไปคือสิทธิ์ระดับรีโป (none / read / review / write): การเป็นสมาชิกเวิร์กสเปซไม่เคยให้สิทธิ์เหนือกว่าโฮสต์โค้ดอย่างเงียบ ๆ ทุกพื้นผิวที่เปิดให้เข้าถึงโค้ดจะตรวจสอบสิทธิ์เหล่านี้ — รวมถึงเส้นทางที่เข้าถึงโค้ดทางอ้อม เช่นเทอร์มินัลหรือเซสชันตัวแก้ไขที่เปิดบน worktree ของสเปซ

บางการดำเนินการไม่เกี่ยวกับเวิร์กสเปซเลย: การตั้งค่าระดับทั้งการติดตั้ง, การกำหนดค่า SSO, ข้อมูลรับรองของผู้ให้บริการ, การจัดการโมเดล, การสำรองข้อมูลทั้งการติดตั้ง การดำเนินการเหล่านี้ประกาศอำนาจของเซิร์ฟเวอร์ และถูกปฏิเสธสำหรับทุกคนยกเว้นผู้ดำเนินการของการติดตั้ง (เจ้าของเซิร์ฟเวอร์ที่บันทึกไว้) โดยเจตนาแล้วมีตัวตนของผู้ดำเนินการเพียงหนึ่งเดียว และมีนิยามของมันเพียงหนึ่งเดียว

การตัดสินด้านการอนุญาตทุกครั้ง — ทั้งการอนุญาตและการปฏิเสธ — ถูกต่อท้ายลงในร่องรอยการตรวจสอบแบบผูกด้วยแฮชของแต่ละเวิร์กสเปซ

ล็อกที่บันทึกแต่การปฏิเสธตอบได้แค่ว่า “เราบล็อกอะไรไปบ้าง?” แต่ตอบไม่ได้ว่า “เอเจนต์นี้ทำอะไรไปจริง ๆ และใครอนุญาต?” ซึ่งเป็นคำถามตั้งต้นของการทบทวนเหตุการณ์ ดังนั้นแต่ละรายการจึงบันทึกสายการอ้างอิงที่มาที่ไปอย่างครบถ้วน: ตัวตนผู้ลงมือ, มนุษย์ที่มันลงมือแทน, การมอบอำนาจที่ทำให้มันเข้ามา, การกระทำและอาร์กิวเมนต์ของมัน (ในรูปไดเจสต์), การตัดสิน และกฎที่ใช้ตัดสิน

รายการต่าง ๆ ถูกต่อเป็นโซ่: แฮชของแต่ละรายการครอบคลุมแฮชของรายการก่อนหน้า การแก้ไข ลบ หรือสลับลำดับแถวใด ๆ จึงทำให้แฮชทุกตัวหลังจากนั้นขาด ตรวจสอบโซ่จะคำนวณใหม่ทั้งชุดและระบุจุดเชื่อมแรกที่ไม่ผ่าน ล็อกตรวจสอบที่คุณตรวจสอบไม่ได้ก็เป็นแค่ล็อก แต่ล็อกที่คำนวณซ้ำได้คือหลักฐาน

ผลที่ตามมาสองข้อที่ควรรู้:

  • ตารางตรวจสอบได้รับการยกเว้นจากการตัดทิ้งตามอายุ โซ่แฮชตัดออกจากตรงกลางไม่ได้ การเก็บรักษาคือนำออกก่อนแล้วจึงตัดทอน และการตัดทอนจะทิ้งจุดตรวจที่พกแฮชปลายทางของช่วงที่ถูกนำออกไว้ ทำให้ส่วนที่เหลือยังตรวจสอบย้อนกลับไปถึงต้นทางได้
  • มันวางอยู่เคียงข้างไทม์ไลน์กิจกรรม ไม่ได้ทับซ้อนอยู่บนนั้น ไทม์ไลน์คือสิ่งที่คนทำ ส่วนนี่คือสิ่งที่ถูกอนุญาตและถูกปฏิเสธ correlation id ที่ใช้ร่วมกันทำให้อ่านการเรียกหนึ่งครั้งได้จากทั้งสองที่

มันส่งออกเป็น JSON ที่คั่นด้วยบรรทัดใหม่ และสตรีมไปยัง SIEM ได้ (Splunk, Elastic, Sentinel — ปลายทาง HTTP พร้อม bearer token) โดยเจตนาออกแบบให้การสตรีมเป็นแบบพยายามให้ได้มากที่สุด: SIEM ล่มต้องไม่บล็อกการเรียกเครื่องมือของเอเจนต์ไม่ว่ากรณีใด และสำเนาถาวรที่ตรวจสอบได้ก็อยู่บนดิสก์อยู่แล้วทั้งสองทาง

การติดตั้งหนึ่งแห่งกำหนดอายุเซสชันสูงสุดและเวลาหมดอายุเมื่อไม่ใช้งานได้ ทั้งสองอย่างถูกบังคับใช้ที่จุดตรวจข้อมูลรับรองอุปกรณ์ ซึ่งทุกช่องทางที่ผ่านการยืนยันตัวตนต้องผ่านจุดนี้ — ขอบเขตเซสชันที่ไคลเอนต์เพิกเฉยได้นั้นตอบได้แค่แบบสอบถาม ไม่ได้ตอบโจมตี การติดตั้งยังบังคับให้ใช้ SSO ได้ด้วย ซึ่งจะปิดการจับคู่ด้วยตนเองสำหรับอุปกรณ์ใหม่ (พร้อมการกันการล็อกเอาต์: มันจะปฏิเสธตราบใดที่ยังไม่มีการเชื่อมต่อ SSO ที่ใช้งานได้)

  • ไม่ใช่ ACL ระดับวัตถุ โดยเจตนาแล้วไม่มีสิทธิ์ระดับตั๋วงานหรือระดับข้อความ การแยกระดับรีโปคือสิ่งที่ทีมขอมาจริง และมีอยู่แล้ว ส่วนการแชร์ระดับวัตถุเป็นพื้นผิวที่ต้องจัดการชุดค่าผสมมากมายโดยยังไม่มีความต้องการที่พิสูจน์ได้ในที่นี้
  • ไม่ใช่เอนจินนโยบายที่คุณกำหนดค่าด้วย DSL คำศัพท์ถูกปิดไว้โดยเจตนา นโยบายทั้งหมดจึงแสดงผล อธิบาย และแจกแจงได้
  • ไม่ถูกบังคับใช้ที่ใดนอกจากเซิร์ฟเวอร์ การตรวจสอบฝั่งไคลเอนต์มีอยู่เพียงเพื่อไม่ให้เสนอตัวควบคุมที่จะถูกปฏิเสธ การตัดสินที่มีผลชี้ขาดเป็นของเซิร์ฟเวอร์เสมอ