こんにちは~ 浮田です。
今回は短めに、権限で踏んだ話をひとつ。
S3 Vectors に検索専用のアプリから QueryVectors を投げる構成を組んでいました。
IAM は最小権限で、s3vectors:QueryVectors だけ。フィルタなしのクエリは通ります。
メタデータで絞ろうとフィルタを付けた途端、403 になりました。
AccessDeniedException: User: arn:aws:sts::...:federated-user/s3v-perm-test
is not authorized to perform: s3vectors:GetVectors
QueryVectors を呼んでいるのに、怒られているのは GetVectors です。
ドキュメントの QueryVectors の説明に、実は書いてあります。
フィルタを指定するか、メタデータを返すよう指定した場合は、s3vectors:QueryVectors に加えて s3vectors:GetVectors の権限が要る。無いと 403 になる、と。
理屈としては、フィルタもメタデータの返却も「ベクトルに付いているメタデータを読む」操作なので、ベクトルを読む権限が要る、ということのようです。
フィルタなしで距離だけ返すなら、ベクトル本体もメタデータも読んでいない扱いになります。
読めば分かる話なのですが、QueryVectors の権限を付けて「フィルタなしで動いた」ところで安心してしまうと、気づきません。
私はクエリの書き方を疑って、フィルタの JSON を何度も書き直していました。
推測しても仕方ないので、権限を絞って 4 パターン投げました。
IAM ユーザーを作るのは面倒なので、sts:GetFederationToken で「いまの自分の権限 ∩ 渡したポリシー」の一時認証情報を作っています。
リソースを作らずに権限だけ絞れるので、この手の検証には便利です。
policy = {"Version": "2012-10-17", "Statement": [{
"Effect": "Allow",
"Action": ["s3vectors:QueryVectors"], # ← ここを変えて試す
"Resource": index_arn}]}
cr = sts.get_federation_token(Name="s3v-perm-test",
Policy=json.dumps(policy), DurationSeconds=900)["Credentials"]
s3v = boto3.client("s3vectors", aws_access_key_id=cr["AccessKeyId"],
aws_secret_access_key=cr["SecretAccessKey"],
aws_session_token=cr["SessionToken"])
対象は前々回 Bedrock のナレッジベースで作った索引です(19 本しか入っていませんが、権限の確認には十分です)。
|
クエリ |
QueryVectors のみ |
QueryVectors + GetVectors |
|
フィルタなし |
200 |
200 |
|
フィルタなし、returnDistance あり |
200 |
200 |
|
フィルタなし、returnMetadata あり |
403 |
200 |
|
フィルタあり($exists) |
403 |
200 |
returnMetadata でも 403 になります。フィルタだけの話ではありません。
「検索結果に本文を付けて返したい」という、RAG ならほぼ必ずやることでも同じ壁に当たります。
検索専用のアプリでも、ポリシーには 2 つ書きます。
{
"Effect": "Allow",
"Action": ["s3vectors:QueryVectors", "s3vectors:GetVectors"],
"Resource": "arn:aws:s3vectors:ap-northeast-1:123456789012:bucket/my-bucket/index/my-index"
}
GetVectors は「キーを指定してベクトルとメタデータを取り出す」API なので、検索アプリに付けるのは少し過剰に見えます。ただ、フィルタもメタデータ返却もこの権限に相乗りしている以上、付けないと検索になりません。
もうひとつ。Bedrock のナレッジベース経由で使っているあいだは、ロールに付ける権限はドキュメントの手順どおりで済むので、ここは踏みません。自分で QueryVectors を叩く構成に変えたときに、初めて踏みます。私がそうでした。
※この記事は 2026 年 9 月時点の挙動に基づきます。