5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS SDK で Bedrock API Key を Authorization ヘッダーに設定してリクエストする方法

Posted at

本記事で紹介する方法はドキュメント等で公式に案内されているものではないため、使用を検討される際はご留意ください。

はじめに

Amazon Bedrock API キーは一部言語の AWS SDK でも使用できます。ドキュメントの記載例のように API キーをAWS_BEARER_TOKEN_BEDROCK 環境変数に設定して使用します。

2025 年 10 月時点で AWS SDK Java、JavaScript、Python で Bedrock API キーを使用できます。

ドキュメントでは API キーを直接 HTTP リクエストの Authorization ヘッダーに含める方法も紹介されています。ほとんどのユースケースにおいては環境変数の利用で問題ないかと思いますが、アプリケーションを再起動せず動的に API キーを切り替えたい場合などもあるかもしれません。この方式を AWS SDK でも利用できないかと考えて検証したところ、動作を確認できたので紹介します。

やり方

ポイントは以下の 2 点です。

1. HTTP リクエストに Authorization ヘッダーを追加

カスタムヘッダーを追加する処理を実装し、HTTP リクエストの Authorization ヘッダー
Bedrock API Key を含めてリクエストします。

2. 認証情報 (SigV4 署名) を無効化する

デフォルトの Credential Provider は AWS 認証情報を検索し、SigV4 の署名リクエストを作成する (Authorization ヘッダーに SigV4 の署名情報が含まれる) ため、1. の手順だけでは Authorization ヘッダーが上手いこと書き変わらないようです。

サンプルコード (Java)

AWS SDK for Java には ExecutionInterceptor という HTTP リクエストの処理に割り込んで、カスタムロジックを実行できる仕組みがあります。これを使用して Authorization ヘッダーを追加します。

そしてクライアント生成時に AnonymousCredentialsProvider を指定して通常の認証をバイパスさせます。

public class BedrockApiKeyExample {

    static class CustomHeaderInterceptor implements ExecutionInterceptor {
        private final String apiKey;
        
        public CustomHeaderInterceptor(String apiKey) {
            this.apiKey = apiKey;
        }
        
        @Override
        public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
            return context.httpRequest().toBuilder()
                    .putHeader("Authorization", "Bearer " + apiKey)
                    .build();
        }
    }

    public static void main(String[] args) {
        var apiKey = "YOUR_API_KEY_HERE";
        var modelId = "global.anthropic.claude-sonnet-4-5-20250929-v1:0";
        
        BedrockRuntimeClient client = BedrockRuntimeClient.builder()
                .region(Region.US_EAST_1)
                .credentialsProvider(AnonymousCredentialsProvider.create())
                .overrideConfiguration(builder -> builder.addExecutionInterceptor(new CustomHeaderInterceptor(apiKey)))
                .build();

        Message userMessage = Message.builder()
                .role(ConversationRole.USER)
                .content(List.of(ContentBlock.fromText("こんにちは")))
                .build();

        ConverseRequest request = ConverseRequest.builder()
                .modelId(modelId)
                .messages(List.of(userMessage))
                .build();

        ConverseResponse response = client.converse(request);
        String responseText = response.output().message().content().get(0).text();
        System.out.println("Response: " + responseText);
        
        client.close();
    }
}

サンプルコード (Boto3)

本件の調査は Java でおこなっていましたが、少し調べたところ多言語の SDK でも類似の機能は提供されていました。

Python (Boto3) の場合、Event System という機構を使用することで API リクエストのライフサイクルの各段階でカスタムコードを実行できるようです。

またクライアント生成時に 署名バージョンを UNSIGNED に設定することで、通常の認証をスキップできます。

import boto3
import botocore
from botocore.config import Config

def main():
    api_key = "YOUR_API_KEY_HERE"
    model_id = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"

    # SigV4 署名無しでクライアント生成
    client = boto3.client(
        'bedrock-runtime',
        region_name='us-east-1',
        config=Config(signature_version=botocore.UNSIGNED)
    )

    # カスタムヘッダーを追加するイベントハンドラーを登録
    def add_auth_header(request, **kwargs):
        request.headers['Authorization'] = f'Bearer {api_key}'

    client.meta.events.register('before-sign', add_auth_header)

    try:
        response = client.converse(
            modelId=model_id,
            messages=[
                {
                    'role': 'user',
                    'content': [
                        {
                            'text': 'こんにちは'
                        }
                    ]
                }
            ]
        )

        response_text = response['output']['message']['content'][0]['text']
        print(f"Response: {response_text}")

    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()

最後に冒頭の繰り返しになりますが、本記事で紹介した方法はドキュメント等で公式に案内されているものではないため、使用を検討される際はご留意ください。

以上です。
参考になれば幸いです。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?