Skip to content

Build impersonated client without the shared cache - #652

Closed
ArnobKumarSaha wants to merge 1 commit into
masterfrom
arnob-impersonate-nocache
Closed

ArnobKumarSaha wants to merge 1 commit into
masterfrom
arnob-impersonate-nocache

Conversation

@ArnobKumarSaha

Copy link
Copy Markdown
Member

Problem

DelegatingClient.Impersonate(u) built the impersonated client from the base client's options, which carry the shared cache reader (optionsShallowCopy := d.options). That cache is populated with the base client's credentials. delegatingReader.shouldBypassCache only bypasses the cache for non-cachable GVKs, explicitly uncached GVKs, or unstructured objects (when cacheUnstructured is false). So a cachable, typed Get/List through an impersonated client was served from the base-credentialed cache, without the impersonation headers — silently bypassing the impersonated user's authorization.

Unstructured reads already went direct, so callers that only read unstructured objects were unaffected; typed reads were the gap.

Fix

  • Impersonate: set optionsShallowCopy.Cache = nil so the impersonated client is built without a cache and reads directly from the API (impersonation is already set on the copied rest config).
  • delegatingReader.shouldBypassCache: return true when CacheReader == nil, so a cache-free delegating client routes every read to the direct ClientReader instead of dereferencing a nil cache.

Impact

Impersonated clients now always read as the impersonated user. Non-impersonated clients are unchanged. Downstream (e.g. kubeops/ui-server render/dashboard/graph endpoints) can rely on Impersonate for authorization without restricting itself to unstructured reads.

DelegatingClient.Impersonate reused the base client's options, including the cache
reader. The cache is populated with the base client's credentials, so any cachable
typed Get/List through an impersonated client was served from that cache without the
impersonation headers, bypassing the impersonated user's authorization.

Drop the cache from the options passed to the impersonated client so it reads directly
from the API, and treat a nil CacheReader as always-bypass in the delegating reader.

Signed-off-by: Arnob Kumar Saha <arnob@appscode.com>
@ArnobKumarSaha

Copy link
Copy Markdown
Member Author

Superseding in the consumer (kubeops/ui-server) with a cache + per-object SubjectAccessReview approach, so Impersonate does not need to become cache-free for all consumers. Making impersonated clients unconditionally bypass the shared informer cache would regress consumers that do typed reads via Impersonate and rely on the cache. Closing in favor of authorizing cached reads per object at the call site.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant