---
title: "Supabase public bucket：誰がファイルを読めるか"
description: "SupabaseのStorageバケットを公開にすると何が変わり、何が変わらないのか。公開と非公開のバケットでローカルテストが返した結果と、使い分けを紹介します。"
url: "https://madsalt.tech/ja/notes/supabase-public-bucket/"
author: "Denys Zaichenko"
author_url: "https://madsalt.tech/ja/about/"
language: "ja"
published: 2026-11-04
---

# Supabase public bucket：誰がファイルを読めるか

TL;DR

公開バケットは、URLを知っている誰にでも、キーもログインもなしでバケット内のすべてのファイルを提供します。ダウンロードでは、あなたのstorageポリシーは参照されません。私のローカルスタックでは、同じテストファイルが、公開バケットでは内容付きの`200`を、非公開バケットでは`400`を返しました。アップロード、削除、移動は、引き続きポリシーを通ります。公開バケットはアバターや記事の画像のように本来公開されるファイルに使い、それ以外は非公開バケットと署名付きURLを使ってください。

私の無料の[Supabaseセキュリティチェッカー](https://madsalt.tech/ja/tools/supabase-security-check/)には、バケットに関するルールが2つあります。「公開されたストレージバケット」は、公開バケットを一覧にして、それぞれが本当に公開でよいかを確認できるようにします。「アップロード制限のない公開バケット」は、サイズやファイル形式の制限がない公開バケットを指摘します。ここでは、公開フラグが実際に何を変えるのかを見ます。

## Supabaseの公開バケットとは何？

Supabaseの[バケットガイド](https://supabase.com/docs/guides/storage/buckets/fundamentals)は、2つのアクセスモデルを定義しています。非公開バケットでは、ダウンロードを含むすべての操作が`storage.objects`のRLSポリシーを通ります。ファイルは、ユーザーのトークンか、期限付きの署名付きURLで読みます。公開バケットでは、ファイルの取得と配信がアクセス制御を迂回するため、URLを知っていれば誰でもファイルを読めます。アップロード、削除、移動、コピーには、引き続きアクセス制御が適用されます。

バケットはデフォルトで非公開です。ダッシュボードでチェックボックスを入れるか、`public: true`で作成すると公開になります。画像が表示されないときの手っ取り早い方法として、よく使われます。

## 私のテストで各バケットは何を返した？

ローカルのSupabaseスタック（CLI 2.109.1）で、公開バケットと非公開バケットを1つずつ作り、同じ小さなテキストファイルをsecret keyで両方にアップロードしました。そのあと、リンクを知っただけの第三者のように、キーなしでリクエストしました。

![同じファイルを、キーなしでリクエスト。ローカルのSupabase Storage、公開と非公開のバケット各1つ。公開バケット：リクエスト、キーなし → 公開バケット → 200、ファイル送信、非公開バケット：リクエスト、キーなし → 非公開バケット → 400、見つからない。](https://madsalt.tech/charts/ja/supabase-public-bucket.svg)

*ローカルのSupabaseスタックでの私の再現、2026年10月23日。*

| `2026/invoice-001.txt`へのリクエスト                      | 公開バケット          | 非公開バケット            |
| --------------------------------------------------------- | --------------------- | ------------------------- |
| `/storage/v1/object/public/…`、キーなし                   | `200`、ファイルの内容 | `400`、"Bucket not found" |
| `/storage/v1/object/authenticated/…`、publishable keyのみ | `200`                 | `400`                     |

非公開バケットは、存在しないかのように応答します。これが望ましい動作です。公開バケットは、パスを推測できる人、あるいは見つけた人に、ファイルを渡してしまいます。

## URLがそれほど重要なのはなぜ？

公開ファイルの秘密度は、そのパスと同じ程度です。パスは予測しやすいことが多く、ユーザーID、日付、請求書番号などが使われがちです。ページのソース、共有されたリンク、ブラウザの履歴、ログからも漏れます。公開バケットに置いた請求書、パスポートのスキャン、署名済みの契約書は、事実上、公開されたのと同じです。

## どう選んで、どう直す？

- **公開バケット：** アバター、商品写真、ブログの画像など、全員に向けたファイル。バケットにファイルサイズの上限と許可するMIMEタイプを設定して、ポリシーが許す公開アップロード経路で別のものをホストされないようにします。
- **非公開バケット：** ドキュメント、エクスポート、請求書など、個人に関わるすべて。ユーザーのセッションでダウンロードするか、期限付きの署名付きURLを作成します。

バケットと、その制限を確認するには次のクエリを使います。

```sql
select id, public, file_size_limit, allowed_mime_types
from storage.buckets
order by public desc, id;
```

非公開バケットには、`storage.objects`のポリシーも必要です。通常は、パスの最初のフォルダがユーザーIDか会社IDであることを確認します。プロジェクトを移行したあとは、そのポリシーの数を数えてください。あるアプリでは、ポリシーのマイグレーションが実行されなかったためにすべてのアップロードが失敗しました。それは[Lovableアプリのセキュリティチェックリスト](https://madsalt.tech/ja/blog/lovable-app-security-checklist/)に書いています。publishable keyがほかに何へ到達できるかは、[Supabaseのanon keyとservice role keyの違い](https://madsalt.tech/ja/blog/supabase-anon-key-vs-service-role-key/)にあります。
