mcpField
F
Filelayer

Filelayer

ローカル
filelayer.devファイル・ストレージ03 日前に更新

Filelayer について

Filelayer は、ユーザーやテナントが所有するプライベートファイルを扱う SaaS アプリ向けの認可レイヤーです。既存のデータベースとストレージを使い、アクセス判定、取り消し可能な共有、監査記録を一元化します。

主な機能

  1. 01ファイルアクセス認可の一元化
  2. 02期限付き共有と取り消し
  3. 03アクセスと拒否の監査記録
  4. 04原子的なダウンロード上限
  5. 05既存のデータベースとストレージの利用

活用シーン

  1. 01ユーザーの非公開文書や添付ファイルの管理
  2. 02取り消し可能な共有リンクの作成
  3. 03組織のメンバーシップに基づくアクセス制御
  4. 04ファイルアクセスや拒否の調査

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"dev-filelayer-core": {
"command": "npx",
"args": [
"-y",
"@filelayer/core"
],
"env": {
"DATABASE_URL": "<DATABASE_URL>",
"FILELAYER_AS": "<FILELAYER_AS>",
"FILELAYER_ORG": "<FILELAYER_ORG>",
"FILELAYER_DATA_DIR": "<FILELAYER_DATA_DIR>",
"S3_ENDPOINT": "<S3_ENDPOINT>",
"S3_BUCKET": "<S3_BUCKET>",
"S3_REGION": "<S3_REGION>",
"S3_ACCESS_KEY_ID": "<S3_ACCESS_KEY_ID>",
"S3_SECRET_ACCESS_KEY": "<S3_SECRET_ACCESS_KEY>",
"FILELAYER_MCP_AGENT_LABEL": "<FILELAYER_MCP_AGENT_LABEL>",
"FILELAYER_MCP_ALLOW_DESTRUCTIVE": "<FILELAYER_MCP_ALLOW_DESTRUCTIVE>",
"FILELAYER_MCP_EXPOSE_AUDIT": "<FILELAYER_MCP_EXPOSE_AUDIT>",
"FILELAYER_MCP_RETURN_BYTES": "<FILELAYER_MCP_RETURN_BYTES>",
"FILELAYER_BASE_URL": "<FILELAYER_BASE_URL>"
}
}
}
}
起動コマンドnpx -y @filelayer/core
設定が必要な環境変数
DATABASE_URLシークレットYour own PostgreSQL, where this library keeps file ownership, grants and the audit chain. Apply node_modules/@filelayer/core/schema.sql once before starting.
FILELAYER_ASThe ONE subject this server speaks for, in your own id space. Fixed for the life of the process: no tool reads it as an argument and no tool can change it, which is the only reason exposing these tools to an agent is safe. Write it yourself or have your provisioning write it, never derive it from a conversation. Serving several people means starting several servers.
FILELAYER_ORGThe organisation this server is scoped to, in your own id space.
FILELAYER_DATA_DIRA local directory for the bytes. Needs no bucket and no IAM user. Set this OR the S3_* block: with neither, the server refuses to start rather than falling back to memory, which would work in a demo and lose the first real file.
S3_ENDPOINTAn S3-compatible endpoint, for example https://<account>.r2.cloudflarestorage.com. Setting it makes S3_BUCKET, S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY required.
S3_BUCKETThe bucket. It must be private: this library decides who may be GIVEN a URL and has no say in who the object store will answer. `npx -p @filelayer/core filelayer doctor` reports whether yours serves unauthenticated reads.
S3_REGIONRegion, or `auto` for Cloudflare R2.
S3_ACCESS_KEY_IDシークレットAccess key id for the bucket.
S3_SECRET_ACCESS_KEYシークレットSecret access key for the bucket.
FILELAYER_MCP_AGENT_LABELHow this agent names itself in the audit trail, recorded on every event these tools produce. It is what lets the chain separate "the partner opened this document" from "the partner's assistant opened this document".
FILELAYER_MCP_ALLOW_DESTRUCTIVESet to exactly `true` to register delete_file. Off by default because deleting is not recoverable and an agent that misreads a sentence deletes the wrong thing silently.
FILELAYER_MCP_EXPOSE_AUDITSet to exactly `true` to register file_audit. Off by default because the trail is an organisation's whole history and a tool that returns it copies every file name, actor and denial into the model's context. Reading it is itself audited since 0.27.0, which was the previous reason; the default did not move.
FILELAYER_MCP_RETURN_BYTESSet to exactly `true` to register read_file. Off by default because a document returned by a tool is a document copied into a model's context; file_info plus a share link is usually what was actually needed.
FILELAYER_BASE_URLThe base of the share URLs this instance mints. Without it, share links come back without a URL.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@filelayer/core0.33.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Filelayer

CI npm node license

SaaS アプリケーションのためのファイルレイヤー。 公開ファイルと非公開ファイルの両方を、共通の認可モデルで扱います。→ filelayer.dev

呼び出し元が誰なのかを Filelayer に伝えるだけです。Filelayer はファイルに対して可能な操作を判断し、適切なヘッダーを付けてバイトデータを配信し、監査イベントを記録します。Filelayer を経由するファイルアクセスでは、その判断は packages/core/src/authz.ts の一箇所で行われるため、ルートハンドラーに所有権チェックを書いたり、署名付き URL の有効期限ロジックを実装したり、独自のルートごとのアクセスルールを設けたりする必要はありません。

デザインパートナーを3〜5社募集しています。 統合を支援し、実施中もサポートします。その代わり、どこで問題が起きるかを教えてください。アルファ版であること、そしてその言葉の裏にある数値は、すべてこちらにまとめています: これに依存してもよいか? · 対応していないこと · 1.0 までのロードマップ

// Public avatar
const { url } = await fl.files.put(bytes, { public: true });

// Private, user-owned
const { id } = await fl.files.put(bytes, { owner: 'user_123' });
const file  = await fl.files.get(id, { as: 'user_123' });

// Multi-tenant, role-controlled
await fl.files.put(bytes, { org: 'acme', owner: 'user_123' });

// Shared with an expiry, a password and a download cap, and revocable
const share = await fl.shares.create(id, {
  as: 'user_123', expiresIn: 3600, maxDownloads: 3, password: 'hunter2',
});
await fl.shares.revoke(share.grantId, { as: 'user_123' });   // this link, now

// Shared with a named user, and taken back. `unshare` is the one you want for
// a person: `create()` is not idempotent, so revoking a single grant id you
// happen to be holding can leave an earlier one live.
await fl.shares.create(id, { as: 'user_123', withUser: 'user_456' });
await fl.shares.unshare(id, { as: 'user_123', user: 'user_456' });   // all of it

自分の課題に当てはまる箇所から始めてください。 複雑さは段階的に増します。各段階で概念が一つ加わり、使わない概念のためにコストを負担する必要はありません。→ docs/QUICKSTART.md


3つのレイヤー

your application          fl.files.put / get / list, fl.shares, fl.orgs
                          you pass YOUR user id; nothing here knows a uuid
   ───────────────────────────────────────────────────────────────────────
Filelayer                 ONE authorization function answers every request
                          grants, roles, expiry, download caps, revocation
                          the audit event, written in the decision's own
                          transaction so the log cannot disagree with it
   ───────────────────────────────────────────────────────────────────────
your Postgres             9 tables. Filelayer owns the schema, you own the
your bucket               database. Bytes go to S3, R2, B2 or a directory
                          behind one adapter; storage is replaceable

Filelayer は、すでに運用している2つのものの間に位置します。データベースも独自のストレージも持たず、実行時依存関係はゼロです。

これは認可ミドルウェアであり、行レベルセキュリティではありません。 Filelayer は、自分のプロセス内で、Filelayer を経由する呼び出しに対して判断を行います。さらにスキーマは、すべての書き込み元(psql セッションを含む)に対して、テナント間の権限付与、プロジェクトをまたぐアイデンティティ、権限を増幅する委任を拒否します。これらは制約とトリガーによって実現されています。しかし、schema.sql に RLS ポリシーはなく、これらのテーブルへの直接の SELECT は何によってもフィルタリングされません。Filelayer はデータベースレベルの強制と組み合わせて使うものであり、それに取って代わるものではありません。


何に向いていて、何に向いていないか

オーバーヘッドをかける価値があるケース: ファイルが非公開で、特定の人やテナントに属し、権限が時間とともに変化する場合です。ドキュメント、契約書、添付ファイル、エクスポート、後から取り消したくなる可能性のある共有リンクなどが該当します。

オーバーヘッドをかける価値がないケース:

必要なもの代わりに使うもの理由
CDN 規模の公開画像配信CDN 対応バケットデフォルトの配信方式では、すべてのバイトデータをプロキシします。リダイレクト配信(後述)ならプロキシを省けますが、オプトイン方式で用途も限定されています。
大規模な動画・音声配信CDN/メディアサービスシークには対応しています。提供されるルートは Range に対して 206 を返します。しかしデフォルトの配信方式では、すべてのバイトデータがサーバーを経由し、CDN もありません。
開発時に、サーバーをデータ経路から外したブラウザーからストレージへのアップロード実際のバケットFsStorage は認証情報を生成するため、クライアントコードは同じままですが、バイトデータを受け取るのは FsStorage 自身であり、そのことも via: 'server' と明示します。プロセスをデータ経路から外せるのは S3 と R2 だけです。
再開可能またはマルチパートの直接アップロード署名付き S3 への直接アップロード/tus署名付き PUT を1回実行し、オブジェクトを1つアップロードします。再開には対応していません。
サムネイル、変換、フォーマットネゴシエーションCloudinary/imgixいずれにも対応していません。
ほかに選べる2つの方法と比べて
手作業で作成する署名付き URLSupabase StorageFilelayer
すでに誰かが持っているリンクを無効にするできません。 署名は有効期限が切れるまで有効です。選択肢は TTL を短くするか、自分でバイト列をプロキシすることですできません。 署名付き URL は内部キーで署名されており、無効にできませんできます。 委任チェーンを通じて、次のリクエストから無効になります
「この組織の全員が読み取り可能」参加・退出のたびに自前の結合処理を再計算しますRLS ポリシーで表現できます1行の許可レコードで対応でき、リクエスト時にメンバーシップを判定します
拒否された場合も含め、誰がアクセスしたか自分で記録した内容によります製品の機能ではありません。Postgres のログはアクセスログではありませんテナントごとにハッシュチェーンで記録し、判定を行うトランザクション内で書き込みます
ダウンロード上限自前のカウンターと、その競合状態への対処が必要ですありませんアトミックに処理し、バイト列を転送する前に枠を確保します
非公開パスでの CDN可能ですが、それがリンクを無効にできない理由です可能ですが、同じトレードオフがありますできません — 2つの事実は同じことを示しています
大量の公開画像可能です可能ですできません。CDN の背後にバケットを配置してください
公開アバターに必要な行数約10行10行16行

最後の2項目は Filelayer が劣る点で、その差は歴然です。負けるケースもすべて含めた比較全文は、 ARCHITECTURE-PROGRESSIVE.md §5 に掲載しています。要点をまとめると、公開アバターの場合、Supabase は10行、Filelayer は 16行です。 アバターだけが課題なら、Supabase をお使いください。


5 つのセキュリティプロパティ

これらが製品の中核です。それぞれは慣例ではなく、スキーマまたは認可エンジンによって強制され、それぞれの名前を冠したテストがあります。

プロパティ実際の意味
P1デフォルトで拒否スキーマ内に public ブール値は存在しません。公開配信は明示的で、取り消し可能かつ監査可能な付与レコードです。誤ってオンのままにできるフラグはありません。これはオブジェクトストアではなく、スキーマのプロパティです。Filelayer はバケットを非公開にできません。また、バケットが公開されていると、このページのすべての仕組みが迂回されます。 これは Filelayer が代わりに設定できない唯一の項目です。QUICKSTART §7。
P2暗黙の権限なしオブジェクトキー、URL、ファイル ID を知っていても、何の権限も得られません。ストレージの場所が判定の入力になることはありません。
P3テナントをまたぐ付与は構造上作成できない付与の org_id はファイルの org_id と一致する必要があり、複合外部キー FOREIGN KEY (file_id, org_id) REFERENCES file (id, org_id) によって強制されます。マイグレーションや psql セッションを含め、どの書き込み手段でも別のテナントのファイルを参照する付与は作成できません。これは読み取りフィルターではなく、書き込み側の整合性制約です。これにより、そのような 行 は表現できなくなります。読み取り範囲はデータベースではなく、エンジンによって制限されます。
P4URL の有効期間は権限を超えない署名付き URL には必ず付与 ID が埋め込まれ、すべてのリクエストで委任チェーン全体を遡って再検証されます。有効な URL があっても、取り消しが優先されます。
P5拒否を含むすべての判定が監査されるテナントごとにハッシュチェーンで記録されます。テナントを特定できないプローブは破棄されず、システムチェーンに記録されます。ログでは内部 ID とともに、marco、contract.pdf、acme など お客様が使う ID で回答できるため、「誰がアクセスしたのか」を調べるために SQL を書く必要はありません。

スキーマで強制され、packages/core/SEMANTICS.md に記載されている重要なプロパティが、さらに 3 つあります。ダウンロードカウンターのアトミック性(P6)、カスケードではなく有効性判定としての削除(P7)、プロジェクトごとの識別子名前空間(P8)です。

導入前に知っておくべきことが 2 つあります。

  • 取り消しは実際に機能します。 fl.files.unpublish(id) を呼び出すと、すでに印刷、インデックス登録、サポートチケットへの貼り付けが済んだ URL も、次のリクエストから機能しなくなります。削除も、キーのローテーションも、キャッシュのパージも必要ありません。Supabase の getPublicUrl() はオフラインで文字列を連結するだけなので、この判定を行うリクエストの機会がありません。公開を取り消すには、オブジェクトを削除するしかありません。
  • この仕組みではバイトを直接配信します。 P4 が、署名付き URL を渡すのではなくバイトを配信するのをデフォルトにしている理由であり、デフォルトの配信経路の前段に CDN を置かない理由でもあります。この 2 つは同じ理由です。リダイレクト配信では、CDN を利用する代わりに取り消し可能な時間に上限が生じます。この方式はオプトインです。詳しくは packages/core/SEMANTICS.md をご覧ください。

その裏付け

ここで一度だけお伝えします。ここに記載されている数値はすべて、公開されている仕様と実行結果が一致しない場合にビルドを失敗させるゲートによって検証されています。

テストスイート736 件のテストをすべてのコミットで実行し、すべて実際の PostgreSQL に対してテストしています
並行性実際の PostgreSQL と 2 つのバックエンドを使った8 件のテストです。競合状態を実際に発生させており、推論だけで済ませていません。そのうち 3 件では、保護機能を取り除いて望ましくない結果が実際に発生することを確認する対照テストを実施しています
敵対的テスト27 件の攻撃、侵害 0 件です。脆弱であることが分かっている、このライブラリの以前のリビジョンに対しても実行し、3 件が成功します。常に成功するだけのテストスイートは、自らについて何も証明しません
実際のオブジェクトストレージすべてのコミットで、実際の Cloudflare R2 に対するテストを 12 件、実際の AWS S3 に対するテストを 12 件実行し、さらに夜間実行ではそれぞれ 13 件目のテストとして、11 MB のマルチパートアップロードを再構成し、バイト単位で完全に一致することを確認しています。R2 は S3 互換ですが S3 ではないため、両方を実行しています
スキーマのマイグレーション実際の PostgreSQL で、すべてのマイグレーションファイルを前回のリリースの schema.sql に適用し、その結果を次のリリースのものと比較しています
公開済みアーティファクト空のディレクトリに tarball をインストールして、ライフサイクル全体を通して動作させています。スターターを HTTP 経由で起動し、25 件のチェックを実行しています。tarball 内のすべての相対パスが、tarball 内から解決されることも確認しています

これらのどれも、負荷や、誰かの本番環境について測定するものではありません。 ゼロの行も含む完全な表は、信頼性のページをご覧ください。


利用を見送る理由となる5つの点

完全な一覧は LIMITATIONS.md にあります。14項目が理由とともに記載され、npm の tarball に含まれるため、インストールすれば手元で確認できます。次の5つに当てはまる場合は、タブを閉じるべきです。

  1. 非公開配信経路に CDN がありません。 バイト列はアプリケーション経由でプロキシされ、認証済みのレスポンスには Cache-Control: no-store が付与されます。これは見落としではなく、P4 によるものです。取り消し可能な URL は、その都度アクセスの可否を確認する必要があるためです。オプトインのリダイレクトモードでは、最大300秒の取り消し猶予期間と引き換えに、キャッシュ可能になります。大量の公開画像を扱うワークロードなら、CDN の背後にバケットを配置し、URL を無効化する必要が生じたときに戻ってきてください。

  2. grant ID は個人のアクセス権ではなく、shares.create() はデフォルトで呼び出しごとに1行を挿入します。 expiresIn を指定した2回の呼び出しは、それぞれ有効期間が異なる正当なリクエストであるため、エンジンが独自に重複排除することはできません。idempotencyKey を渡せば、リトライ時に既存の grant が返されます。指定しない場合、共有ボタンを二度クリックすると、1人の閲覧者に2つの grant が付与されます。revoke() は subjectCanStillRead を返すようになったため、1つの grant を取り消してもその人のアクセス権が残っている場合、後日の監査ではなく、応答で確認できます。特定の人のアクセス権を削除するには shares.unshare(fileId, { as, user }) を使ってください。また、1つの subject が保持できる有効な grant の数に上限はありません。

    ただし、そのコストは、もはや以前のような問題ではありません。0.17.0 より前は、読み取り時に保持している grant ごとに再帰的なチェーン走査が1回発生していました。5件で4.3 ms、10万件で5,911 ms かかっていました。ショートサーキット処理を SQL に移したことで、この急激な性能低下は解消されています。 benchmark/load/RESULTS.md の H4b で測定したところ、grant が集中する20万件でも30.4 ms で、同じファイルに対する所有者の読み取りの1.13倍でした。残っているのは正確性に関する落とし穴であり、性能の急激な低下ではありません。

  3. 再開可能なアップロードやマルチパートアップロードには対応していません。 署名付き PUT は1回につき1オブジェクトです。大容量のアップロードが失敗すると、最初からやり直す必要があります。また、fl.files.put() はリクエスト本文全体をメモリ上に保持します。ストリームを受け取るのはコアの fl.upload() だけで、どちらもサイズ上限を設けていないため、その制限はご自身で適用する必要があります。

  4. 組織の管理者と所有者は private ファイルを読み取れます。 これは意図的な仕様です。保持しているものを、保持責任を負う人が確認できなければ、保持ポリシーやリーガルホールドは役に立ちません。ただし、これはポリシー上の判断です。運用者をアクセス対象から除外する必要がある場合は、エンベロープ暗号化が必要ですが、こちらには実装されていません。

  5. アルファ版であり、スキーマは12回変更されています。 0.x から 0.(x+1) への更新では、API、スキーマ、あるいはその両方に互換性のない変更が生じる可能性があります。変更はすべて MIGRATIONS.md に番号付きで記載され、migrations/ 以下には実行可能なファイルがあります。CI はそれらを前のリリースのスキーマに適用し、次のリリースのスキーマが生成されることを確認します。しかし、LTS ブランチも、バックポートも、独立したセキュリティレビューもありません。


インストール

npm install @filelayer/core

Node ≥ 22.18 が必要です。パッケージにはコンパイル済みの JavaScript と型宣言が dist/ に含まれています。また、TypeScript ソースとテストスイート全体も tarball に含まれているため、このページに記載されている内容は、インストールしたものからすべて確認できます。

このインストールには、実行時依存関係が一切ありません。 Filelayer は お使いの Postgres と お使いの バケットを利用するため、どちらも同梱していません。以下の一時インスタンスだけは例外です。quickstart() は組み込みの WebAssembly Postgres で動作し、本番環境の node_modules に決して含まれないよう、オプションのピア依存関係として宣言されています。一時インスタンスを使いたい場合は追加し、そうでなければ省略してください。必要な場合は createTestDb() がパッケージ名を示して通知します。

npm install --save-dev "@electric-sql/pglite@^0.3.11"

PGlite は、指定のバージョン制約でインストールしてください。 Filelayer がサポートしているのは 0.3.x 系で、peerDependencies にもこの範囲が宣言されており、テストスイートもこのバージョンで実行されます。0.5.x はサポートされていません。0.5.8 でテストスイート全体を実行したところ、通過しなかったため、バージョン範囲は拡大していません。npm の PGlite の latest は 0.5.x のリリースであるため、制約を省略するとサポート範囲外のバージョンがインストールされる場合があり、その場合、npm はツリー全体のインストールを ERESOLVE で拒否します。引用符はシェル用であり、npm 用ではありません。^ は extendedglob が有効な zsh ではグロブ演算子となり、cmd.exe ではエスケープ文字です。

import { Filelayer } from '@filelayer/core';

const fl2 = await Filelayer.quickstart();          // PGlite + in-memory bytes
const { url: avatarUrl } = await fl2.files.put(bytes, { public: true });

quickstart() は一時的です。プロセスの終了時にすべて失われます。

バイトデータの配信

読み取りを許可することと、リクエストに応答することは別です。後者を行うハンドラーは 2 種類あり、どちらを使うかは好みではなく、実行環境によって決まります。

deliveryHandler(fl, opts?)(req: IncomingMessage, res: ServerResponse) => Promise<void> を返します。Node 独自の HTTP サーバーや、これらのオブジェクトを渡す Express、Fastify、Koa で使います。
deliveryFetch(fl, opts?)(req: Request) => Promise<Response | null> を返します。Request を渡し、Response を返す Next.js App Router、Hono、Cloudflare Workers、Deno、Bun で使います。

どちらも、同じ動作をする同じ 2 つのルートです。deliveryFetch は、自身が処理しないリクエストに対して null を返します。そのため、キャッチオールルートはリクエストを握りつぶさずに、アプリケーションの残りの部分へ処理を引き継げます。

誤ったハンドラーをマウントすることが、最もよく見られる統合の失敗です。 App Router のルートに node:http ハンドラーを置くと、エクスポートされる関数の形式が合いません。症状はマウント時の型エラーではなく、リクエストに応答が返らないことです。

import { deliveryFetch } from '@filelayer/core';

const serve = deliveryFetch(fl, {
  principal: async () => ({ as: await currentUserId() }),
});

export async function GET(req: Request) {
  return (await serve(req)) ?? new Response('Not found', { status: 404 });
}

どちらも Range を解析します。これは想像以上に重要です。<video> 要素は、レンジリクエストに応答が返るまでユーザーがシークできず、PDF リーダーは最初にファイルの末尾を要求します。無効なレンジには、RFC 9110 の要件に従って表現全体を含む 200 で応答します。416 と Content-Range: bytes */<size> を返すのは、正しく解析されたものの、満たせないレンジに限られます。クライアントがシーク可能であることを認識できるよう、通常の 200 にも Accept-Ranges: bytes を付与します。

どちらかをマウントする前に知っておきたいデフォルトが 2 つあります。disposition のデフォルトは attachment で、再生ではなくダウンロードになるため、メディアルートでは disposition: 'inline' が必要です。また、プロキシではなく署名付き URL にリダイレクトするには、明示的なオプトインが必要です。URL の有効期間中、失効処理がプロセスの管理外になるためです。署名に対応したストレージアダプターが必要で、設定で明示的に許可されるまで redirect_not_acknowledged で拒否されます。 docs/guides/serving-private-files.md では、この 2 つを実測して比較しています。

それ以外は、項目ごとに1ページ

ほとんどのアプリケーションで必要な連携はこれだけです。インストールし、quickstart() で動作を確認してから、実際のデータベースと以下のハンドラーのいずれかを使います。それ以外は各項目1ページで説明しており、すべて npm tarball に同梱されているため、インストールすればディスク上にそろいます。

ストレージアダプターの選択と、バケットを非公開にする方法QUICKSTART §7
ターミナルからデプロイを確認する方法(filelayer doctor)docs/CLI.md
エージェントが連携を行う場合の Agent Skilldocs/AGENT-SKILL.md
サーバーを経由しない、ブラウザーからバケットへのアップロードdocs/DIRECT-UPLOAD.md
エージェントがファイルを操作できる MCP サーバーdocs/MCP.md
29個のエラーコードと FilelayerErrorQUICKSTART §9 · ERRORS.md
自分たちのルートが機能することを確認する方法(auditIntegration())QUICKSTART §8
時間範囲を指定し、ストレージアダプターを使わずに監査証跡を読む方法QUICKSTART §4
クローンから、またはインストールしたものからテストスイートを実行する方法CONTRIBUTING · インストールしたものから

ガイドは filelayer.dev/guides にもレンダリングされており、同じ Markdown ですが、リポジトリ内のファイルより読みやすくなっています。

バージョニング

1.0 未満です。バージョンは 0.MINOR.PATCH で、保証する内容は意図的に限定しています。

  • 0.x → 0.(x+1) では、API、スキーマ、またはその両方が破壊的に変更される可能性があります。変更内容はすべて packages/core/CHANGELOG.md に記載し、スキーマの破壊的変更にはすべて packages/core/MIGRATIONS.md にマイグレーションを用意しています。
  • 0.x.y → 0.x.(y+1) は機能追加または修正です。対応が必要なスキーマ変更やシグネチャ変更はありません。
  • 1.0 より前には、長期サポートブランチもバックポートもありません。

スキーマは12回変更されています。 MIGRATIONS.md には番号付きの項目が15件あり、そのうち10件には引き継ぎ用の SQL が含まれています。残る2件のスキーマ変更は、リポジトリ内で最も古いタグより前に行われたため、以前のスキーマに照らして検証できません。この段落ではなく、該当ファイルを基準にアップグレードの計画を立ててください。この段落内の数値はすべて migrations/manifest.json を基に check:versions が算出しており、数値にずれがあればビルドは失敗します。これらの数値は最後に 0.15.0 で手作業による修正が行われ、その後 0.33.0 では再びずれていたためです。

データベースのバージョンは、データベースから確認できます。 schemaStatus(db) は、データベースの現在の状態、このビルドが想定する状態、migrations/ 内で未適用のファイルを報告します。DDL は発行しません。マイグレーションランナーはアプリケーションが管理するという方針を、MIGRATIONS.md §2 で示し、現在も維持しています。


構成

パス内容
packages/core/schema.sqlデータモデルです。各セキュリティ特性は、それを適用する制約の箇所にコメントされています。レビューする場合は、まずこれをお読みください。
packages/core/src/authz.ts認可エンジンです。2つの関数と、1つの判定コアで構成されています。
packages/core/src/simple.ts階層化された API(files、orgs、shares)です。認可ロジックはなく、ファサードとして機能します。
packages/core/src/delivery.tsバイトデータの配信を担います。レスポンスヘッダーを管理するため、設定を誤ることはありません。
packages/core/test/プロパティテストのスイートです。tarball に含まれています。
packages/core/dev/診断スクリプトです。公開されません。
examples/tier1-avatar … tier3-org-roles各階層につき1つの実行可能なサンプル
examples/vaultHTTP を介した、B2B 向けの完全なドキュメントワークスペース
examples/starterデプロイ可能なサーバーです。独自の Postgres と FsStorage を使い、ルートヘルパーをマウントします。
examples/nextjsApp Router のサンプルです。キャッチオールルートでの deliveryFetch、アップロード、共有、取り消しを扱います。
examples/mcp起動可能な MCP サーバーです。専用の verify.mjs によって、実際の stdio を介して動作します。

ドキュメント

  • docs/QUICKSTART.md — インストールから最初のファイル、さらに高度な機能まで
  • LIMITATIONS.md — このライブラリが対応しないことの完全な一覧です。理由とともに14項目を記載しています。
  • ROADMAP.md — 外部評価者が評価を変えると述べた9項目のうち、完了した8項目と、意図的に対応しない項目
  • docs/guides/ — 実際によく寄せられる質問への4つの回答です。このライブラリを使うかどうかにかかわらず役立ちます。掲載されているコードは CI で実行されます。
  • packages/core/SEMANTICS.md — 生存期間、委譲、削除、監査チェーンなど、あらゆるエッジケースの正確な動作
  • packages/core/MIGRATIONS.md — スキーマ変更の提供方法と、1.0 以前の互換性に関する保証
  • packages/core/CHANGELOG.md — 自ら発見したセキュリティ上の欠陥も含む、実際の変更履歴
  • ARCHITECTURE-PROGRESSIVE.md — 階層モデル、代替案とのコード行数の比較、劣る点
  • architecture/TIER5-DESIGN-NOTE.md — 大容量ファイル、ストリーミング、範囲リクエスト、CDN
  • llms.txt — 統合を実装するエージェント向けに記述した、同じドキュメント一覧
  • openapi.yaml — ライブラリが提供する2つの HTTP ルートを OpenAPI 3.1 で記述したもの

上記のリンクはすべて GitHub を指しており、インストール済みパッケージを利用する環境にはネットワーク接続もブラウザーもない場合があります。そのため npm パッケージには、同じファイルが node_modules/@filelayer/core/ 以下に含まれています。また、3つのファイルはサブパスインポート(@filelayer/core/llms.txt、@filelayer/core/openapi.json、@filelayer/core/schema.sql)として解決できるため、node_modules 内の構成を推測する必要はありません。

ライセンス

Apache-2.0 です。明示的な特許許諾と、特許侵害を理由とする終了条項が含まれています。ご自身のコードにコピーレフトの義務はありませんが、通知を保持し、重大な変更を明記してください。LICENSE と NOTICE はどちらも tarball に同梱されており、成果物とともにライセンス許諾が引き継がれます。

SPDX-License-Identifier: Apache-2.0
Copyright 2026 Technology Pro Bono S.L.

依存関係。 実行時の依存関係はありません。CI のジョブでは、依存関係が追加されるとビルドが失敗します。サードパーティパッケージはすべて devDependencies です。具体的には、@electric-sql/pglite(Apache-2.0)が含まれます。これはオプションのピア依存関係でもあり、quickstart() の実行に使われます。また、2 つの実際のバックエンドが必要な競合テスト向けに pg と embedded-postgres があります。本番環境へのインストールにはこれらは一切含まれず、このリポジトリのどこにもサードパーティのコードはコピーも埋め込みもされていません。

貢献、セキュリティ、行動規範

  • CONTRIBUTING.md — セットアップ方法、npm run verify の対象、プルリクエストに必要な内容について説明しています。
  • SECURITY.md — 脆弱性は公開の Issue ではなく、非公開で報告してください。情報開示のスケジュールと、対象範囲内外の内容も記載しています。
  • CODE_OF_CONDUCT.md — Contributor Covenant 2.1 です。

バグ、質問、「このドキュメントは間違っている」という報告は、GitHub Issues にお寄せください。README に書かれているとおりに製品が動作しないという報告は、皆さんからいただく情報の中で最も役に立つものであり、これまでに寄せられた報告はすべて当日中に修正されています。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。