# บทเรียน 06 — สร้าง Cloudflare API token แบบกำหนดสิทธิ์เฉพาะงาน

บทก่อนหน้าเว็บของเราสมบูรณ์บนเครื่องแล้ว ขั้นถัดไปคือขึ้นอินเทอร์เน็ตจริง — แต่ก่อนสั่ง deploy เราต้องเตรียม **Cloudflare API token** ให้ agent ใช้ก่อน

บทนี้ไม่ได้อยู่ใน session จริงของ “เล ไปกัน” (agent สั่ง deploy ด้วย token ที่เตรียมไว้แล้วใน `.env`) แต่เป็น **ขั้นเตรียมที่ทำบนเครื่องเรา** และเป็นจุดที่ความปลอดภัยเริ่มต้น: token ที่ดีคือ token ที่ **ทำได้เฉพาะงานที่จำเป็น ไม่เกินความจำเป็น** (principle of least privilege)

เป้าหมายของบทนี้: ได้ token หนึ่งตัวที่ deploy เว็บ + ผูกโดเมนได้ แต่แตะอย่างอื่นในบัญชีไม่ได้เลย

## ทำไมต้องสร้าง token เอง ไม่ใช้ Global API Key

| วิธี | ขอบเขต | ความเสี่ยง |
| --- | --- | --- |
| **Global API Key** | ทุกอย่างในบัญชี ทุก zone ทุกบริการ แก้-ลบได้ไม่จำกัด | รั่วตัวเดียว = เสียบัญชีทั้งบัญชี และ rollback ไม่ได้ |
| **API token (custom)** | เฉพาะ permission ที่เลือก เฉพาะ account/zone ที่กำหนด ตั้งวันหมดอายุได้ เพิกถอนแยกตัวได้ | รั่วแค่ตัวเดียว = กระทบเฉพาะงานนั้น |

สรุป: ใช้ custom token เสมอ และกำหนดสิทธิ์ให้แคบที่สุดที่ยัง deploy งานได้

## สิทธิ์ที่ต้องใช้ (จาก token จริงของ workshop นี้)

token ที่ใช้ deploy “เล ไปกัน” มีหน้า summary ตามนี้ — เราจะสร้าง token ของตัวเองให้ได้ตารางแบบเดียวกัน:

| ขอบเขต | Permission | ทำไมต้องมี |
| --- | --- | --- |
| **Rawinnipa.soft@gmail.com's Account** (Account) | D1 : Edit | สร้าง/แก้ไขฐานข้อมูล D1 ที่เว็บใช้ |
| | Workers Scripts : Edit | upload และ deploy ตัว Worker ของเว็บ |
| **rawinlab.com** (Zone) | DNS Settings : Edit | ปรับการตั้งค่า DNS ของโซน |
| | Zone : Read | ค้นหา/อ่านข้อมูลโซน (wrangler ต้องอ่านก่อนแตะเสมอ) |
| | Workers Routes : Edit | ผูก route และ custom domain ให้ Worker |
| | DNS : Edit | สร้าง/แก้ DNS record เมื่อผูกโดเมนใหม่ |
| **All users** (User) | Memberships : Read | ให้ wrangler ตรวจว่าเราเป็นสมาชิกบัญชีใดบ้าง |
| | User Details : Read | ให้คำสั่งอย่าง `wrangler whoami` ตรวจตัวตนได้ |

สังเกตว่าไม่มี permission แบบ Delete หรือ Admin ปนอยู่ — แม้ token รั่ว ผู้ที่ได้ไปก็แค่ deploy เว็บต่อได้ แต่ลบบัญชีหรือแตะ zone อื่นไม่ได้

## สร้าง token ทีละขั้น

### 1. เปิดหน้า API Tokens

1. เข้าสู่ระบบ [dash.cloudflare.com](https://dash.cloudflare.com/)
2. คลิกไอคอนโปรไฟล์ (มุมขวาบน) → **My Profile**
3. เลือกแท็บ **API Tokens** → ปุ่ม **Create Token**

### 2. เลือกแบบ Custom Token

ที่หัวข้อ “Custom Tokens” กด **Get started** — เราจะกำหนดสิทธิ์เองทุกช่อง (template สำเร็จรูปอย่าง “Edit Cloudflare Workers” ใกล้เคียงแต่ไม่ตรง และมักให้เกินที่จำเป็น)

ตั้งชื่อ token ให้รู้เรื่อง เช่น `lay-pai-gun-deploy`

### 3. กรอก Permissions ให้ครบ 3 กลุ่ม

ที่ตาราง **Permissions** เพิ่มทีละแถวจนครบตามตารางด้านบน — แต่ละแถวคือ [ขอบเขต] / [ชื่อรายการ] / [ระดับ]:

| # | ช่องแรก | ช่องกลาง | ช่องสุดท้าย |
| --- | --- | --- | --- |
| 1 | Account | D1 | Edit |
| 2 | Account | Workers Scripts | Edit |
| 3 | Zone | DNS Settings | Edit |
| 4 | Zone | Zone | Read |
| 5 | Zone | Workers Routes | Edit |
| 6 | Zone | DNS | Edit |
| 7 | User | Memberships | Read |
| 8 | User | User Details | Read |

### 4. กำหนด Account Resources และ Zone Resources

- **Account Resources**: Include → *Specific account* → `Rawinnipa.soft@gmail.com's Account`
- **Zone Resources**: Include → *Specific zone* → `rawinlab.com`

จุดนี้คือหัวใจของ least privilege — ถ้าเลือก “All accounts” หรือ “All zones” token ตัวนี้จะไปแตะงานอื่นในบัญชีได้ด้วย

### 5. (แนะนำ) จำกัดอายุและ IP

- **TTL**: ตั้ง Start / End Date ตามอายุโปรเจกต์ หรืออย่างน้อยตั้ง End Date ไว้เผื่อลืมเพิกถอน
- **Client IP Address Filtering**: ถ้า deploy จากเครื่อง/IP คงที่ ใส่ได้ยิ่งดี

### 6. ตรวจ summary แล้วสร้าง

1. กด **Continue to summary** — Cloudflare จับตารางสิทธิ์ทั้งหมดให้ดูอีกครั้ง รูปแบบเดียวกับตาราง “สิทธิ์ที่ต้องใช้” ด้านบน
2. ไล่เช็กว่าไม่มีแถวไหนเกิน แล้วกด **Create Token**
3. หน้าถัดไปแสดงค่า token **ครั้งเดียวเท่านั้น** — คัดลอกทันที ปิดหน้าแล้วย้อนไม่ได้ (ต้องสร้างใหม่)

### 7. เก็บ token ลง `.env` ทันที

```bash
# ในโฟลเดอร์โปรเจกต์ (ไฟล์ .env — ต้องอยู่ใน .gitignore)
CLOUDFLARE_API_TOKEN=คัดลอกค่าที่ได้มาวางตรงนี้
```

ห้ามวาง token ใน chat ในคอมเมนต์โค้ด หรือในรูปภาพ — ใช้แล้วให้ agent อ่านจาก `.env` เท่านั้น

## ตรวจว่า token ใช้งานได้

ก่อนส่งต่อให้ agent ทดสอบเองสองคำสั่ง (ไม่ต้องส่ง token ให้ใคร):

```bash
# 1) ตรวจกับ Cloudflare โดยตรง — ต้องได้ "status": "active"
curl https://api.cloudflare.com/client/v4/user/tokens/verify \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

# 2) ให้ wrangler อ่านสิทธิ์ — ต้องเห็นบัญชีและ permission ตรงตามที่ตั้งไว้
npx wrangler whoami
```

ถ้า `wrangler whoami` แจ้ง permission ไม่ครบตามตาราง หรือ deploy แล้วเจอ `authentication error` / `not authorized` ให้กลับมาดูหน้า summary ของ token ว่าขาดแถวไหน — แก้ที่ **API Tokens → จุดสามจุดข้าง token → Roll** (แก้สิทธิ์แล้วได้ค่าใหม่) หรือสร้างใหม่แล้วเพิกถอนตัวเก่า

## ข้อควรระวัง

| ข้อ | เหตุผล |
| --- | --- |
| **เห็น token ครั้งเดียว** | Cloudflare ไม่แสดงซ้ำ — คัดลอกใส่ `.env` ทันทีก่อนปิดหน้า |
| **เพิกถอนทันทีเมื่อสงสัย** | API Tokens → Delete ตัวทันที แล้วสร้างใหม่ — เร็วกว่าไล่ดูว่ามันไปทำอะไร |
| **หนึ่งโปรเจกต์ หนึ่ง token** | อย่าใช้ token เดียวร่วมกันหลายงาน เพราะ scope จะกว้างขึ้นเอง |
| **สิทธิ์ขาดดีกว่าสิทธิ์เกิน** | ตอน deploy ติด error เพราะขาด permission แก้เพิ่มทีหลังได้ แต่สิทธิ์ที่ให้เกินไปแล้วไม่มีใครเตือน |

## สรุป

ตอนนี้ `.env` ของเรามี token ที่ deploy Worker + D1 ได้ ผูก route และ DNS บนโซน `rawinlab.com` ได้ และอ่านข้อมูลผู้ใช้/สมาชิกพอให้ wrangler ทำงาน — ครบทุกอย่างที่ agent ต้องใช้ในบทถัดไป โดยไม่เผื่อสิทธิ์เกินแม้แต่รายการเดียว

ต่อไป: [บท 07 — deploy ขึ้น Cloudflare ด้วย API token](07-deploy-cloudflare.md)
