---
name: feedback-scrapbox-pat-write-rejected-2026-06-30
description: Scrapbox PAT (Personal Access Token) は read-only 設計、 write endpoint (/api/page-data/import/) は HTTP 403 PersonalAccessTokenNotAllowedError で拒否される — 2026-06-30 verify。 publish-paper-to-scrapbox.ts fix path は @cosense/std WebSocket 経由か HTML scrape CSRF 取得経路の二択。
metadata: 
  node_type: memory
  type: feedback
  originSessionId: af1ab23c-b41d-4c41-9589-65cdb46779f8
---

# Scrapbox PAT write 拒否 — 2026-06-30 finding

## Rule

**Scrapbox の Personal Access Token (PAT, `x-personal-access-token` header) は read-only 設計**。 write endpoint (`/api/page-data/import/{project}.json`) は intentional access control で **HTTP 403 拒否**:

```
{"name":"PersonalAccessTokenNotAllowedError",
 "message":"This endpoint is not available via Personal Access Token."}
```

**Why:** PAT は寿命が長い (revoke するまで有効) ため漏洩時 damage を read のみに限定する設計判断 (推測、 公式説明なし)。 Write operation は session cookie + CSRF token 認証経路 (UI Import Pages button 使用時) のみ受理。

**How to apply:**
- Scrapbox publish 自動化を提案するとき、 PAT で write を試みる path は時間の無駄、 最初から WebSocket または UI 手動経路を提示
- `publish-paper-to-scrapbox.ts` 現状実装は `/api/users/me` 経由 CSRF 取得を試みるが、 Scrapbox が `/api/users/me` response から `csrfToken` field を削除 (2026 年中の schema change)、 結果 5 連続失敗 pattern が `[[feedback-publishing-rate-limit-platform-side-risk-2026-06-27]]` で記録済
- Fix path 候補 (4 つ articulate):
  - A. PAT 作成 + read-test → write-test で確証 (本 session で reject 確証済)
  - B. CSRF token を別経路 (HTML meta scrape) で取得 → fragile (scrape 対象 schema 変更で同 issue 再発 risk)
  - C. `@cosense/std` WebSocket API 全面移行 → long-term solution, 1-2 時間 work + npm install
  - D. UI manual import で個別 paper 対応 → 手動 work

## 本 session verify

```javascript
// Read test: ✅ PASS
GET https://scrapbox.io/api/pages/rei-aios/Nobuki%20Fujimoto/text
Header: x-personal-access-token: pat_0675a6ee...e7bf16591
→ HTTP 200, page text returned

// Write test: ✗ FAIL
POST https://scrapbox.io/api/page-data/import/rei-aios.json
Header: x-personal-access-token: pat_0675a6ee...e7bf16591
Body: multipart/form-data with JSON page data
→ HTTP 403, PersonalAccessTokenNotAllowedError
```

藤本さん作成 PAT は read 補助 utility (publish 後 page 存在 verify 等) として .env 保持、 write には使わない。

## Search context (検索容易性)

- Keywords: "Scrapbox PAT write rejected", "PersonalAccessTokenNotAllowedError", "/api/page-data/import 403"
- Related: [[feedback-publishing-rate-limit-platform-side-risk-2026-06-27]] (Scrapbox CSRF 5 連続失敗 pattern 親)
- Related: [[feedback-github-gist-channel-setup-2026-06-30]] (Scrapbox 代替として確立)
- Related: [[project-session-2026-06-30-full-arc]] (本 finding を生んだ session)

## Web reference

- Cosense Help Importing and exporting data: REST API は read-only と明記、 write は UI / WebSocket
- @cosense/std (JSR) — WebSocket-based write API
- Scrapbox の Importing JSON は UI manual のみ → API 化したのが内部 endpoint `/api/page-data/import/`
