ต่อระบบ
Permission manifest
ประกาศสิ่งที่แอปอนุญาตได้ ส่งเทมเพลต role และ sync จากคอนโซลหรือ pipeline deploy
manifest คือวิธีที่แอปบอก Pi Auth ว่าในแอปมีอะไรให้อนุญาตได้บ้าง permission เป็นข้อความธรรมดาที่แอปตรวจเอง ส่วนเทมเพลต role ให้องค์กรมีจุดเริ่มที่สมเหตุสมผล sync ทุกครั้งที่ permission ของแอปเปลี่ยน — ปกติทำตอน deploy
โครงของ manifest
{
"application": "AOWrBtppsYLxThsohmXWS7JjCknWiog9",
"name": "Pi PDF",
"permissions": [
{ "key": "pdf:use", "name": "ใช้งาน Pi PDF", "risk": "LOW" },
{ "key": "pdf:admin", "name": "ดูแล Pi PDF", "description": "จัดการเทมเพลตและการตั้งค่า", "risk": "HIGH" }
],
"roleTemplates": [
{ "key": "pdf-user", "name": "ผู้ใช้ Pi PDF", "permissions": ["pdf:use"] },
{ "key": "pdf-admin", "name": "ผู้ดูแล Pi PDF", "permissions": ["pdf:use", "pdf:admin"] }
]
}| ฟิลด์ | กติกา |
|---|---|
application | ตัวกันพลาด (ไม่บังคับ): ใส่ได้เฉพาะเมื่อตรงกับ client_id (หรือ softwareId) ของแอปที่ sync — ไม่ตรงจะถูกปฏิเสธ 400; แอปที่มีหลาย client เช่น dev/prod ให้ละไว้ |
permissions[].key | รูปแบบ app:action ตัวพิมพ์เล็ก ต่อท้ายด้วยจุดได้ — เช่น memo:approve, memo:report.export ยาว 3–64 ตัวอักษร สูงสุด 500 รายการต่อแอป |
permissions[].name / description | แสดงให้ผู้ดูแลเห็นในคอนโซลตอนสร้าง role |
permissions[].risk | LOW (ค่าเริ่มต้น) หรือ HIGH — สิทธิ์ HIGH ถูกเน้นในคอนโซลให้ผู้ดูแลสังเกตเมื่อ role ให้สิทธิ์นั้น |
roleTemplates[] | role แนะนำ เมื่อองค์กรติดตั้งแอปจะได้ role สำเร็จรูปเหล่านี้ไว้ผูกหรือแก้ต่อ |
ประกาศ permission ครั้งเดียว แล้วให้ Pi Auth ดึง
ประกาศ permission ครั้งเดียวในโค้ด ได้ทั้ง key แบบ type-safe และ manifest สำหรับ Pi Auth ไม่ต้องแก้ไฟล์ JSON ซ้ำหรือสร้าง cron เพื่อ sync
import { definePermissions } from "@suphark/auth-client/manifest";
export const P = definePermissions(
{
"memo:create": { name: "สร้างเอกสาร" },
"memo:approve": { name: "ลงนามอนุมัติ", risk: "HIGH" },
},
{
roleTemplates: { "memo-approver": { name: "ผู้อนุมัติ", permissions: ["memo:create", "memo:approve"] } },
autoApplyTemplates: true, // องค์กรที่ติดตั้งได้ role จากเทมเพลตทันที
},
);
// ในโค้ด — key พิมพ์ผิดเป็น type error
piAuth.hasPermission(user, P.keys["memo:approve"]);import { createPiAuth } from "@suphark/auth-client/next";
import { P } from "./permissions";
export const piAuth = createPiAuth({
manifest: P.manifest, // หรือส่ง P ตรงๆ
// ...
});
// ใน app/auth/[...pi]/route.ts
// export const { GET, POST } = piAuth.handlers;
// Route GET /auth/manifest จะเปิดให้อัตโนมัติ ไม่ต้องสร้าง route แยกถ้าแอปมี proxy บังคับล็อกอิน ให้เพิ่ม /auth/manifest ใน public paths เพื่อให้ endpoint คืน JSON โดยไม่ redirect ไปหน้าเข้าสู่ระบบ
ลงทะเบียนแอปใน Pi Auth เลือก “มี permission แล้ว” ใส่ base URL ของแอป เช่นhttps://app.example.com แล้วกด “ทดสอบและ Sync” Pi Auth จะดึง JSON จาก/auth/manifest เมื่อ permission เปลี่ยนให้กลับมากด Sync อีกครั้ง แอปที่ยังไม่มี permission เลือก “เพิ่มภายหลัง” ได้
แอปแบบ confidential ยัง Push manifest ชุดเดียวกันด้วย client_id และ client_secret ไปที่POST /api/apps/manifest หลัง deploy ได้ แอปแบบ public ใช้ Pull ทั้งสองทางไม่ต้องส่ง heartbeat รายวัน Pi Auth อัปเดตเวลาการใช้งานผ่าน OIDC token traffic ให้อัตโนมัติ
ประกาศ webhook ในโค้ด · ตรวจสิทธิ์แบบ type-safe · เริ่มโปรเจกต์ใหม่
export const P = definePermissions({ ... }, {
// Pi Auth ลงทะเบียน webhook endpoint ให้ทุกองค์กรที่ติดตั้งแอป (path ต่อท้าย APP_URL) — ตรวจลายเซ็น JWS ไม่ต้องมี secret
webhook: { path: "/api/pi-auth/webhook", events: ["membership.created", "membership.left", "role.binding.changed"] },
});
// ตรวจสิทธิ์ด้วย key ชุดเดียวกันทั้ง server และ client component
P.can(await piAuth.getCurrentUser(), "memo:approve"); // server
P.can(useUser().user, "memo:approve"); // client ("memo:aprove" = type error)แอปใหม่: npx pi-auth init สร้าง lib/pi-auth.ts, lib/permissions.ts, app/auth/[...pi]/route.ts, app/api/pi-auth/webhook/route.ts, proxy.ts และเติม .env.example ให้ (ไม่ทับไฟล์เดิม เว้นแต่ใส่ --force) proxy ที่สร้างให้เปิดทางสาธารณะไปยัง /auth/manifest ด้วย
ทางอื่นในการ sync
จากคอนโซล (App setup)
platform admin เปิด Platform → Applications → ตั้งค่า → Permissionใส่ base URL แล้วกด “ทดสอบและ Sync” Pi Auth ตรวจ manifest และแสดงผลที่เปลี่ยน เจ้าของแอปทำแบบเดียวกันจากหน้า Access ของแอปได้
ตอน build (ไม่ต้องกดปุ่ม)
แอปที่เก็บ manifest เป็นไฟล์
pi-auth.manifest.jsonใส่ CLI ของ SDK ไว้ก่อน build ทุกครั้งที่ deploy สิทธิ์ใน Pi Auth จะตรงกับโค้ดเอง (ใช้ client id/secret ของแอป ไม่ต้องมี service account)package.json"scripts": { "prebuild": "pi-auth manifest sync --optional" }--optional(SDK 0.8.3+): ไม่มี envPI_AUTH_*(เช่น build preview) หรือ Pi Auth ไม่ตอบ = เตือนแล้ว build ต่อ; manifest ผิดรูปแบบยังทำให้ build ล้มจาก pipeline deploy
สร้าง service account ของแอปที่มี scope
application.manifestแล้ว POST manifest ด้วย service token ของมัน:POST /api/v1/applications/{clientId}/manifestcurl -X POST https://auth.suphark.com/api/v1/applications/$CLIENT_ID/manifest \ -H "Authorization: Bearer $SERVICE_TOKEN" \ -H "Content-Type: application/json" \ --data @manifest.json
sync แล้วเกิดอะไร
- key ใหม่ถูกเพิ่ม; ชื่อ คำอธิบาย และ risk ถูกอัปเดตในที่
- key ที่หายไปจาก manifest ใหม่ถูกทำเครื่องหมาย deprecated ไม่ได้ลบ: role เดิมยังใช้ได้ คอนโซลแสดงขีดฆ่า และ role ใหม่เลือกไม่ได้ เอาออกจาก role แล้วมันจะหายจากโทเค็น
- เทมเพลต role ถูกอัปเดต; role ที่องค์กรสร้างจากเทมเพลตไปแล้วไม่ถูกแตะ
ติดตั้งในองค์กร
ผู้ดูแล tenant เปิด สิทธิ์ → แอปที่ติดตั้ง แล้วติดตั้งแอป จากนั้น permission ของแอปจะปรากฏตอนสร้าง role เทมเพลตพร้อมใช้ และสมาชิกล็อกอินเข้าแอปได้ ถอนการติดตั้งแล้วทั้งสองอย่างหยุด: role เสีย permission ของแอปนั้น และการล็อกอินถูกปฏิเสธ