fix(predictions): fix Face Liveness with temporary credentials on iOS 26 (URL signing + Sendable credentials) - #4248
Merged
Merged
Conversation
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
had a problem deploying
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Error
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
had a problem deploying
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Error
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
thisisabhash
temporarily deployed
to
IntegrationTest
July 13, 2026 20:21 — with
GitHub Actions
Inactive
7 tasks
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4248 +/- ##
==========================================
+ Coverage 66.91% 66.96% +0.04%
==========================================
Files 1151 1151
Lines 43870 43874 +4
==========================================
+ Hits 29357 29379 +22
+ Misses 14513 14495 -18
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
thisisabhash
had a problem deploying
to
IntegrationTest
July 13, 2026 21:29 — with
GitHub Actions
Error
thisisabhash
had a problem deploying
to
IntegrationTest
July 17, 2026 16:47 — with
GitHub Actions
Error
Co-authored-by: zhouzihao <zhouzihao@changzhi.top>
harsh62
approved these changes
Jul 17, 2026
This was referenced Aug 5, 2026
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.
Issue
Fixes aws-amplify/amplify-ui-swift-liveness#225
FaceLiveness fails with
FaceLivenessDetectionError.unknown(Rekognition returnsUnrecognizedClientException, websocket close code 4005) when the caller supplies temporary credentials via a customAWSCredentialsProvider. Long-term credentials are unaffected.Root Cause
Two independent bugs contributed to signing failures with temporary credentials:
1. SigV4 URL signing
The canonical query string was built from
url.query, which drops/round-trips query items incorrectly, and the query-item split on=used the default (unbounded)maxSplits, which corrupted values that themselves contain=(e.g. base64 padding in aX-Amz-Security-Token). This produced an invalid signature.URLComponents.queryItemsso existing items are preserved verbatim.key=valuepair withmaxSplits: 1so values containing=survive percent-encoding intact.2. Actor-isolated
AWSTemporaryCredentialsconformancecredential(from:)inLivenessCredentials.swiftextracts the session token with:When a caller declares their credential type in a target that uses
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor(an increasingly common default in new Xcode projects) and the type does not opt intoSendable/nonisolated, its conformance toAWSTemporaryCredentialsbecomes actor-isolated toMainActor. Theas?cast is performed from anonisolatedasync context, so it fails and returnsnil, silently dropping the session token.This was confirmed with a minimal reproduction: a
MainActor-isolated credential struct cast from a nonisolated function returnsnilfor the session token, even though the value carries it.Making
AWSCredentialsinherit fromSendableprevents the conformance from becoming actor-isolated, so the cast succeeds from any isolation context. This is also semantically correct — credentials are returned from anasyncprovider and cross concurrency boundaries, so they should beSendable.Changes
SigV4Signer.swift: build canonical query fromURLComponents.queryItems; usemaxSplits: 1when splitting query pairs.AuthAWSCredentialsProvider.swift:public protocol AWSCredentials: Sendable.Testing
SigV4URLSigningTestCasecovering query strings with=-containing values and session tokens.Credit
The
Sendablefix and root-cause analysis of the actor-isolated conformance were contributed by @nenseso via #4253.General Checklist
Given When Theninline code documentation and are named accordinglytestThing_condition_expectation()By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.