Repository navigation
Conversation
anxkhn
force-pushed
the
fix/reposerver-assume-role-duration
branch
from
August 12, 2026 05:24
d8c249d to
5ac6de8
Compare
Add a regression test asserting the resolved assume-role duration converts to a DurationSeconds of at least the STS 900s minimum, and documenting that a sub-second duration truncates to 0. The original repository-server call site that passed time.Duration(time.Now().Second()) was removed upstream with the repositoryserver CRD, so this keeps the duration contract coverage. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
anxkhn
force-pushed
the
fix/reposerver-assume-role-duration
branch
from
August 20, 2026 12:05
5ac6de8 to
5cbd2fe
Compare
This branch has not been deployed
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.
Change Overview
RepoServerHandler.setCredDataFromSecretInPodbuilds the credential environmentvariables for the kopia repository-server pod. It passed
time.Duration(time.Now().Second())as the AWS assume-role session duration:time.Time.Second()returns the wall-clock seconds field as anintin[0, 59],and
time.Durationinterprets thatintas nanoseconds. So the value handed tothe AWS
AssumeRole/AssumeRoleWithWebIdentityprovider is only0-59nsand itchanges every second.
That duration flows through
GenerateEnvSpecFromCredentialSecret->getEnvSpecForAWSCredentialSecret->secrets.ExtractAWSCredentials; for a role-based secret it is stored as its.String()form and parsed back bydurationFromString, then reaches the SDK'sstscredsproviders. Those providers compute the STS request asDurationSeconds = int32(duration / time.Second)(
assume_role_provider.go,web_identity_provider.go), which truncates anysub-second duration to
0. AWS STS rejectsDurationSecondsbelow its documented900s (15m) minimum for
AssumeRole/AssumeRoleWithWebIdentity.Net effect: whenever the storage credential secret uses an IAM role (config role /
web identity), repository-server credential env generation fails for roughly 59 of
every 60 wall-clock seconds. It only "works" in the single second where
Second() == 0, because a0duration falls through to the provider's 15m default.Static access-key secrets are unaffected, since the duration is unused for them.
This change passes
aws.AssumeRoleDurationDefault(60m) instead, which is exactlythe value already used at the other
ExtractAWSCredentialscall sites(
pkg/restic/restic.go,pkg/validate/validate.go,pkg/location/location.go).That removes the wall-clock dependence and yields a valid STS session duration. The
now-unused
timeimport is dropped fromhandler.go.Issues
Ref #
Test Plan
Added
TestAssumeRoleDurationRoundTripinpkg/aws/aws_test.go. It drives the realdurationFromStringparser and mirrors the SDK'sDurationSeconds = int32(duration / time.Second)derivation to assert that:AssumeRoleDurationDefaultresolves to aDurationSeconds>= the STS 900s minimum,DurationSeconds = 0,documenting the exact behaviour this fix avoids.
Commands run locally:
All pass; golangci-lint reports 0 issues; gofmt clean.
The role path in the handler itself ends in a live STS
Retrieve, so it is notexercisable offline without AWS credentials; the regression guard is therefore placed
at the deepest pure-Go seam (
durationFromStringplus the SDK'sDurationSecondsformula).