AWS Bedrock with .NET: Getting Started
The Problem: Too Many APIs, Too Much Friction
Imagine this: your team decides to add AI to your .NET application. You pick a model, wire up the HTTP client, handle the auth, parse the response schema—and it works. Then the product team asks to try a different model. Suddenly you have two HTTP clients, two authentication flows, two response formats, and twice the maintenance burden. Add a third model and things start to spiral.
This is the reality that many .NET teams hit when integrating generative AI directly through vendor APIs. Each provider has its own conventions, and none of them speak fluent C#.
What is AWS Bedrock and Why Use It from .NET?
AWS Bedrock is Amazon's answer to the multi-model problem. It gives you a single, consistent interface to access foundation models from providers like Anthropic Claude and Amazon Titan—without juggling separate APIs, auth tokens, or request formats for each one.
What makes it especially compelling for .NET developers is the official AWS SDK for .NET. You can invoke powerful AI models using idiomatic C# code, plugging straight into your existing projects—no context switching, no foreign tooling. Text generation, summarization, intelligent chat—all accessible through the same familiar patterns you already use for other AWS services.
Why: The Need for Simplicity, Security, and Scale
- Simplicity: No REST API wrangling or manual token management. The AWS SDK for .NET handles the heavy lifting so you can focus on building features.
- Security: AWS IAM and credentials management give you enterprise-grade access control out of the box—no custom auth layers needed.
- Scale: Bedrock is built for production, with built-in monitoring, throttling, and cost controls that would take weeks to build yourself.
Whether you're prototyping an idea or shipping to production, Bedrock removes the friction that usually slows GenAI adoption in .NET teams.
How: Step-by-Step Guide to Using AWS Bedrock from .NET
1. Prerequisites
- An AWS account with Bedrock access enabled.
- AWS credentials (Access Key, Secret Key, and Session Token) with permissions for Bedrock.
- .NET 9 SDK or later installed.
- The following NuGet packages:
- AWSSDK.Bedrock
- AWSSDK.BedrockRuntime
2. Setting Up Your Project
You can use a simple C# script or a .NET project. Here's how to reference the required libraries:
#r "nuget: AWSSDK.Bedrock, 3.7.0"
#r "nuget: AWSSDK.BedrockRuntime, 3.7.0"
3. Authenticating with AWS
⚠️ Authentication and permissions are where most developers struggle. The AWS SDK supports multiple authentication methods, each suited for different scenarios. Choose the one that fits your deployment model.
Method 1: Session Credentials (Local Development)
Use this for quick local testing with temporary credentials (e.g., from AWS STS or temporary session tokens).
SessionAWSCredentials GetCredentials()
{
// ⚠️ NEVER hardcode credentials in production!
string accessKey = "<your-access-key>";
string secretKey = "<your-secret-key>";
string sessionToken = "<your-session-token>";
return new SessionAWSCredentials(accessKey, secretKey, sessionToken);
}
Method 2: IAM User Credentials (Not Recommended for Production)
Use static IAM user credentials for simple scenarios, but this method is less secure for production.
BasicAWSCredentials GetBasicCredentials()
{
string accessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID");
string secretKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY");
if (string.IsNullOrWhiteSpace(accessKey) || string.IsNullOrWhiteSpace(secretKey))
throw new InvalidOperationException("AWS credentials not found in environment variables.");
return new BasicAWSCredentials(accessKey, secretKey);
}
Method 3: AWS Credentials File (~/.aws/credentials)
The most convenient approach for local development is the AWS shared credentials file. When you run aws configure, the CLI writes your credentials to ~/.aws/credentials. The AWS SDK for .NET automatically reads from this file through its default credential resolution chain—no extra code required.
# ~/.aws/credentials
[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
[bedrock-dev]
aws_access_key_id = YOUR_DEV_ACCESS_KEY_ID
aws_secret_access_key = YOUR_DEV_SECRET_ACCESS_KEY
To use the default profile, simply instantiate the client without passing credentials—the SDK picks it up automatically:
// SDK automatically resolves credentials from ~/.aws/credentials [default] profile
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
To use a named profile explicitly at runtime, use CredentialProfileStoreChain:
var chain = new CredentialProfileStoreChain(); // reads ~/.aws/credentials
if (chain.TryGetAWSCredentials("bedrock-dev", out AWSCredentials credentials))
{
var bedrockClient = new AmazonBedrockClient(credentials, RegionEndpoint.USEast1);
}
Method 4: EC2 Instance Profile Role (Production on EC2)
This is the recommended approach for production applications running on EC2. The SDK automatically retrieves credentials from the instance metadata without any code changes.
// No credentials needed! The SDK automatically uses the EC2 instance role.
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
var runtimeClient = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
Creating the EC2 Instance Profile Role
To create an EC2 instance profile role with the minimal permissions needed to list models and invoke them:
Step 1: Create an IAM Role
- Go to IAM console → Roles → Create Role
- Select "AWS service" → "EC2" as the trusted entity
- Click "Create Role"
Step 2: Add Inline Policy with Required Permissions
Once the role is created, add this inline policy to grant Bedrock permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:ListFoundationModels",
"bedrock:GetFoundationModel"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:*:*:foundation-model/*"
}
]
}
Step 3: Attach the Role to Your EC2 Instance
- Go to EC2 console → Instances → Select your instance
- Right-click → Security → Modify IAM role
- Select the role you created
- Click "Update IAM role"
Step 4: Use in Your .NET Code
No code changes needed! The SDK automatically picks up the EC2 instance role:
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
var runtimeClient = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
Troubleshooting Authentication Issues
If you're getting permission errors, check these common issues:
- UnauthorizedException or AccessDeniedException: Your credentials don't have Bedrock permissions. Double-check the IAM policy above is attached to your role/user.
- InvalidUserID or SignatureDoesNotMatch: Your AWS credentials are incorrect or expired. Re-verify your access key and secret key.
- EC2 instance can't access Bedrock: The instance profile role isn't attached, or the IAM policy is missing. Check the instance details in AWS console.
- Region issues: Ensure Bedrock is available in your region. Not all AWS regions support Bedrock yet.
Debug tip: Use the AWS CLI to test credentials before using them in your .NET app:
aws bedrock list-foundation-models --region us-east-1
Note: The same IAM permissions can also be set up using CloudFormation or AWS CDK if you prefer infrastructure-as-code approaches.
4. Listing Available Foundation Models
async Task ListAvailableModels(AmazonBedrockClient client)
{
var request = new ListFoundationModelsRequest();
var response = await client.ListFoundationModelsAsync(request);
Console.WriteLine($"Found {response.ModelSummaries.Count} models:");
foreach (var model in response.ModelSummaries.Take(10))
{
Console.WriteLine($" Model ID: {model.ModelId}");
Console.WriteLine($" Name: {model.ModelName}");
Console.WriteLine();
}
}
5. Invoking a Model (Anthropic Claude)
The BedrockService class in the AwsBedrockExamples project wraps the Invoke API to query movie details. Here is the core invocation logic from BedrockService.cs:
public async Task<string> GetMovieDetails(string movieQuery)
{
var prompt =
$"\n\nHuman: You are a movie information expert. Provide detailed information about the movie '{movieQuery}'. " +
"Return the results as a JSON array of objects with fields: title, year, category, directors, actors, plot, genre, rating. " +
"If no movie is found, return an empty JSON array.\n\nAssistant:";
var request = new InvokeModelRequest
{
ModelId = ModelId, // "anthropic.claude-3-haiku-20240307-v1:0"
ContentType = "application/json",
Accept = "application/json",
Body = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(
JsonSerializer.Serialize(new
{
anthropic_version = "bedrock-2023-05-31",
max_tokens = 1024,
messages = new[]
{
new { role = "user", content = prompt }
}
})
))
};
var response = await _client.InvokeModelAsync(request);
var responseBody = System.Text.Encoding.UTF8.GetString(response.Body.ToArray());
return FormatJsonString(responseBody);
}
6. Putting It All Together
Here's how you'd use BedrockService from the AwsBedrockExamples solution to query movie details end-to-end. For the full source, see BedrockService.cs on GitHub.
var service = new BedrockService();
string movieJson = await service.GetMovieDetails("Inception");
Console.WriteLine(movieJson);
Example Response from Claude:
[
{
"title": "Inception",
"year": 2010,
"category": "Movie",
"directors": [
"Christopher Nolan"
],
"actors": [
"Leonardo DiCaprio",
"Ellen Page",
"Joseph Gordon-Levitt",
"Tom Hardy",
"Cillian Murphy",
"Michael Caine"
],
"plot": "A thief who steals corporate secrets through the use of dream-sharing technology is given the inverse task of planting an idea in the mind of a CEO.",
"genre": "Science Fiction, Action, Adventure",
"rating": "PG-13"
}
]
Summary
- What: You can now use AWS Bedrock's powerful GenAI models directly from .NET.
- Why: It's secure, scalable, and easy to integrate into your existing C# workflows.
- How: With just a few lines of code, you can list models, send prompts, and process responses—all using the official AWS SDK.
This approach lets you build intelligent, generative features into your .NET apps with minimal friction. Whether you're prototyping or going to production, AWS Bedrock and .NET make GenAI accessible and robust.
References & Further Reading
For reference, the code repository being discussed is available at github: https://github.com/ajaysskumar/ai-playground
Thanks for reading through. Please share feedback, if any, in comments or on my email ajay.a338@gmail.com
