fix(iam): leave omitted DurationSeconds nil so STS default applies

capDurationByRole was substituting the role's MaxSessionDuration
when the caller omitted DurationSeconds entirely. AWS returns the
configured default (typically 1 hour) in that case, not the role's
upper bound — a 12h MaxSessionDuration shouldn't silently make every
no-duration assume-role mint a 12h session.

Return nil when requested is nil; let the downstream
calculateSessionDuration in the STS service apply its TokenDuration
default. The role-max upper bound still clamps when the request
arrives with a concrete value above the cap.

Addresses gemini high-priority review on PR #9318.
This commit is contained in:
Chris Lu
2026-05-04 22:06:19 -07:00
parent f9dfc0ea37
commit d4365e2f37
2 changed files with 8 additions and 9 deletions
+7 -8
View File
@@ -352,17 +352,16 @@ func (m *IAMManager) AssumeRoleWithWebIdentity(ctx context.Context, request *sts
}
// capDurationByRole returns the requested duration clamped to the role's
// MaxSessionDuration. A nil requested duration with a role cap returns the
// role cap so the STS service does not silently mint a session longer than
// the role permits.
// MaxSessionDuration. A nil requested duration is left nil so the STS
// service's calculateSessionDuration applies the global default (typically
// 1 hour) — substituting the role's max here would silently mint a 12h
// session for any caller who omitted DurationSeconds, which AWS does not
// do. The role-max upper bound still applies in the downstream cap chain
// once the request has a concrete duration.
func capDurationByRole(requested *int64, roleMax int64) *int64 {
if roleMax <= 0 {
if roleMax <= 0 || requested == nil {
return requested
}
if requested == nil {
v := roleMax
return &v
}
if *requested > roleMax {
v := roleMax
return &v
@@ -13,7 +13,7 @@ func TestCapDurationByRole(t *testing.T) {
}{
{"no cap, no request", nil, 0, nil},
{"no cap, with request", intPtr(7200), 0, intPtr(7200)},
{"cap only, no request -> use cap", nil, 3600, intPtr(3600)},
{"cap only, no request -> nil so STS default applies", nil, 3600, nil},
{"request below cap -> request", intPtr(1800), 3600, intPtr(1800)},
{"request equal cap -> request", intPtr(3600), 3600, intPtr(3600)},
{"request above cap -> cap", intPtr(43200), 3600, intPtr(3600)},