AWS Bedrock with .NET: Advanced Integration & Production Setup
Advanced Authentication & Production Setup
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);
}
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);
}
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.
Prompt Engineering & Response Parsing
For reliable parsing, craft your prompts to instruct the model to return strict JSON. Here’s a helper for formatting/parsing the response:
private string FormatJsonString(string input)
{
if (string.IsNullOrWhiteSpace(input)) return input;
// Try to extract the first JSON array or object from the string
var match = System.Text.RegularExpressions.Regex.Match(input,
"(\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])");
if (!match.Success)
return input;
var jsonContent = match.Value;
try
{
using var doc = System.Text.Json.JsonDocument.Parse(jsonContent);
return System.Text.Json.JsonSerializer.Serialize(doc.RootElement,
new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
}
catch
{
// If not valid JSON, return as-is
return jsonContent;
}
}
Summary & Best Practices
- Advanced authentication enables secure, scalable, and production-ready AWS Bedrock integration in .NET.
- Use EC2 instance roles for production workloads—never hardcode credentials.
- Prompt engineering and response parsing are key for reliable GenAI workflows.
- Refer to AWS documentation for the latest best practices and SDK updates.
For most users, the shared credentials file is sufficient. Move to advanced setups only when your deployment or security needs require it.
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
