AWS Secrets Manager plugin cannot use IRSA or an instance role — static keys are mandatory
- Dominant language
- Python
- Stars
- 9
- Forks
- 41
- Avg merge
- 8d 14h
- Merged PRs (30d)
- 2
Description
## Summary
`aws_secretsmanager` requires `aws_access_key` and `aws_secret_key`, so the plugin is only usable
with long-lived IAM user keys. On EKS the AWX task pod already has a role-based identity via IRSA,
and botocore resolves it without any plugin changes if the keys are passed as `None`.
The HashiCorp Vault plugin in this package already works this way — its `required` list excludes
every auth field, and it selects an auth method from whatever is supplied, including
`kubernetes_role` and `workload_identity_token`. This is a request to make the AWS plugin
consistent with it.
## Current behavior
Two things make static keys mandatory:
- `secrets_manager_inputs['required']` lists `aws_access_key` and `aws_secret_key`, so a credential
of this type cannot be saved without them.
- `aws_secretsmanager_backend` reads both with direct indexing and passes them to
`session.client()` unconditionally.
⇒ the only way to use the plugin is to create an IAM user, issue a static access key, and store it
in AWX.
## Desired behavior
| Keys supplied | Behavior |
| --- | --- |
| Yes | unchanged |
| No | botocore's default chain resolves: env vars → web identity token (IRSA) → container/instance metadata |
## Suggested change
Two edits, no new authentication code — botocore does the work, given `None` rather than empty
strings:
```
# inputs
'required': ['region_name', 'secret_name'] # drop the two key fields
# backend
aws_access_key_id = kwargs.get('aws_access_key') or None
aws_secret_access_key = kwargs.get('aws_secret_key') or None
```
Coercing empty to `None` matters: botocore treats `None` as "not supplied" and falls through to the
chain, whereas an empty string is treated as a supplied credential and fails at signing time.
`region_name` and `secret_name` are metadata, set per input source, so they can stay required.
## Why this matters
| Concern | Static access key | Default credential chain |
| --- | --- | --- |
| Lifetime | long-lived, rotated by hand | short-lived STS credentials, rotated automatically |
| Blast radius | valid anywhere the key reaches | role assumable only by the annotated service account |
| Material stored in AWX | an IAM key, in the AWX database | none |
| Scope | whatever the IAM user can read | bounded by the role's trust policy |
An external credential lookup exists to keep secret material out of AWX. Requiring a static cloud
key inverts that: it trades N application secrets for one broader, longer-lived credential that can
read all of them, and that credential lives in the AWX database.
Organizations that prohibit static IAM users as policy cannot use this plugin at all, on the
platform where AWX is most often deployed.
## Precedent in this package
| Plugin | Static credential required? |
| --- | --- |
| `hashivault` | no — `kubernetes_role` and `workload_identity_token` auth, chosen from supplied fields |
| `github_app` | no — its own App private key, scoped to selected repositories, mints short-lived tokens |
| `aws_secretsmanager` | yes |
## Environment
- `awx-plugins-core`, `credentials-aws-secretsmanager`
- AWX 25.4.0 on EKS via awx-operator, task pod service account annotated for IRSA
Contributor guide
Research direction
Start with the `secrets_manager_inputs['required']` definition and the `aws_secretsmanager_backend` credential lookup described in the issue. Make optional keys fall through to botocore while preserving the existing behavior when keys are supplied. Done means credentials can be saved with only `region_name` and `secret_name`, and the default chain can resolve IRSA or instance-role credentials.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, python
- Domain
- backend, cloud
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100