From d4365e2f37c48e47d2ac075fd434b3bac7b666f9 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 4 May 2026 19:42:46 -0700 Subject: [PATCH] fix(iam): leave omitted DurationSeconds nil so STS default applies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- weed/iam/integration/iam_manager.go | 15 +++++++-------- weed/iam/integration/role_max_session_test.go | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/weed/iam/integration/iam_manager.go b/weed/iam/integration/iam_manager.go index 2d76d7e4b..223cf4689 100644 --- a/weed/iam/integration/iam_manager.go +++ b/weed/iam/integration/iam_manager.go @@ -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 diff --git a/weed/iam/integration/role_max_session_test.go b/weed/iam/integration/role_max_session_test.go index 60be6078e..9f011c71f 100644 --- a/weed/iam/integration/role_max_session_test.go +++ b/weed/iam/integration/role_max_session_test.go @@ -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)},