# 認証・Cookie ポリシー

監査 P0 (S3 / 2026-04-26) 確認結果と恒久ポリシー。

## 結論

**Parky 全レイヤーは Bearer JWT のみで認証する。Set-Cookie / Cookie ヘッダは一切使わない。**
よって S3 (Cookie 属性: `Secure; HttpOnly; SameSite=Lax`) は **適用対象なし** で no-op。

## 検証 (2026-04-26)

| 対象 | 検証 | 結果 |
|---|---|---|
| BFF (`parky/api/src/**`) | `setCookie` / `Set-Cookie` / `c.req.header("Cookie")` を grep | **0 件** |
| Admin / Owner / Marketing portal | `@supabase/ssr` / `cookies.set` を grep | **0 件** (`@supabase/supabase-js` の localStorage ベース) |
| Home (Astro SSR) | `@supabase/ssr` / `setCookie` を grep | **0 件** (SSR は anon-only でセッションを Cookie に持たない) |
| Flutter | `flutter_secure_storage` で JWT 保管 | OK |

## 認証フロー (再確認)

```
Mobile / Portal (Browser)
  ├─ Supabase Auth で sign-in → JWT 取得
  │   - Mobile: flutter_secure_storage (iOS Keychain / Android Keystore)
  │   - Portal: @supabase/supabase-js が localStorage に保管 (SPA, 同一 origin 内)
  └─ 全 BFF リクエストで `Authorization: Bearer <jwt>` 送信
        ↓
BFF (parky/api)
  └─ middleware/auth.ts が JWT を JWKS で検証 → c.set("userId", sub) etc.
```

## ポリシー (恒久ルール)

1. **新規 endpoint で `Set-Cookie` を出さない**。 セッション継続が必要な機能は JWT refresh で対応。
2. **portal で `@supabase/ssr` を導入しない**。SSR で session を持つと CSRF / SameSite 議論が発生する。
   現状 SPA + Bearer は CSRF 影響を受けない (Cookie ベース session でないため)。
3. **Astro home は anon-only SSR**。ユーザー固有データ取得は client-side で BFF を Bearer 付きで叩く。
4. **どうしても Cookie が必要になったら**:
   - 必ず `Secure; HttpOnly; SameSite=Lax` (auth) / `SameSite=Strict` (state) を付与
   - 同一サイト送信のみ許容、第三者 origin の embed では送らない
   - `Path` を最小スコープに、`Domain=parky.co.jp` は基本付けない (subdomain 流出防止)
   - 本書を更新し、ポリシー変更を記録する

## 関連

- [parky/api/src/middleware/auth.ts](../../api/src/middleware/auth.ts) — JWT 検証
- [parky/api/src/middleware/owner-context.ts](../../api/src/middleware/owner-context.ts) — owner Auth + RLS
- [parky/api/CLAUDE.md](../../api/CLAUDE.md) §7 — 認可・セキュリティ
