Skip to content

Support cross aws account iam role authetication#979

Open
munishchouhan wants to merge 8 commits intomasterfrom
001-cross-account-iam-role-auth
Open

Support cross aws account iam role authetication#979
munishchouhan wants to merge 8 commits intomasterfrom
001-cross-account-iam-role-auth

Conversation

@munishchouhan
Copy link
Member

Summary

Add support for AWS IAM cross-account role assumption in Wave for ECR authentication. This enables users to configure AWS credentials with assume role ARN and external ID
in Tower/Platform, allowing Wave to securely access ECR repositories across AWS accounts without sharing long-term credentials.

Changes

Core Implementation

  • ContainerRegistryKeys (src/main/groovy/io/seqera/wave/service/ContainerRegistryKeys.groovy:57-60):
    • Modified to support AWS assume role credentials from Tower
    • Maps assumeRoleArn → userName and externalId → password
    • Removed warning about unsupported assume role, now fully implemented
  • AwsEcrService (src/main/groovy/io/seqera/wave/service/aws/AwsEcrService.groovy):
    • Added assumeRole() method for STS AssumeRole API calls
    • Automatic detection of role ARN vs access key via pattern matching
    • Support for session tokens in temporary credentials
    • Enhanced caching strategy for role-based credentials
    • Comprehensive error mapping for STS exceptions with actionable messages
    • Added getLoginTokenWithRole() and getLoginTokenWithStaticCredentials() methods

Testing

  • ContainerRegistryKeysTest (src/test/groovy/io/seqera/wave/service/ContainerRegistryKeysTest.groovy):
    • Comprehensive unit tests for all authentication scenarios
    • Tests for container registry credentials parsing
    • Tests for AWS access key credentials
    • Tests for AWS assume role with/without external ID
    • Tests for toString() redaction of sensitive fields
    • Tests for various registry hostnames (Docker Hub, Quay, ECR, GCR, etc.)

Dependencies

  • build.gradle:
    • Changed software.amazon.awssdk:sts from runtimeOnly to implementation
    • Required for direct usage of STS AssumeRole API

Documentation

  • Added comprehensive specification documents under specs/001-cross-account-iam-role-auth/:
    • Service interface contracts
    • STS integration contracts
    • Data model documentation

Technical Details

Authentication Flow:

  1. Wave receives ECR image request with Tower credentials
  2. Tower returns assume role ARN + external ID (via ContainerRegistryKeys)
  3. Wave detects role ARN pattern and calls STS AssumeRole using default AWS credentials
  4. STS returns temporary credentials (access key + secret + session token)
  5. Wave uses temporary credentials to get ECR authorization token
  6. Credentials cached with proper expiration handling

Backward Compatibility:

  • Existing static AWS credentials continue to work unchanged
  • Detection is automatic via pattern matching - no API changes
  • All existing tests remain passing

Security Considerations

  • External ID support for confused deputy attack prevention
  • Temporary credentials expire after 1 hour
  • Session tokens properly included in all API calls
  • Sensitive fields redacted in logs and toString() methods
  • Uses Wave's default AWS credentials (environment/IAM role) to assume customer roles

Test Plan

  • Unit tests for ContainerRegistryKeys parsing
  • Unit tests for AwsEcrService role assumption
  • Integration test with local Tower (manual testing required)
  • End-to-end test with real ECR repository (manual testing required)

Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
@munishchouhan munishchouhan self-assigned this Feb 11, 2026
@munishchouhan munishchouhan marked this pull request as draft February 11, 2026 12:04
@munishchouhan munishchouhan marked this pull request as ready for review February 13, 2026 16:29
@munishchouhan
Copy link
Member Author

@claude reveiw

@claude
Copy link

claude bot commented Feb 13, 2026

Claude finished @munishchouhan's task —— View job


Code Review for Cross-Account IAM Role Authentication

I've completed a comprehensive review of this PR that adds AWS IAM cross-account role authentication support. This is a solid implementation with excellent security practices and thorough testing.

Summary

This PR successfully implements AWS IAM cross-account role assumption for ECR authentication, allowing Wave to securely access ECR repositories across AWS accounts without sharing long-term credentials. The implementation is backward compatible and follows security best practices.

Code Quality Assessment: ✅ Excellent

Core Implementation Quality

ContainerRegistryKeys.groovy - src/main/groovy/io/seqera/wave/service/ContainerRegistryKeys.groovy:57-60

  • ✅ Clean mapping of assumeRoleArn → userName and externalId → password
  • ✅ Proper priority: IAM role credentials take precedence over access keys
  • ✅ Good security logging with sensitive data redaction
  • ✅ toString() method properly redacts sensitive fields

AwsEcrService.groovy - Excellent implementation with comprehensive features:

  • Pattern matching: Clean detection of role ARN vs access key using AWS_ROLE_ARN regex pattern (line 64)
  • Security: Proper session token handling in all AWS SDK calls (lines 196-213)
  • Error handling: Excellent STS exception mapping with actionable error messages (lines 162-193)
  • Caching strategy: Smart cache key using stable roleArn instead of temporary credentials (lines 288-295)
  • Session naming: Good practice using timestamp in session names (line 139)
  • Duration: Appropriate 1-hour session duration (line 140)

CredentialServiceImpl.groovy - Well-integrated with existing flow:

  • ✅ Maintains existing AWS credential lookup logic
  • ✅ Proper integration with Tower's credential system

Test Coverage Quality: ✅ Outstanding

ContainerRegistryKeysTest.groovy - Comprehensive unit tests (304 lines):

  • ✅ Tests all authentication scenarios (container-reg, AWS access keys, IAM roles)
  • ✅ Tests role prioritization over access keys
  • ✅ Tests with/without external ID
  • ✅ Tests toString() redaction for various password lengths
  • ✅ Tests various registry hostnames (Docker Hub, Quay, ECR, GCR, etc.)
  • ✅ Tests error conditions and edge cases
  • ✅ Tests JSON parsing with extra fields

AwsEcrServiceTest.groovy - Thorough unit tests:

  • ✅ Tests role ARN pattern detection with valid/invalid patterns
  • ✅ Tests cache key generation for static vs session credentials
  • ✅ Tests parameter validation
  • ✅ Tests integration with existing ECR functionality

Security Assessment: ✅ Excellent

  • External ID support: Prevents confused deputy attacks (line 144)
  • Temporary credentials: 1-hour expiration reduces exposure (line 140)
  • Session tokens: Properly included in all API calls
  • Credential redaction: Sensitive data properly masked in logs and toString()
  • Default credentials: Uses Wave's default AWS credentials to assume customer roles
  • Exception mapping: Comprehensive error handling without exposing sensitive details

Dependency Changes: ✅ Appropriate

build.gradle - Line 96:

  • ✅ Changed software.amazon.awssdk:sts from runtimeOnly to implementation
  • ✅ Required for direct STS AssumeRole API usage - this change is correct and necessary

Documentation: ✅ Comprehensive

The specs/ directory contains extensive documentation covering:

  • Service interface contracts
  • STS integration contracts
  • Data model documentation
  • Implementation plans and research

Minor Suggestions for Future Enhancement

  1. Metrics: Consider adding metrics for role assumption success/failure rates
  2. Logging: Could add trace-level logging for cache hit/miss scenarios
  3. Error context: STS error messages could include the role ARN for easier debugging

Backward Compatibility: ✅ Maintained

  • ✅ Existing static AWS credentials continue to work unchanged
  • ✅ Automatic detection via pattern matching requires no API changes
  • ✅ All existing functionality preserved

Final Assessment

This is a high-quality implementation that:

  • ✅ Follows AWS security best practices
  • ✅ Has comprehensive test coverage
  • ✅ Maintains backward compatibility
  • ✅ Includes proper error handling and logging
  • ✅ Uses appropriate caching strategies

The code is production-ready and demonstrates excellent understanding of AWS IAM, STS, and ECR authentication patterns.

Recommendation: ✅ APPROVED - This PR is ready to merge.

@munishchouhan
Copy link
Member Author

Tested locally with assume role and external Id

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we allow the use of credentials that are not assigned to this exact workflow? Isn't this incorrect? (I see the comment so I know it's intentional but I'd like to know the rationale behind it).

Copy link
Member Author

@munishchouhan munishchouhan Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wave uses a user access token to retrieve credentials from the platform. If a request is from a pipeline run, then there will be a workflow ID and also a compute present. But if the call is from Wave CLI or API workflow id won't be there

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After more consideration, I think you might be right, We only to this credentials when a call is from platfrom, and currently it is only from pipeline runs

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

Comments