Skip to content

S3 互換性

AWS SDK を使用して、Amazon S3 と同じコードで IPFS Ninja 上のファイルをアップロード、ダウンロード、管理できます。

Endpoint

https://s3.ipfs.ninja

認証情報

S3 API は認証に IPFS Ninja の API キーを使用します。API キーが access key と secret key の両方として機能します。

認証情報の取得方法

  1. Dashboard > API Keys にアクセス
  2. Create API key をクリックし、名前を付けます(例: "S3 access")
  3. すぐにキー全体をコピーしてください — キーは一度だけ表示され、後から確認することはできません

キーは以下のような形式です:

bws_628bba35e9e0079d9ff9c392b1b55a7b
├──────────┘└──────────────────────────┘
 prefix (12 chars)    rest of key

AWS 認証情報へのマッピング

AWS パラメータ
accessKeyIdAPI キーの最初の 12 文字bws_628bba35
secretAccessKeyAPI キー全体(36 文字すべて)bws_628bba35e9e0079d9ff9c392b1b55a7b
region常に us-east-1us-east-1

WARNING

完全な API キーは作成時に一度だけ表示されます。紛失した場合は、キーを削除して API Keys ページから新しいキーを作成してください。

クイックスタート

javascript
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "https://s3.ipfs.ninja",
  credentials: {
    accessKeyId: "bws_628bba35",
    secretAccessKey: "bws_628bba35e9e0079d9ff9c392b1b55a7b"
  },
  region: "us-east-1",
  forcePathStyle: true
});

// Upload a file
const put = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "hello.json",
  Body: JSON.stringify({ hello: "IPFS" }),
  ContentType: "application/json"
}));

console.log("CID:", put.Metadata?.cid);
// CID: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

Bucket = フォルダ

S3 の bucket は IPFS Ninja のフォルダに対応します。bucket にファイルをアップロードすると、対応するフォルダに保存されます。bucket 内のオブジェクトを一覧表示すると、そのフォルダ内のファイルが表示されます。

S3 操作IPFS Ninja での対応
CreateBucket新しいフォルダを作成
ListBucketsフォルダの一覧を表示
DeleteBucketフォルダとその中の全ファイルを削除
PutObject (bucket へ)フォルダ内にファイルをアップロード
ListObjectsV2 (bucket に対して)フォルダ内のファイルを一覧表示
javascript
import { ListBucketsCommand, CreateBucketCommand, PutObjectCommand } from "@aws-sdk/client-s3";

// Create a bucket (= create a folder)
await s3.send(new CreateBucketCommand({ Bucket: "nft-metadata" }));

// Upload a file into the folder
await s3.send(new PutObjectCommand({
  Bucket: "nft-metadata",      // ← folder name
  Key: "token-42.json",        // ← filename within the folder
  Body: JSON.stringify({ name: "My NFT #42" })
}));

// List buckets (= list your folders)
const { Buckets } = await s3.send(new ListBucketsCommand({}));
console.log(Buckets);
// [{ Name: "nft-metadata", CreationDate: "2026-04-13T..." }]

TIP

S3 API で作成したフォルダは Dashboard に表示されるフォルダと同じです。S3 API、REST API、Web インターフェースのいずれからでもファイルを整理できます — すべて同じフォルダシステムを共有しています。

INFO

Amazon S3 とは異なり、IPFS Ninja のフォルダはデフォルトでフラットです。ネストされた構造を作成するには、REST API のフォルダ endpoint で parentFolderId を使用してください。S3 API からは、キーのプレフィックス(例: images/photo.png)を使ってフォルダ内のファイルを整理できます。

Bucket 名はグローバルに一意

Bucket 名は、Amazon S3 のセマンティクスと同様に、全顧客にまたがるグローバルな名前空間に存在します。つまり:

  • ある名前で最初に bucket を作成したユーザーが、その名前をグローバルに確保します。
  • 同じ名前で別のアカウントから CreateBucket を呼び出すと BucketAlreadyExists409)が返されます。
  • 自分自身の bucket を再作成しようとすると BucketAlreadyOwnedByYou409)が返されます。
  • ダッシュボード上のフォルダ名はアカウントごとに独立しており、自由に付けることができます — グローバルな名前空間を通るのは、S3 上に見えるbucket 名だけです。

希望する名前がすでに使われている場合は、別のスコープを持つ名前(myapp-photos-2026acme-nft-metadata など)を選んでください — Amazon S3 で使うのと同じ慣習です。

サポートされている操作

PutObject

ファイルを IPFS にアップロードします。ファイルはピン留めされ、セキュリティスキャンが実行され、CID が ETag および x-amz-meta-cid ヘッダーで返されます。

通常のファイルではなく CAR ファイル をインポートするには、x-amz-meta-import: car メタデータヘッダーを追加してください。詳細は CAR Import を参照してください。

javascript
import { PutObjectCommand } from "@aws-sdk/client-s3";
import fs from "fs";

const result = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "photo.png",
  Body: fs.readFileSync("photo.png"),
  ContentType: "image/png"
}));

console.log("CID:", result.ETag);
bash
# curl equivalent
curl -X PUT "https://s3.ipfs.ninja/my-project/photo.png" \
  --data-binary @photo.png \
  -H "Content-Type: image/png" \
  --aws-sigv4 "aws:amz:us-east-1:s3" \
  --user "bws_628bba35:bws_628bba35e9e0079d9ff9c392b1b55a7b"

GetObject

キー(ファイル名)または CID でファイルをダウンロードします。

javascript
import { GetObjectCommand } from "@aws-sdk/client-s3";

const result = await s3.send(new GetObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

const body = await result.Body.transformToByteArray();
console.log("Size:", body.length);
console.log("CID:", result.Metadata?.cid);

HeadObject

コンテンツをダウンロードせずにファイルのメタデータを取得します。

javascript
import { HeadObjectCommand } from "@aws-sdk/client-s3";

const head = await s3.send(new HeadObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

console.log("Size:", head.ContentLength);
console.log("Type:", head.ContentType);
console.log("CID:", head.Metadata?.cid);

DeleteObject

ファイルの IPFS ピンを解除し、アカウントから削除します。

javascript
import { DeleteObjectCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

ListObjectsV2

オプションのプレフィックスフィルタリングとページネーションで bucket 内のファイルを一覧表示します。

javascript
import { ListObjectsV2Command } from "@aws-sdk/client-s3";

const list = await s3.send(new ListObjectsV2Command({
  Bucket: "my-project",
  Prefix: "images/",
  MaxKeys: 100
}));

for (const obj of list.Contents ?? []) {
  console.log(obj.Key, obj.Size, obj.ETag); // ETag = CID
}

Multipart Upload

マルチパートアップロードを使用して大きなファイル(最大 5 GB)をアップロードします。AWS SDK が自動的に処理します:

javascript
import { Upload } from "@aws-sdk/lib-storage";
import fs from "fs";

const upload = new Upload({
  client: s3,
  params: {
    Bucket: "my-project",
    Key: "large-dataset.tar.gz",
    Body: fs.createReadStream("large-dataset.tar.gz"),
    ContentType: "application/gzip"
  },
  partSize: 10 * 1024 * 1024, // 10 MB per part
});

upload.on("httpUploadProgress", (progress) => {
  console.log(`Uploaded ${progress.loaded} of ${progress.total} bytes`);
});

const result = await upload.done();
console.log("CID:", result.ETag);

または手動でパートを制御:

javascript
import {
  CreateMultipartUploadCommand,
  UploadPartCommand,
  CompleteMultipartUploadCommand
} from "@aws-sdk/client-s3";

// 1. Start
const { UploadId } = await s3.send(new CreateMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin"
}));

// 2. Upload parts
const part1 = await s3.send(new UploadPartCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  PartNumber: 1,
  Body: chunk1
}));

// 3. Complete
const result = await s3.send(new CompleteMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  MultipartUpload: {
    Parts: [{ PartNumber: 1, ETag: part1.ETag }]
  }
}));

Python の例

python
import boto3

s3 = boto3.client(
    "s3",
    endpoint_url="https://s3.ipfs.ninja",
    aws_access_key_id="bws_628bba35",
    aws_secret_access_key="bws_628bba35e9e0079d9ff9c392b1b55a7b",
    region_name="us-east-1"
)

# Upload
s3.put_object(
    Bucket="my-project",
    Key="data.json",
    Body=b'{"hello": "IPFS"}',
    ContentType="application/json"
)

# List files
response = s3.list_objects_v2(Bucket="my-project")
for obj in response.get("Contents", []):
    print(obj["Key"], obj["Size"])

# Download
result = s3.get_object(Bucket="my-project", Key="data.json")
print(result["Body"].read())

Go の例

go
package main

import (
    "context"
    "fmt"
    "strings"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    client := s3.New(s3.Options{
        BaseEndpoint: aws.String("https://s3.ipfs.ninja"),
        Region:       "us-east-1",
        Credentials:  credentials.NewStaticCredentialsProvider("bws_628bba35", "bws_628bba35e9e0...", ""),
        UsePathStyle: true,
    })

    _, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
        Bucket:      aws.String("my-project"),
        Key:         aws.String("hello.txt"),
        Body:        strings.NewReader("Hello, IPFS!"),
        ContentType: aws.String("text/plain"),
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("Uploaded!")
}

ブラウザ SDK アクセス向けの CORS 設定

ブラウザの JavaScript(SPA、ウォレットアプリ、ダッシュボードツールなど)から直接 S3 API を呼び出す場合は、事前に bucket 上で CORS を設定する必要があります。設定しないと、ブラウザがプリフライトをブロックし、アップロードが No 'Access-Control-Allow-Origin' header is present というエラーで失敗します。

Amazon S3 と同じ形式です — PutBucketCors / GetBucketCors / DeleteBucketCors のサブリソースを使用します:

PutBucketCors

javascript
import { S3Client, PutBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new PutBucketCorsCommand({
  Bucket: "my-bucket",
  CORSConfiguration: {
    CORSRules: [{
      AllowedOrigins: ["http://localhost:3000", "https://myapp.com"],
      AllowedMethods: ["GET", "HEAD", "PUT", "POST", "DELETE"],
      AllowedHeaders: ["*"],
      ExposeHeaders: ["ETag", "x-amz-meta-cid", "x-amz-request-id"],
      MaxAgeSeconds: 3600,
    }],
  },
}));

GetBucketCors

javascript
import { GetBucketCorsCommand } from "@aws-sdk/client-s3";

const { CORSRules } = await s3.send(new GetBucketCorsCommand({ Bucket: "my-bucket" }));
console.log(CORSRules);

DeleteBucketCors

javascript
import { DeleteBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteBucketCorsCommand({ Bucket: "my-bucket" }));

上限とデフォルト値

  • bucket あたり最大5 ルール(仕様上は 100 まで許可されていますが、ブラウザのプリフライトレスポンスをコンパクトに保つため 5 に制限しています)。
  • 設定全体はシリアライズ後で64 KBに制限されます。
  • CORS 設定が行われていない場合、ブラウザのプリフライトは拒否されます — これは Amazon S3 のデフォルトの挙動と同じです。実際に配信するオリジンに対して明示的なルールを設定してください。

実運用におけるセキュリティ上の注意

CORS はブラウザ側の利便性のためのレイヤーであり、セキュリティ境界ではありません。すべての S3 API 呼び出しは、依然として API キーから計算された有効な SigV4 署名を必要とします — 寛容な CORS 設定を行っても、その認証情報なしに誰かが bucket を使えるようになるわけではありません。CORS が防ぐのは、意図しないオリジン(例えば dev.myapp.com にある古いコピーのアプリなど)がブラウザコンテキストから署名済みリクエストを送信することです。

ダッシュボードでの代替手段

Files ページでは、各フォルダのアクションメニューに S3 CORS という項目があります。裏側のストレージは同じなので、PutBucketCors のコードを書きたくない場合はそちらから設定できます。

Amazon S3 との違い

機能Amazon S3IPFS Ninja S3
ストレージモデル変更可能なオブジェクトコンテンツアドレス(不変の CID)
上書き動作オブジェクトをその場で置換新しい CID を作成、古い CID は引き続きアクセス可能
Versioningサポート非サポート(CID を使用してバージョン管理)
サーバーサイド暗号化サポート非サポート(コンテンツは IPFS 上)
ライフサイクルポリシーサポート非サポート
Bucket ポリシー / ACLサポートgateway アクセスモードを使用
Presigned URLサポート署名付きアップロードトークンを使用
最大オブジェクトサイズ5 TB5 GB(multipart)、100 MB(single PUT)
リージョンマルチリージョンus-east-1 のみ
ETag の値MD5 ハッシュIPFS CID
追加ヘッダー標準 S3x-amz-meta-cid(IPFS CID)
CID format該当なし新規アップロードでは最新の CIDv1(bafy…)を使用。入力としては従来の Qm… も引き続き有効
Bucket namespaceグローバル(AWS 全体)グローバル(全 IPFS Ninja アカウントにまたがる)— 同じセマンティクス
CORSPutBucketCors サポートPutBucketCors サポート(5 ルール上限)

Amazon S3 からの移行

S3 クライアントの設定を置き換えてください:

diff
 const s3 = new S3Client({
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "AKIA...",
-    secretAccessKey: "wJalrX..."
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
+  forcePathStyle: true
 });

既存の PutObjectGetObjectListObjectsV2DeleteObject の呼び出しはそのまま動作します。

Filebase からの移行

endpoint URL を置き換えてください:

diff
 const s3 = new S3Client({
-  endpoint: "https://s3.filebase.com",
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "FILEBASE_KEY",
-    secretAccessKey: "FILEBASE_SECRET"
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
   forcePathStyle: true
 });