Azure / azure-sdk-for-rust

This repository is for the active development of the Azure SDK for Rust. For consumers of the SDK we recommend visiting Docs.rs and looking up the docs for any of libraries in the SDK.
MIT License
707 stars 245 forks source link

Azure Workload Identity - Expired token #1739

Open hjarraya opened 2 months ago

hjarraya commented 2 months ago

We are running Azure Identity v0.20.0 and getting this error for a longer-running process in AKS. We are using Workload Identity with our deployments.

 azure_identity::federated_credentials_flow: rsp_body == "{
 "error":"invalid_client",
 "error_description":"AADSTS700024: Client assertion is not within its valid time range.  
   Current time: 2024-08-05T10:07:04.2542067Z, assertion 
   valid from 2024-08-02T18:52:57.0000000Z, expiry time of assertion 2024-08-02T19:52:57.0000000Z.  Review the documentation at https://learn.microsoft.com/entra/identity-platform/certificate-credentials . Trace ID: XXXX-XXXX-XXXX-XXXX-XXXX Correlation ID: XXXX-XXXX-XXXX-XXXX-XXXX Timestamp: 2024-08-05 10:07:04Z",
   "error_codes":[700024],
   "timestamp":"2024-08-05 10:07:04Z", "trace_id":"XXXX-XXXX-XXXX-XXXX-XXXX",
   "correlation_id": "XXXX-XXXX-XXXX-XXXX-XXXX","error_uri": "https://login.microsoftonline.com/error?code=700024"
   }"

The workload identity token is not being refreshed as it is supposed to be.

erewok commented 2 months ago

I have the same problem. This is occurring on 0.20.0 and did not occur with the previous version of the library: 0.19.0.

eplightning commented 1 week ago

Looks like the federated token (e.g. Kubernetes SA projected token) is only loaded once since 0.20.0.

0.19.0 EnvironmentCredential loaded it every time so it just worked back then:

            let token = std::fs::read_to_string(file.clone())
                .with_context(ErrorKind::Credential, || {
                    format!("failed to read federated token from file {}", file.as_str())
                })?;
            let mut credential: WorkloadIdentityCredential = WorkloadIdentityCredential::new(
                self.http_client.clone(),
                tenant_id,
                client_id,
                token,
            );
            credential.set_options(options);

            return credential.get_token(scopes).await;
hjarraya commented 1 week ago

Indeed, it is loaded every time, so I cached it locally and requested it when it was about to expire.