fix(aws): use default credential chain#403
Conversation
Signed-off-by: Oleg Leizerov <oleizerov@nvidia.com>
Signed-off-by: Oleg Leizerov <oleizerov@nvidia.com>
Greptile SummaryThis PR fixes a bug where the AWS provider always fell back to the EC2 instance-role credential provider (
Confidence Score: 5/5Safe to merge — the change correctly delegates credential resolution to the AWS SDK default chain, removing a hand-rolled EC2 IMDS fallback that blocked EKS Pod Identity and IRSA. No existing credential paths are removed; explicit static credentials and environment variables still work through the SDK chain. The refactor is small and well-contained: two provider files change, the new behaviour is fully exercised by five new integration-style tests, and the change was validated end-to-end on an EKS cluster with EC2 metadata disabled. The old busy-wait retry loop and its race-prone timing constant are cleanly removed. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Loader called with cfg.Creds] --> B{Creds empty?}
B -- Yes --> C[return nil provider\nSDK default chain]
B -- No --> D[Decode explicit credentials]
D --> E{Decode error?}
E -- Yes --> F[HTTP 400 Bad Request]
E -- No --> G[StaticCredentialsProvider]
C --> H[loadAWSConfig without provider]
G --> I[loadAWSConfig with static provider]
H --> J[SDK default chain\nenv, shared config, web identity,\ncontainer/Pod Identity, EC2 IMDS]
I --> K[Static provider overrides SDK chain]
J --> L[Client with awsCfg.Credentials set]
K --> L
L --> M[generateRegionInstanceTopology]
M --> N{credentials != nil?}
N -- Yes --> O[credentials.Retrieve]
O --> P{Retrieve error?}
P -- Yes --> Q[HTTP 401 Unauthorized]
P -- No --> R[EC2 DescribeInstanceTopology]
N -- No --> R
R --> S{EC2 error?}
S -- Yes --> T[HTTP 502 Bad Gateway]
S -- No --> U[Process topology output]
Reviews (3): Last reviewed commit: "Merge branch 'main' into fix/aws-default..." | Re-trigger Greptile |
|
/ok-to-test 4473a9e |
|
🌿 Preview your docs: https://nvidia-preview-pull-request-403.docs.buildwithfern.com/topograph |
ArangoGutierrez
left a comment
There was a problem hiding this comment.
Solid refactor — moving to the SDK default credential chain is the right call, and the new tests genuinely exercise precedence and auto-refresh rather than asserting SDK tautologies. Two behavior changes worth a quick confirm below.
- One precedence change worth confirming is intentional: the old resolver only consulted request creds, then AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, then the EC2 instance role — it never read ~/.aws/config, ~/.aws/credentials, or AWS_PROFILE. The full default chain places shared-config/profile (and IRSA) ahead of the instance role, so a host with stray ~/.aws state or an exported AWS_PROFILE that previously fell through to instance-role creds will now silently authenticate as that profile identity. The docs cover the env / Pod Identity case; worth extending the caveat to shared-config/profile too. (pkg/providers/aws/provider.go:126)
- With no explicit creds, credential-resolution failure is now deferred to the API call: the old ec2rolecreds path returned 401 at load time when instance-role creds couldn't be retrieved, whereas an unresolvable default chain now surfaces as the 502 from DescribeInstanceTopology. #177 deliberately curated these status codes, so worth deciding whether a no-credentials failure should still present as 401 rather than 502. (pkg/providers/aws/provider.go:104)
| SecretAccessKey: secretAccessKey, | ||
| Token: sessionToken, | ||
| }, nil | ||
| return config.LoadDefaultConfig(ctx, opts...) |
There was a problem hiding this comment.
One precedence change worth confirming is intentional: the old resolver only consulted request creds, then AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, then the EC2 instance role — it never read ~/.aws/config, ~/.aws/credentials, or AWS_PROFILE. The full default chain places shared-config/profile (and IRSA) ahead of the instance role, so a host with stray ~/.aws state or an exported AWS_PROFILE that previously fell through to instance-role creds will now silently authenticate as that profile identity. The docs cover the env / Pod Identity case; worth extending the caveat to shared-config/profile too.
There was a problem hiding this comment.
Yes, the expanded precedence is intentional because the goal is to use the standard SDK chain. I’ll make the warning explicit for AWS_PROFILE and shared config/credentials files.
| func getCredentialsProvider(creds map[string]any) (aws.CredentialsProvider, *httperr.Error) { | ||
| if len(creds) == 0 { | ||
| klog.Infof("Using AWS SDK default credential chain") | ||
| return nil, nil |
There was a problem hiding this comment.
With no explicit creds, credential-resolution failure is now deferred to the API call: the old ec2rolecreds path returned 401 at load time when instance-role creds couldn't be retrieved, whereas an unresolvable default chain now surfaces as the 502 from DescribeInstanceTopology. #177 deliberately curated these status codes, so worth deciding whether a no-credentials failure should still present as 401 rather than 502.
There was a problem hiding this comment.
Good catch. The status-code change was not intentional. I’ll preserve the previous 401 for credential-resolution failures while keeping EC2 API authorization errors as 502.
Signed-off-by: Oleg Leizerov <oleizerov@nvidia.com>
Signed-off-by: Oleg Leizerov <olegleyz@gmail.com>
ArangoGutierrez
left a comment
There was a problem hiding this comment.
Second-round review — both items from the previous round are addressed:
- The credential-precedence caveat now documents that environment and shared-profile sources (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, AWS_PROFILE, ~/.aws/config, ~/.aws/credentials) can take priority over EKS Pod Identity or an EC2 instance role.
- A missing/unresolvable credential now surfaces as 401 again, via the pre-flight Retrieve check before the EC2 call, with tests covering the 401 and 502 paths plus a real credential-refresh test against a fake container-credentials endpoint.
No new issues found — checked for bugs, Go conventions, test quality, security, and CLAUDE.md compliance.
Description
The AWS provider currently calls the EC2 instance-role credential provider whenever Topograph-specific credentials are absent. That bypasses the AWS SDK default credential chain, so EKS Pod Identity and IRSA credentials injected into the Topograph pod are ignored and the EC2 node role is used instead.
This change:
ec2:DescribeInstanceTopologypermission.Tests cover invalid and valid explicit credentials, explicit-over-environment precedence, environment credentials, EKS container credentials with an authorization token file, and refresh after expiration.
Validation
make qualifyAWS integration test
Validated commit
4473a9eon thenkx-slinky-gb300-dev-01EKS cluster:topographServiceAccount and its EKS Pod Identity association with the dedicatedaehiqzudem-topographIAM role.AWS_EC2_METADATA_DISABLED=trueto prevent fallback to the EC2 node role.The request used the AWS SDK default credential chain, extracted topology for 35 instances, updated the test ConfigMap, and completed with HTTP 200. No authorization errors occurred.
Checklist
git commit -s).