fix(sts): enforce AssumeRole trust with the real caller - #1442
Draft
NitinKumar004 wants to merge 1 commit into
Draft
NitinKumar004 wants to merge 1 commit into
NitinKumar004 wants to merge 1 commit into
Conversation
Under --enforce-auth the role trust policy is now evaluated for the signed caller, with principal types, NotPrincipal and conditions. Session credentials are limited to the STS and IAM calls AWS allows each kind, signed web identity and SAML calls are refused, and a RoleArn with another account or path no longer assumes the local role.
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.
AUTHZ-X1d. Also closes tracker row STS-X2.
Before this change, AssumeRole always evaluated the trust policy as if the account root were calling, whoever actually signed the request. Under
--enforce-auth, any caller withsts:AssumeRolecould therefore assume any role that trusted the account. A role that named one specific user could not be assumed by that user unless they also had an identity allow. Separately, the role was looked up by the last segment of the RoleArn, soarn:aws:iam::999999999999:role/Aorrole/x/Awould assume the local roleA.What changed
IAM:
EvaluateTrust(providers/aws/iam/trust_policy.go, newdriver.TrustEvaluator)"AWS"principals, or the plain string"*", can match a SigV4 caller.Service,FederatedandCanonicalUsernever match one."AWS":"*"matches anyone.arn:aws:iam::ACCT:rootor a bareACCTmatches any caller in that account.NamedDirectly.NotPrincipalis honoured on Deny statements. The caller escapes the Deny only when every ARN in its chain (the role and the session, for a role session) and the account are listed.Conditionis evaluated through the existing condition engine. Role tags are visible asaws:ResourceTag/*.ForAllValues:andForAnyValue:now work on multivalued keys, whichaws:TagKeysneeds.EvaluateAssumeRoleTrustis unchanged, so the auth-off path behaves exactly as before.STS: the decision under
--enforce-auth(server/aws/sts/trust.go)ResourcePolicychecks. The gate records the identity decision, and the handler finishes it:allowed = roleExists && trust.Allow && !trust.ExplicitDeny && identity != explicitDeny && (identity == allowed || trust.NamedDirectly).sts:ExternalId,sts:RoleSessionNameandsts:SourceIdentity;aws:RequestTag/*,aws:TagKeysandsts:TransitiveTagKeys;aws:PrincipalArnset to the role ARN.sts:TagSession(in both the trust policy and the identity policy, same rule as above). PassingSourceIdentityalso requiressts:SetSourceIdentity.User: <caller> is not authorized to perform: sts:AssumeRole on resource: <RoleArn as sent>. The message is the same whether or not the role exists.AssumeRoleWithWebIdentityandAssumeRoleWithSAMLnow return 403 AccessDenied under--enforce-auth, because the token or assertion is not validated. Unsigned calls still get MissingAuthenticationToken. Auth-off behaviour is unchanged.Session kinds (
SessionOwner.KindreplacesRole bool)The gate refuses the following calls whatever the policies say:
STS-X2
The RoleArn must equal the stored ARN of the role, including account and path. If it doesn't, the call is refused like a missing role: AccessDenied, naming the RoleArn as sent. This applies with auth on and off, whenever IAM is wired.
Sources (re-checked during research)
sts:TagSession) and SourceIdentity (sts:SetSourceIdentity).Known gaps (tracked separately)
Verification
Tests were written first and failed on the old code:
server/aws/sts/trust_enforced_test.go(real SDK against an enforced server);providers/aws/iam/evaluate_trust_test.go;server/aws/authz_matrix_test.go;TestEnforceAuthAssumeRoleTrustin contrib/server.Commands that pass:
go build ./...go test -raceonproviders/aws/iam,server/aws/...andserver/wire/...go -C contrib/server test -run Enforcegolangci-lint --new-from-rev=origin/development(root and contrib/server): 0 issuesdocs/coveragefor the newTrustEvaluatorReal
awsCLI againstcloudemu serve --enforce-auth, bootstrapped through the admin token and seedediamUsers:sts assume-rolewithout--external-idsts assume-rolewith--external-idsts:AssumeRole, then succeeds