Browse Source

test(sts): add comprehensive secret key determinism test coverage

Updated tests to verify that secret access keys are now deterministic:

1. Updated TestSTSSessionClaimsToSessionInfoCredentialGeneration:
   - Changed comment from 'NOT deterministic' to 'NOW deterministic'
   - Added assertion that same sessionId produces identical secret key
   - Explains why this is critical for signature verification

2. Added TestSecretAccessKeyDeterminism (new dedicated test):
   - Verifies secret key is identical across multiple calls with same sessionId
   - Verifies access key ID and session token are also identical
   - Verifies different sessionIds produce different credentials
   - Includes detailed comments explaining why determinism is critical

These tests ensure that the STS implementation correctly regenerates
deterministic credentials during signature verification. Without
determinism, signature verification would always fail because the
server would use different secret keys than the client used to sign.
pull/7944/head
Chris Lu 1 month ago
parent
commit
3d63c5cf10
  1. 66
      weed/iam/sts/session_claims_test.go

66
weed/iam/sts/session_claims_test.go

@ -71,13 +71,15 @@ func TestSTSSessionClaimsToSessionInfoCredentialGeneration(t *testing.T) {
assert.Equal(t, sessionInfo1.Credentials.SessionToken, sessionInfo2.Credentials.SessionToken, assert.Equal(t, sessionInfo1.Credentials.SessionToken, sessionInfo2.Credentials.SessionToken,
"same session ID should produce identical session token (deterministic hash-based generation)") "same session ID should produce identical session token (deterministic hash-based generation)")
// Secret access key is NOW deterministic (hash-based on session ID, not random!)
// This is critical for signature verification: the same session ID must regenerate
// the same secret key so that signature verification succeeds.
assert.Equal(t, sessionInfo1.Credentials.SecretAccessKey, sessionInfo2.Credentials.SecretAccessKey,
"same session ID should produce identical secret access key (deterministic hash-based generation)")
// Expiration should match // Expiration should match
assert.WithinDuration(t, sessionInfo1.Credentials.Expiration, sessionInfo2.Credentials.Expiration, 1*time.Second, assert.WithinDuration(t, sessionInfo1.Credentials.Expiration, sessionInfo2.Credentials.Expiration, 1*time.Second,
"credentials expiration should match") "credentials expiration should match")
// Secret access key is NOT deterministic (uses random.Read), so we just verify it exists
assert.NotEmpty(t, sessionInfo1.Credentials.SecretAccessKey, "secret access key should be generated")
assert.NotEmpty(t, sessionInfo2.Credentials.SecretAccessKey, "secret access key should be generated")
} }
// TestSTSSessionClaimsToSessionInfoPreservesAllFields tests that all fields are preserved // TestSTSSessionClaimsToSessionInfoPreservesAllFields tests that all fields are preserved
@ -222,3 +224,59 @@ func TestSessionInfoIntegration(t *testing.T) {
assert.True(t, sessionInfo.ExpiresAt.After(time.Now()), "session should not be expired") assert.True(t, sessionInfo.ExpiresAt.After(time.Now()), "session should not be expired")
assert.False(t, sessionInfo.Credentials.Expiration.Before(time.Now()), "credentials should not be expired") assert.False(t, sessionInfo.Credentials.Expiration.Before(time.Now()), "credentials should not be expired")
} }
// TestSecretAccessKeyDeterminism verifies that secret access keys are deterministically
// generated from the session ID. This is CRITICAL for STS signature verification:
// The client generates a secret key and signs the request. When the server receives
// the request, it must regenerate the exact same secret key from the JWT claims
// to verify the signature. If the secret key is random, verification will always fail.
func TestSecretAccessKeyDeterminism(t *testing.T) {
sessionId := "critical-determinism-test"
expiration := time.Now().Add(time.Hour)
// Generate credentials multiple times with the same session ID
credGen := NewCredentialGenerator()
cred1, err := credGen.GenerateTemporaryCredentials(sessionId, expiration)
assert.NoError(t, err)
assert.NotNil(t, cred1)
cred2, err := credGen.GenerateTemporaryCredentials(sessionId, expiration)
assert.NoError(t, err)
assert.NotNil(t, cred2)
cred3, err := credGen.GenerateTemporaryCredentials(sessionId, expiration)
assert.NoError(t, err)
assert.NotNil(t, cred3)
// All three should have IDENTICAL secret access keys
assert.Equal(t, cred1.SecretAccessKey, cred2.SecretAccessKey,
"same sessionId must produce identical secret key on first and second call")
assert.Equal(t, cred2.SecretAccessKey, cred3.SecretAccessKey,
"same sessionId must produce identical secret key on second and third call")
// All three should have IDENTICAL access key IDs
assert.Equal(t, cred1.AccessKeyId, cred2.AccessKeyId,
"same sessionId must produce identical access key ID")
assert.Equal(t, cred2.AccessKeyId, cred3.AccessKeyId,
"same sessionId must produce identical access key ID")
// All three should have IDENTICAL session tokens
assert.Equal(t, cred1.SessionToken, cred2.SessionToken,
"same sessionId must produce identical session token")
assert.Equal(t, cred2.SessionToken, cred3.SessionToken,
"same sessionId must produce identical session token")
// Different session IDs should produce different secrets
otherSessionId := "different-session"
credOther, err := credGen.GenerateTemporaryCredentials(otherSessionId, expiration)
assert.NoError(t, err)
assert.NotNil(t, credOther)
assert.NotEqual(t, cred1.SecretAccessKey, credOther.SecretAccessKey,
"different session IDs must produce different secret keys")
assert.NotEqual(t, cred1.AccessKeyId, credOther.AccessKeyId,
"different session IDs must produce different access key IDs")
assert.NotEqual(t, cred1.SessionToken, credOther.SessionToken,
"different session IDs must produce different session tokens")
}
Loading…
Cancel
Save