Skip to content

AWS: Isolate S3V4RestSignerClient signed request cache per principal … - #17914

Open
SHIVANSH-ux-ys wants to merge 4 commits into
apache:mainfrom
SHIVANSH-ux-ys:fix-17801-s3-signer-cache-principal-isolation
Open

AWS: Isolate S3V4RestSignerClient signed request cache per principal …#17914
SHIVANSH-ux-ys wants to merge 4 commits into
apache:mainfrom
SHIVANSH-ux-ys:fix-17801-s3-signer-cache-principal-isolation

Conversation

@SHIVANSH-ux-ys

Copy link
Copy Markdown

…(#17801)

@github-actions github-actions Bot added the AWS label Sep 1, 2026

@singhpk234 singhpk234 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the change @SHIVANSH-ux-ys, can you please add test for it

Comment on lines +414 to +415
.credential(signerClient.credential())
.token(signerClient.token().get())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should ideally either credential or token right not both because of case when credentials is exchanged for token ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing @singhpk234!

Makes sense - updated Key.from to prioritize token if set and fallback to credential. Also added a unit test (testSignedComponentCacheKeyIsolation) in TestS3V4RestSignerClient.java to verify cache key isolation across different credentials.

Pushed the updates!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with using either the token or the credential rather than both. My remaining concern is whether either value alone is sufficient to define the principal boundary for a process-wide cache.

The auth session is derived from more than these two values (AuthManager, OAuth server URI, scope/resource/audience, and potentially non-OAuth auth types). For example, two signer clients can use the same credential against different OAuth servers/resources, while non-OAuth principals may have both token and credential unset. Those clients would still produce the same cache key here.

Would it be simpler and safer to scope the signed-component cache to the S3V4RestSignerClient instance instead? That makes the isolation structural rather than trying to encode every authentication dimension into Key, and it also avoids retaining bearer tokens/client secrets in a process-wide cache key.

FWIW, #16524 has already been updated to make this cache per-instance, so it may be worth coordinating the two fixes.

S3V4RestSignerClient.Key key1 = S3V4RestSignerClient.Key.from(request, client1);
S3V4RestSignerClient.Key key2 = S3V4RestSignerClient.Key.from(request, client2);

assertThat(key1).isNotEqualTo(key2);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this a regression test for the actual cache behavior rather than testing Key.equals directly?

For #17801, I'd expect the test to populate a cacheable signed response through signer/client A, then make the same method/region/URI request through signer/client B and verify that B still calls its signer and receives B's signed component. That directly protects the security invariant and doesn't couple the test to the current cache-key implementation.

}

@Test
void testSignedComponentCacheKeyIsolation() throws Exception {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Iceberg's current convention for newly added tests avoids the test prefix, so this could be signedComponentCacheKeyIsolation() or, if converted to a behavior level regression test, something like doesNotReuseSignedComponentAcrossSignerClients().

@SHIVANSH-ux-ys

Copy link
Copy Markdown
Author

Thanks @yangshangqing95!

Refactored signedComponentCache to be a per-instance @Value.Lazy cache on S3V4RestSignerClient rather than a shared static cache. This structurally isolates signed components per client instance without storing credentials in the cache key.

Also updated the test name to doesNotReuseSignedComponentAcrossSignerClients() following Iceberg's naming convention and pushed the updates!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants