apache / apache/opendal-reqsign
Support assume-role profile chains backed by named SSO sessions
- Dominant language
- Rust
- Stars
- 169
- Forks
- 75
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 16
Description
## Summary
`DefaultCredentialProvider` cannot resolve a standard shared AWS configuration where the selected profile assumes a role through `source_profile` and the source profile obtains credentials from a named IAM Identity Center (`sso_session`) session.
This is one credential graph rather than two independent fallback providers: the SSO credentials must first be loaded for the source profile, then used to sign an STS `AssumeRole` request for the selected profile.
## Reproduction
The following example is entirely synthetic:
```ini
[profile operator]
role_arn = arn:aws:iam::111122223333:role/Operator
source_profile = sso-source
role_session_name = local-operator
region = us-west-2
[profile sso-source]
sso_session = example-session
sso_account_id = 111122223333
sso_role_name = ExampleAccess
[sso-session example-session]
sso_start_url = https://example.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access
```
Select `operator` through `AWS_PROFILE` or `DefaultCredentialProvider::builder().with_profile("operator")` after logging in with the AWS CLI.
## Current behavior
- [`ProfileCredentialProvider`](https://github.com/apache/opendal-reqsign/blob/e11dde0e55a84300c0397aa1faabafcce1235c0c/services/aws-core/src/provide_credential/profile.rs#L81-L228) only returns static `aws_access_key_id` / `aws_secret_access_key` values. It does not interpret `role_arn`, `source_profile`, or execute STS `AssumeRole`.
- [`SSOCredentialProvider`](https://github.com/apache/opendal-reqsign/blob/e11dde0e55a84300c0397aa1faabafcce1235c0c/services/aws-core/src/provide_credential/sso.rs#L138-L209) requires the legacy inline `sso_start_url` and `sso_region` fields. The `sso_session` key is declared but unused, and token cache lookup always hashes the start URL.
- Since the provider chain treats Profile and SSO as independent fallback slots, the selected `operator` profile cannot combine the SSO source credentials with the target role.
The result is no usable credential even when the AWS CLI can resolve the same profile and has a valid cached SSO login.
## Expected behavior
Resolve the shared-profile credential graph in AWS order:
1. Follow `source_profile` references until reaching a supported base credential provider.
2. For a named SSO base profile, resolve `sso_region` and `sso_start_url` from `[sso-session NAME]`, and use the session name for the AWS CLI token cache key.
3. Exchange the cached SSO token for source-role credentials.
4. Call STS `AssumeRole` sequentially for each role in the chain.
5. Detect missing profiles, cycles, and invalid combinations such as both `source_profile` and `credential_source`.
Legacy inline SSO configuration should remain compatible. Automated SSO token refresh can be scoped separately, but the intended behavior should be explicit because named SSO sessions support refresh while legacy SSO configuration does not.
## AWS sources
- [AWS SDKs and Tools: Assume role credential provider](https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html) documents `role_arn`, `source_profile`, and sequential role-chain resolution.
- [AWS SDKs and Tools: Assuming a role with AWS credentials](https://docs.aws.amazon.com/sdkref/latest/guide/access-assume-role.html) states that SDKs automatically make the corresponding STS `AssumeRole` call and that `source_profile` supports role chaining.
- [AWS CLI: Configuring IAM Identity Center authentication](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) documents the recommended `sso_session` layout, requires `sso_region` and `sso_start_url` in the `[sso-session]` section, and states that the cached token filename is based on the session name.
- The AWS SDK for Rust models this as a flattened base-provider plus role chain in [`profile/credentials/repr.rs`](https://github.com/awslabs/aws-sdk-rust/blob/main/sdk/aws-config/src/profile/credentials/repr.rs), with synthetic table-driven coverage in [`assume-role-tests.json`](https://github.com/awslabs/aws-sdk-rust/blob/main/sdk/aws-config/test-data/assume-role-tests.json). These are useful behavioral references without requiring an AWS SDK dependency.
## Implementation constraint
`DefaultCredentialProvider` currently lives in `aws-core`, while the concrete SigV4 request signer lives in `aws-v4`, which already depends on `aws-core`. Performing STS `AssumeRole` from the profile provider therefore needs an intentional ownership boundary to avoid a circular dependency or duplicated signing implementation.
Tests should use synthetic profiles, temporary config/cache directories, and mock HTTP responses only; they must not depend on or expose a developer's local `~/.aws` configuration.
Contributor guide
Research direction
Start with services/aws-core/src/provide_credential/profile.rs and sso.rs, then inspect DefaultCredentialProvider and the AWS SDK for Rust references in profile/credentials/repr.rs and assume-role-tests.json. Use synthetic profiles, temporary config/cache directories, and mock HTTP responses to cover named SSO sources, sequential role chains, invalid references, and cycles. Done means the selected profile resolves like the AWS CLI while legacy inline SSO remains compatible, without local AWS configuration or circular dependencies.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, rust
- Domain
- authentication, cloud
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100