Refactor: Replaces 'get_federation_token' with 'assume_role' in 'external_creds()' for IAM Role-based S3 credential generation#25
Closed
kellygavin96 wants to merge 1 commit intosmaht-dac:mainfrom
Conversation
…based S3 credential generation Previously, external_creds() used permanent IAM User access keys stored in Secrets Manager (S3_AWS_ACCESS_KEY_ID / S3_AWS_SECRET_ACCESS_KEY) to call sts:GetFederationToken and generate scoped temporary credentials for S3 file uploads and downloads. This required long-lived secrets to be maintained and rotated across multiple AWS accounts. This change replaces that pattern with sts:AssumeRole, which works with the existing ECS Fargate Task Roles and eliminates the need for any permanent IAM User credentials. Changes to encoded-core: - Remove explicit IAM User key construction from boto3 STS client - Replace get_federation_token(Name=...) with assume_role(RoleArn=..., RoleSessionName=...) - Update response handling: FederatedUser -> AssumedRoleUser - Read S3_UPLOAD_ROLE_ARN from GAC (Secrets Manager) or environment variable - All policy construction, KMS handling, and credential packaging unchanged Infrastructure changes applied per AWS account (cgap-dbmi, 4dn, smart-prod, smaht-wolf, cgap-mgb-prod, lzprod-cgap-production, cgap-dev-test): - Created dedicated S3 Upload IAM Role (encoded-core-s3-upload) with scoped S3 and KMS permissions - Added ECS Task Roles to S3 Upload Role trust policy - Added sts:AssumeRole permission to ECS Task Roles targeting S3 Upload Role - Added S3_UPLOAD_ROLE_ARN to each account Secrets Manager secret Testing: - Verified assume_role() returns correct credentials shape - Verified scoped credentials allow upload and download to target key only - Verified cross-key access is denied (policy enforcement confirmed) - Verified download-only credentials block PutObject - Verified KMS encrypted buckets work with KMS actions in session policy - No regressions in existing test suite
8b221ca to
a936827
Compare
Author
|
"Closing in favor of (#26) which is branched directly off the upstream repo." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Previously, external_creds() used permanent IAM User access keys stored in Secrets Manager (S3_AWS_ACCESS_KEY_ID / S3_AWS_SECRET_ACCESS_KEY) to call sts:GetFederationToken and generate scoped temporary credentials for S3 file uploads and downloads. This required long-lived secrets to be maintained and rotated across multiple AWS accounts.
This change replaces that pattern with sts:AssumeRole, which works with the existing ECS Fargate Task Roles and eliminates the need for any permanent IAM User credentials.
Addressing the concern
"You can't use a role to call get_federation_token"
Correct — but we don't need get_federation_token anymore. IAM Roles are already temporary. assume_role() does the same downscoping with the same inline Policy parameter and returns an identical Credentials object.
Code changes
Remove explicit IAM User key construction from boto3 STS client
Replace get_federation_token(Name=...) with assume_role(RoleArn=..., RoleSessionName=...)
Update response handling: FederatedUser → AssumedRoleUser
New env var: S3_UPLOAD_ROLE_ARN (role ARN to assume — replaces key pair)
Read S3_UPLOAD_ROLE_ARN from GAC (Secrets Manager) or environment variable
All policy construction, KMS handling, and credential packaging unchanged
Infrastructure changes applied per AWS account
Accounts: cgap-dbmi, 4dn, smaht-prod, smaht-wolf, cgap-mgb-prod, lzprod-cgap-production, cgap-dev-test
Created dedicated S3 Upload IAM Role (encoded-core-s3-upload) with scoped S3 and KMS permissions
Added ECS Task Roles to S3 Upload Role trust policy
Added sts:AssumeRole permission to ECS Task Roles targeting S3 Upload Role
Added S3_UPLOAD_ROLE_ARN to each account Secrets Manager secret
Testing
Standalone test script included: src/encoded_core/tests/test_assume_role_migration.py
✅ assume_role() returns correct credentials shape
✅ Scoped credentials allow upload and download to target key only
✅ Cross-key access denied (policy enforcement confirmed)
✅ Download-only credentials correctly block PutObject
✅ KMS encrypted buckets work with KMS actions in session policy
✅ No regressions in existing test suite