Skip to content

Commit 3eebd7e

Browse files
ira-at-workIra Abramov
andauthored
feat: add AWS_USE_IMDS support for ambient IAM credential resolution on Bedrock (#2307)
Co-authored-by: Ira Abramov <ira@agrematch.com>
1 parent b32c526 commit 3eebd7e

6 files changed

Lines changed: 1055 additions & 177 deletions

File tree

docs/docs/installation/github.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,35 @@ To use local models via Ollama:
280280

281281
**Note:** For local models, you'll need to use a self-hosted runner with Ollama installed, as GitHub Actions hosted runners cannot access localhost services.
282282

283+
##### Using Amazon Bedrock
284+
285+
To use Amazon Bedrock models with static IAM credentials:
286+
287+
```yaml
288+
env:
289+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
290+
config.model: "bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0"
291+
config.fallback_models: '["bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0"]'
292+
aws.AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
293+
aws.AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
294+
aws.AWS_REGION_NAME: "us-east-1"
295+
```
296+
297+
**Recommended: IAM Role Credentials on AWS Compute**
298+
299+
When the GitHub Actions runner is on AWS infrastructure (EC2, ECS, EKS), use the instance/task IAM role directly — no secrets required:
300+
301+
```yaml
302+
env:
303+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
304+
config.model: "bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0"
305+
config.fallback_models: '["bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0"]'
306+
AWS_USE_IMDS: "true"
307+
# AWS_REGION_NAME: us-east-1 # optional if instance metadata provides the region
308+
```
309+
310+
The IAM role must have `bedrock:InvokeModel` on the target model ARN. See [Bedrock model configuration](../usage-guide/changing_a_model.md#amazon-bedrock) for the full IAM policy example and supported models.
311+
283312
#### Advanced Configuration Options
284313

285314
##### Custom Review Instructions
@@ -732,4 +761,4 @@ After you set up AWS CodeCommit using the instructions above, here is an example
732761
PYTHONPATH="/PATH/TO/PROJECTS/pr-agent" python pr_agent/cli.py \
733762
--pr_url https://us-east-1.console.aws.amazon.com/codesuite/codecommit/repositories/MY_REPO_NAME/pull-requests/321 \
734763
review
735-
```
764+
```

docs/docs/usage-guide/changing_a_model.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Please note that the `custom_model_max_tokens` setting should be configured in a
111111
Commercial models such as GPT-5, Claude Sonnet, and Gemini have demonstrated robust capabilities in generating structured output for code analysis tasks with large input. In contrast, most open-source models currently available (as of January 2025) face challenges with these complex tasks.
112112

113113
Based on our testing, local open-source models are suitable for experimentation and learning purposes (mainly for the `ask` command), but they are not suitable for production-level code analysis tasks.
114-
114+
115115
Hence, for production workflows and real-world usage, we recommend using commercial models.
116116

117117
### Hugging Face
@@ -251,6 +251,43 @@ model="bedrock/us.meta.llama4-scout-17b-instruct-v1:0"
251251
fallback_models=["bedrock/us.meta.llama4-maverick-17b-instruct-v1:0"]
252252
```
253253

254+
#### Using IAM Role Credentials (Recommended on AWS Compute)
255+
256+
When running PR-Agent on AWS infrastructure (EC2, ECS/Fargate, EKS with IRSA, Lambda, or any self-hosted GitHub Actions runner on AWS), the instance or task already has an IAM role attached. You can use those ambient credentials directly instead of storing long-lived static keys.
257+
258+
Set `AWS_USE_IMDS=true` in the environment. PR-Agent will resolve credentials via boto3's standard provider chain, which handles all AWS compute contexts transparently:
259+
260+
| Compute context | Mechanism |
261+
|---|---|
262+
| EC2 instance with IAM role | IMDSv2 (169.254.169.254) |
263+
| ECS / Fargate task role | Task metadata endpoint |
264+
| EKS pod with IRSA | Web identity token + STS |
265+
| Lambda function | Runtime-injected credentials |
266+
267+
Minimal GitHub Actions workflow (no AWS secret keys required):
268+
269+
```yaml
270+
- uses: Codium-ai/pr-agent@main
271+
env:
272+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
273+
AWS_USE_IMDS: "true"
274+
# AWS_REGION_NAME: us-east-1 # optional if the instance metadata provides it
275+
with:
276+
command: review
277+
```
278+
279+
The IAM role must have `bedrock:InvokeModel` permission on the target model ARN, for example:
280+
281+
```json
282+
{
283+
"Effect": "Allow",
284+
"Action": "bedrock:InvokeModel",
285+
"Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
286+
}
287+
```
288+
289+
If you also configure static keys in `[aws]`, they serve as an automatic fallback: if the ambient credentials fail a Bedrock call (e.g., the role lacks `bedrock:InvokeModel`), PR-Agent retries with the static keys and logs a warning.
290+
254291
#### Custom Inference Profiles
255292

256293
To use a custom inference profile with Amazon Bedrock (for cost allocation tags and other configuration settings), add the `model_id` parameter to your configuration:
@@ -339,7 +376,7 @@ key = "..." # your Codestral api key
339376
To use model from Openrouter, for example, set:
340377

341378
```toml
342-
[config] # in configuration.toml
379+
[config] # in configuration.toml
343380
model="openrouter/anthropic/claude-3.7-sonnet"
344381
fallback_models=["openrouter/deepseek/deepseek-chat"]
345382
custom_model_max_tokens=20000

pr_agent/algo/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,22 @@
165165
'bedrock/anthropic.claude-sonnet-4-20250514-v1:0': 200000,
166166
'bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0': 200000,
167167
'bedrock/anthropic.claude-sonnet-4-6': 200000,
168+
'bedrock/anthropic.claude-sonnet-4-6-v1:0': 200000,
169+
'bedrock/anthropic.claude-opus-4-5-20251101-v1:0': 200000,
168170
"bedrock/us.anthropic.claude-opus-4-20250514-v1:0": 200000,
169171
"bedrock/us.anthropic.claude-opus-4-1-20250805-v1:0": 200000,
170172
"bedrock/us.anthropic.claude-opus-4-6-20260120-v1:0": 200000,
171173
"bedrock/global.anthropic.claude-opus-4-5-20251101-v1:0": 200000,
174+
"bedrock/eu.anthropic.claude-opus-4-5-20251101-v1:0": 200000,
175+
"bedrock/au.anthropic.claude-opus-4-5-20251101-v1:0": 200000,
176+
"bedrock/jp.anthropic.claude-opus-4-5-20251101-v1:0": 200000,
177+
"bedrock/apac.anthropic.claude-opus-4-5-20251101-v1:0": 200000,
172178
"bedrock/us.anthropic.claude-opus-4-5-20251101-v1:0": 200000,
173179
"bedrock/global.anthropic.claude-opus-4-6-v1:0": 200000,
180+
"bedrock/eu.anthropic.claude-opus-4-6-v1:0": 200000,
181+
"bedrock/au.anthropic.claude-opus-4-6-v1:0": 200000,
182+
"bedrock/jp.anthropic.claude-opus-4-6-v1:0": 200000,
183+
"bedrock/apac.anthropic.claude-opus-4-6-v1:0": 200000,
174184
"bedrock/us.anthropic.claude-opus-4-6-v1:0": 200000,
175185
"bedrock/global.anthropic.claude-opus-4-7": 1000000,
176186
"bedrock/us.anthropic.claude-opus-4-7": 1000000,
@@ -187,16 +197,23 @@
187197
"bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000,
188198
"bedrock/au.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000,
189199
"bedrock/us.anthropic.claude-sonnet-4-6": 200000,
200+
"bedrock/us.anthropic.claude-sonnet-4-6-v1:0": 200000,
190201
"bedrock/au.anthropic.claude-sonnet-4-6": 200000,
202+
"bedrock/au.anthropic.claude-sonnet-4-6-v1:0": 200000,
191203
"bedrock/apac.anthropic.claude-3-5-sonnet-20241022-v2:0": 100000,
192204
"bedrock/apac.anthropic.claude-3-7-sonnet-20250219-v1:0": 200000,
193205
"bedrock/apac.anthropic.claude-sonnet-4-20250514-v1:0": 200000,
194206
"bedrock/eu.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000,
195207
"bedrock/eu.anthropic.claude-sonnet-4-6": 200000,
208+
"bedrock/eu.anthropic.claude-sonnet-4-6-v1:0": 200000,
196209
"bedrock/jp.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000,
197210
"bedrock/jp.anthropic.claude-sonnet-4-6": 200000,
211+
"bedrock/jp.anthropic.claude-sonnet-4-6-v1:0": 200000,
212+
"bedrock/apac.anthropic.claude-sonnet-4-6": 200000,
213+
"bedrock/apac.anthropic.claude-sonnet-4-6-v1:0": 200000,
198214
"bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0": 200000,
199215
"bedrock/global.anthropic.claude-sonnet-4-6": 200000,
216+
"bedrock/global.anthropic.claude-sonnet-4-6-v1:0": 200000,
200217
'claude-3-5-sonnet': 100000,
201218
'bedrock/us.meta.llama4-scout-17b-instruct-v1:0': 128000,
202219
'bedrock/us.meta.llama4-maverick-17b-instruct-v1:0': 128000,

0 commit comments

Comments
 (0)