Skip to content

aws-agent-toolkit: accept AWS access keys as saved credentials - #23

Merged
morgante merged 5 commits into
CognitionAI:mainfrom
bsmitches:devin/aws-agent-toolkit-env-credentials
Sep 15, 2026
Merged

morgante merged 5 commits into
CognitionAI:mainfrom
bsmitches:devin/aws-agent-toolkit-env-credentials

Conversation

@bsmitches

@bsmitches bsmitches commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #22. Declares the three standard AWS credential env vars on the aws-agent-toolkit server so a user with no shared config, SSO session or instance role can supply keys through the plugin:

"AWS_ACCESS_KEY_ID": "${AWS_ACCESS_KEY_ID:-}",
"AWS_SECRET_ACCESS_KEY": "${AWS_SECRET_ACCESS_KEY:-}",
"AWS_SESSION_TOKEN": "${AWS_SESSION_TOKEN:-}"

AWS_MCP_PROXY_PROFILES and AWS_REGION are unchanged, and the description now explains that keys must be set as a pair and that they take precedence over any profile.

Why the ${NAME:-} form matters here

All three use the empty-default form rather than a bare ${NAME}. This is not cosmetic. botocore's EnvProvider gates on a truthy access key, not a valid one:

access_key = self.environ.get(self._mapping['access_key'], '')
if access_key:
    logger.info('Found credentials in environment variables.')

So an empty value falls through to the rest of the chain, but an unsubstituted literal ${AWS_ACCESS_KEY_ID} would be treated as a real access key. I tested that case against the live endpoint: the tool call fails with failed due to expired or invalid AWS credentials and does not fall back to the shared-config credentials that were working a moment earlier. The empty-default form removes that exposure entirely.

Test evidence

Carried over from the testing done on #22, against the real https://aws-mcp.us-east-1.api.aws/mcp endpoint (initialize + tools/call running sts:GetCallerIdentity):

Env state Result
All credential vars empty Succeeds — falls through to shared config / aws login session
Complete but invalid keys Fails with a clear invalid AWS credentials message, confirming the env provider is consumed and takes precedence over the profile
Bare ${AWS_ACCESS_KEY_ID} literal Fails and shadows the working chain — the case this form avoids

One sharp edge worth knowing, also measured: setting AWS_ACCESS_KEY_ID without AWS_SECRET_ACCESS_KEY does not fall through and does not report a credential error — the proxy comes up with no tools and reports Unknown tool: 'aws___run_script'. That is upstream behaviour in mcp-proxy-for-aws, not something this manifest can guard, which is why the description tells users to set the two together.

Not exercised, since the test machine has no such credentials: SSO, EC2/ECS instance roles, web identity, process credentials. They ride the same boto3.Session() as the tested sources.

Test plan

  • python3 scripts/validate.pyok: 171 entries (170 authored, 1 upstream)
  • python3 scripts/validate.py --fetch → all pinned upstream shas resolve
  • Each env value is a plain ${<OWN_KEY>} placeholder matching its own env key; no credential values checked in

Generated with Devin


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Devin Review (Staging)

Brian Smitches and others added 5 commits September 14, 2026 19:13
The plugin is the Agent Toolkit for AWS, so name the card after it rather
than AWS Core. Credentials come from the standard AWS chain, and the
toolkit selects profiles via AWS_MCP_PROXY_PROFILES, so replace the
AWS_PROFILE entry and let both env values default to empty when the user
has saved nothing.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Live-tested the config against the proxy. AWS_MCP_PROXY_PROFILES takes a
space-separated list and enables per-call switching via the aws_profile
tool parameter, and determine_aws_region() reads the profile's region
first and only falls back to AWS_REGION when the profile sets none, so
AWS_REGION does not override a profile region. Say both accurately.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Users who have no shared config, SSO session or instance role had no way
to give the toolkit credentials through the plugin. Declare the three
standard env vars so keys can be supplied directly, in the ${NAME:-}
form: botocore gates the env provider on a truthy access key, so an
empty value falls through to the normal chain, while an unsubstituted
bare ${NAME} literal would count as a real key and shadow credentials
that were otherwise working.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The fork merged the rename with a merge commit while upstream squash-merged
the same content, so the two histories carried identical changes under
different shas and collided on the toolkit manifest. Resolved in favour of
this branch, whose manifest is a superset: same description plus the
access-key clause, and the env block with the three credential vars.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@morgante
morgante merged commit ce6263a into CognitionAI:main Sep 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants