Skip to content

WorkloadIdentityCredential enhancement for AKS FIC limit #24442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

chlowell
Copy link
Member

This is the client part of a workaround for the per-application federated credentials limit. The feature is conceptually simple: instead of sending token requests to Entra ID, the client sends them to an endpoint specified by AKS, which also provides TLS configuration for that endpoint. The implementation is a little complex though, because AKS may provide configuration in a file whose content it may change.

chlowell and others added 4 commits April 14, 2025 16:18
As the endpoint injected into the pod is self-signed we need to pick the certificate up from a defined place in the pod.
@azure-sdk
Copy link
Collaborator

API change check

API changes are not detected in this pull request.

Copy link
Member

@enj enj left a comment

Choose a reason for hiding this comment

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

First pass.

Comment on lines +29 to +32
aksCAData = "AZURE_KUBERNETES_CA_DATA"
aksCAFile = "AZURE_KUBERNETES_CA_FILE"
aksSNIName = "AZURE_KUBERNETES_SNI_NAME"
aksTokenEndpoint = "AZURE_KUBERNETES_TOKEN_ENDPOINT"
Copy link
Member

Choose a reason for hiding this comment

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

nit: the SDK changes are generic and are meant to be usable on any kube running on Azure, i.e. AKS, CAPZ, etc.

Suggested change
aksCAData = "AZURE_KUBERNETES_CA_DATA"
aksCAFile = "AZURE_KUBERNETES_CA_FILE"
aksSNIName = "AZURE_KUBERNETES_SNI_NAME"
aksTokenEndpoint = "AZURE_KUBERNETES_TOKEN_ENDPOINT"
azureCAData = "AZURE_KUBERNETES_CA_DATA"
azureCAFile = "AZURE_KUBERNETES_CA_FILE"
azureSNIName = "AZURE_KUBERNETES_SNI_NAME"
azureTokenEndpoint = "AZURE_KUBERNETES_TOKEN_ENDPOINT"

Comment on lines +166 to +167
// c is configured for the AKS token endpoint
c *http.Client
Copy link
Member

Choose a reason for hiding this comment

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

Will the request seen by this client still contain the correct headers such as user agent, etc?

func newAKSTokenRequestPolicy() (*aksTokenRequestPolicy, error) {
host := os.Getenv(aksTokenEndpoint)
serverName := os.Getenv(aksSNIName)
if host == "" || serverName == "" {
Copy link
Member

Choose a reason for hiding this comment

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

Server name should not be required. Only host should be needed to use this code path.

f := os.Getenv(aksCAFile)
switch {
case len(b) == 0 && len(f) == 0:
return nil, fmt.Errorf("no value found for %s or %s", aksCAData, aksCAFile)
Copy link
Member

Choose a reason for hiding this comment

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

These are optional, system roots should be used if these are not given.

return nil, errors.New("couldn't parse " + aksCAData)
}
a.c = &http.Client{
Transport: &http.Transport{
Copy link
Member

Choose a reason for hiding this comment

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

Are there other transport level defaults that the SDK normally uses?

return nil, errors.New(aksCAFile + " specifies an empty file")
}
if !bytes.Equal(b, a.ca) {
a.ca = b
Copy link
Member

Choose a reason for hiding this comment

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

This should only be set after a.c is successfully set.

}

func newAKSTokenRequestPolicy() (*aksTokenRequestPolicy, error) {
host := os.Getenv(aksTokenEndpoint)
Copy link
Member

Choose a reason for hiding this comment

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

This is not a host, it is a full URL that can contain a path.

if err != nil {
return nil, errorinfo.NonRetriableError(err)
}
r.URL.Host = a.host
Copy link
Member

Choose a reason for hiding this comment

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

This is not correct.

}

func (a *aksTokenRequestPolicy) Do(req *policy.Request) (*http.Response, error) {
if r := req.Raw(); strings.HasSuffix(r.URL.Path, "/token") {
Copy link
Member

Choose a reason for hiding this comment

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

I do not believe this assumption is correct.

@github-project-automation github-project-automation bot moved this from Untriaged to In Progress in Azure Identity SDK Improvements May 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

4 participants