> ## Documentation Index
> Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
> Use this file to discover all available pages before exploring further.

# プライベートアセット

> AdCP のプライベートアセットは、プレサインド URL を使用して DAM、S3 バケット、認証ソースに保存されたファイルへの一時的なアクセスを許可します。

AdCP にはアセットアップロードタスクは含まれない。クリエイティブエージェントはバイヤーに代わってファイルのアップロードを受け入れたりストレージを管理したりすることは想定されていません。代わりに、バイヤーエージェントは自分のアセットをホストし、[クリエイティブマニフェスト](/docs/creative/creative-manifests)でアクセス可能な URL を提供する責任があります。

アセットがプライベートストレージ — 内部の DAM、プライベートな S3 バケット、または認証が必要なもの — に存在する場合、バイヤーエージェントはマニフェストに URL を渡す前にそれらをアクセス可能にしなければなりません。

## プレサインド URL

推奨されるパターンは**プレサインド URL** だ。ほとんどのクラウドストレージプロバイダーは、認証ヘッダーを必要とせずに一時的な読み取りアクセスを許可する時間制限付き URL の生成をサポートしています。

### 仕組み

1. バイヤーエージェントがプライベートアセットを受け取るか特定する（例: S3 のブランドロゴ）
2. バイヤーエージェントが短い有効期限でプレサインド URL を生成します
3. バイヤーエージェントがクリエイティブマニフェストにプレサインド URL を渡します
4. クリエイティブエージェントが他のパブリック URL と同様にアセットをフェッチします

```json theme={null}
{
  "format_id": {
    "agent_url": "https://creatives.example.com",
    "id": "display_static",
    "width": 300,
    "height": 250
  },
  "assets": {
    "banner_image": {
      "url": "https://my-bucket.s3.amazonaws.com/brand/logo.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=3600&X-Amz-Signature=...",
      "width": 300,
      "height": 250
    },
    "headline": {
      "content": "Spring collection"
    },
    "clickthrough_url": {
      "url": "https://shop.example.com/spring"
    }
  }
}
```

<Note>
  標準マニフェストとの唯一の違いは URL 自体です。`banner_image.url` にはプレサインドクエリパラメーター（`X-Amz-Algorithm`、`X-Amz-Expires`、`X-Amz-Signature`）が含まれます。他のフィールドは変更なし。
</Note>

### プロバイダー例

<CodeGroup>
  ```javascript AWS S3 theme={null}
  import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

  const client = new S3Client({ region: "us-east-1" });

  const url = await getSignedUrl(
    client,
    new GetObjectCommand({
      Bucket: "my-brand-assets",
      Key: "logos/primary.png",
    }),
    { expiresIn: 3600 } // 1 hour
  );
  ```

  ```javascript Google Cloud Storage theme={null}
  import { Storage } from "@google-cloud/storage";

  const storage = new Storage();

  const [url] = await storage
    .bucket("my-brand-assets")
    .file("logos/primary.png")
    .getSignedUrl({
      action: "read",
      expires: Date.now() + 3600 * 1000, // 1 hour
    });
  ```

  ```javascript Cloudflare R2 theme={null}
  import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

  const client = new S3Client({
    region: "auto",
    endpoint: "https://<account-id>.r2.cloudflarestorage.com",
  });

  const url = await getSignedUrl(
    client,
    new GetObjectCommand({
      Bucket: "my-brand-assets",
      Key: "logos/primary.png",
    }),
    { expiresIn: 3600 }
  );
  ```

  ```javascript Azure Blob Storage theme={null}
  import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions, StorageSharedKeyCredential } from "@azure/storage-blob";

  const credential = new StorageSharedKeyCredential(accountName, accountKey);

  const sasToken = generateBlobSASQueryParameters({
    containerName: "brand-assets",
    blobName: "logos/primary.png",
    permissions: BlobSASPermissions.parse("r"),
    expiresOn: new Date(Date.now() + 3600 * 1000), // 1 hour
  }, credential).toString();

  const url = `https://${accountName}.blob.core.windows.net/brand-assets/logos/primary.png?${sasToken}`;
  ```
</CodeGroup>

## 有効期限のガイドライン

プレサインド URL の有効期限をワークフロー全体をカバーするのに十分な長さに設定しつつ、必要以上に長くしないようにします。

| ワークフロー                                                                                                                                  | 推奨有効期限 |
| --------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| [`build_creative`](/docs/creative/task-reference/build_creative) のみ                                                                     | 1 時間   |
| [`build_creative`](/docs/creative/task-reference/build_creative) + [`preview_creative`](/docs/creative/task-reference/preview_creative) | 2 時間   |
| フルパイプライン（build、preview、反復、[`sync_creatives`](/docs/creative/task-reference/sync_creatives)）                                             | 4 時間   |

## ローカルファイルのアップロード

すでにクラウドストレージに存在しないアセット——ローカルファイル、Slack の添付、メールの添付——については、バイヤーエージェントはまずそれらを自身のストレージにアップロードし、それからプレサインド URL を生成すべきです。

<CodeGroup>
  ```javascript AWS S3 theme={null}
  import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
  import { readFile } from "fs/promises";

  const client = new S3Client({ region: "us-east-1" });

  // Upload the local file
  const fileBuffer = await readFile("./assets/logo.png");
  await client.send(new PutObjectCommand({
    Bucket: "my-brand-assets",
    Key: "logos/primary.png",
    Body: fileBuffer,
    ContentType: "image/png",
  }));

  // Generate a presigned URL for the creative agent to fetch
  const url = await getSignedUrl(
    client,
    new GetObjectCommand({
      Bucket: "my-brand-assets",
      Key: "logos/primary.png",
    }),
    { expiresIn: 3600 }
  );
  ```

  ```javascript Google Cloud Storage theme={null}
  import { Storage } from "@google-cloud/storage";

  const storage = new Storage();
  const bucket = storage.bucket("my-brand-assets");

  // Upload the local file
  await bucket.upload("./assets/logo.png", {
    destination: "logos/primary.png",
    contentType: "image/png",
  });

  // Generate a presigned URL for the creative agent to fetch
  const [url] = await bucket
    .file("logos/primary.png")
    .getSignedUrl({
      action: "read",
      expires: Date.now() + 3600 * 1000,
    });
  ```
</CodeGroup>

## なぜ認証ヘッダーではないのか?

AdCP のマニフェストは、エージェント間で JSON として渡される宣言的なデータです。URL ごとの認証ヘッダーを追加すると、信頼境界をまたいでストレージのクレデンシャルを共有することになります——マニフェストに触れるすべてのシステム（クリエイティブエージェント、プレビューサービス、アドサーバー、ロギングインフラ）が、それらのクレデンシャルを安全に扱う必要が生じます。

プレサインド URL は、認可を URL 自体にエンコードすることでこれを避けます:

* 読み取り専用アクセスで単一のオブジェクトにスコープされる
* 組み込みの有効期限で時間制限される
* クレデンシャルの転送が不要
* 失効は自動（URL が期限切れになる）

## 関連ドキュメント

* [クリエイティブマニフェスト](/docs/creative/creative-manifests) — マニフェストの構造とアセット参照
* [アセットタイプ](/docs/creative/asset-types) — 各アセットタイプの要件
* [`build_creative`](/docs/creative/task-reference/build_creative) — マニフェストからクリエイティブを生成する
* [`sync_creatives`](/docs/creative/task-reference/sync_creatives) — エージェントがホストするクリエイティブライブラリにクリエイティブを同期する
