Skip to content
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

Azure Key Vault- How to use AzureCliCredential first when using spring.cloud.azure.keyvault.secret.property-sources[0].endpoint #38995

Closed
lavercr opened this issue Feb 28, 2024 Discussed in #38982 · 35 comments · Fixed by #41580
Assignees
Labels
azure-spring All azure-spring related issues azure-spring-keyvault Spring keyvault related issues. Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that
Milestone

Comments

@lavercr
Copy link

lavercr commented Feb 28, 2024

Discussed in #38982

regarding this
https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-key-vault#use-spring-key-vault-propertysource

Issue with spring-cloud-azure-starter-keyvault 5.9.1

Originally posted by lavercr February 28, 2024
There is a really large delay when using spring.cloud.azure.keyvault.secret.property-sources[0].endpoint
The delay is more than 2 mins.

When I do this using AzureCliCredential directly my spring boot app loads and finds the key in seconds. How can I configure spring.cloud.azure.keyvault.secret.property-sources[0].endpoint to only use AzureCliCredential for authentication.

@github-actions github-actions bot added azure-spring All azure-spring related issues Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-triage Workflow: This issue needs the team to triage. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Feb 28, 2024
@lavercr
Copy link
Author

lavercr commented Feb 28, 2024

using :
springboot 3.2.2
sring-cloud-azure-dependencies 5.9.1
JavaSE-17 (OpenJDK 21.0.1)
az cli 2.57.0
running on MacOS 14.3

@lavercr
Copy link
Author

lavercr commented Feb 28, 2024

logs

 [2m2024-02-28T11:46:45.153-05:00 [0;39m  [32m INFO [0;39m  [35m34603 [0;39m  [2m--- [0;39m  [2m[           main] [0;39m  [2m [0;39m [36mm.p.s.SpringbootAzureKeyvaultApplication [0;39m  [2m: [0;39m Starting SpringbootAzureKeyvaultApplication using Java 21.0.1 with PID 34603 (/Users/lavercr/src/springboot-azure-keyvault/target/classes started by lavercr in /Users/lavercr/src/springboot-azure-keyvault)
 [2m2024-02-28T11:46:45.154-05:00 [0;39m  [32m INFO [0;39m  [35m34603 [0;39m  [2m--- [0;39m  [2m[           main] [0;39m  [2m [0;39m [36mm.p.s.SpringbootAzureKeyvaultApplication [0;39m  [2m: [0;39m No active profile set, falling back to 1 default profile: "default"
 [2m2024-02-28T11:46:45.642-05:00 [0;39m  [32m INFO [0;39m  [35m34603 [0;39m  [2m--- [0;39m  [2m[           main] [0;39m  [2m [0;39m [36mAbstractAzureServiceClientBuilderFactory [0;39m  [2m: [0;39m Will configure the default credential of type DefaultAzureCredential for class com.azure.identity.DefaultAzureCredentialBuilder.
 [2m2024-02-28T11:46:45.710-05:00 [0;39m  [32m INFO [0;39m  [35m34603 [0;39m  [2m--- [0;39m  [2m[           main] [0;39m  [2m [0;39m [36mm.p.s.SpringbootAzureKeyvaultApplication [0;39m  [2m: [0;39m Started **SpringbootAzureKeyvaultApplication in 141.667 seconds (process running for 142.235)**

@joshfree
Copy link
Member

Hi @lavercr thanks for reaching out to us via this github issue. @saragluna @backwind1233 could you please follow up?

/cc @vcolin7

@Netyyyy Netyyyy added the azure-spring-keyvault Spring keyvault related issues. label Mar 1, 2024
@Netyyyy
Copy link
Member

Netyyyy commented Mar 1, 2024

Hi @lavercr , thanks for reaching out, Could help provide more info about how to use AzureCliCredential directly?

@lavercr
Copy link
Author

lavercr commented Mar 1, 2024

If I create my own secretClient using AzureCliCredentialBuilder I can connect and pull passwords, but this way I have to write all the code. I would like to keep to the one liner that spring.cloud.azure.keyvault.secret.property-sources[0].endpoint gives us. This loads all the secrets and makes them available to the spring beans right away. If I do it myself it is more code, and the beans with secrets have to depend on this bean loading first. That gets messy quick.

@Configuration

public class AzureKeyVaultConfig {

    @Value("${spring.cloud.azure.keyvault.secret.uri}")
    private String keyVaultUri;

    @Bean
    SecretClient secretClient() {
        
        AzureCliCredential cliCredential = new AzureCliCredentialBuilder().build();

        // Azure SDK client builders accept the credential as a parameter.
        return new SecretClientBuilder()
           .vaultUrl(keyVaultUri)
           .credential(cliCredential)
           .buildClient();
         
    }
    
  
}

@Netyyyy
Copy link
Member

Netyyyy commented Mar 5, 2024

Hi @lavercr , we don't support use AzureCliCredential directly, but you can add this code to only use AzureCliCredential for authentication.

    @Bean(name = DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)
    TokenCredential tokenCredential( ) {
        return new AzureCliCredentialBuilder().build();
    }

@Netyyyy Netyyyy removed the needs-team-triage Workflow: This issue needs the team to triage. label Mar 5, 2024
@github-actions github-actions bot added the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Mar 5, 2024
@lavercr
Copy link
Author

lavercr commented Mar 6, 2024

Hi, I don't understand your solution. Does this need a specific bean name ?
I put a dummy name in and it still took a long time to respond.

@lavercr
Copy link
Author

lavercr commented Mar 6, 2024

can you provide a more complete example that uses

spring.cloud.azure.keyvault.secret.property-sources[0].endpoint

and

  @Bean(name = DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)
    TokenCredential tokenCredential( ) {
        return new AzureCliCredentialBuilder().build();
    }

@Netyyyy
Copy link
Member

Netyyyy commented Mar 11, 2024

Hi @lavercr , could you help provide your minimal project?

@lavercr
Copy link
Author

lavercr commented Mar 13, 2024

can you provide a more complete example that uses

spring.cloud.azure.keyvault.secret.property-sources[0].endpoint

and

  @Bean(name = DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)
    TokenCredential tokenCredential( ) {
        return new AzureCliCredentialBuilder().build();
    }

can you provide me an example with this working. where spring.cloud.azure.keyvault.secret.property-sources uses TokenCredential tokenCredential( ) {

@lavercr
Copy link
Author

lavercr commented Mar 13, 2024

create a springboot application with required azure dependencies

	<dependencies>
		<dependency>
			<groupId>com.azure.spring</groupId>
			<artifactId>spring-cloud-azure-starter-keyvault</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>com.azure.spring</groupId>
				<artifactId>spring-cloud-azure-dependencies</artifactId>
				<version>5.9.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

add this entry into your application.properties file that points to your working key vault
spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=[Your key vault url]

Add a secret to your vault called TestSecret

Setup your main class like this

package com.mbc.poc.springbootazurekeyvault;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootAzureKeyvaultApplication implements CommandLineRunner {

    @Value("${TestSecret}")
    private String testSecret;

    public static void main(String[] args) {
        SpringApplication.run(SpringbootAzureKeyvaultApplication.class, args);
    }

    @Override
    public void run(String... args) {

        System.out.println("TestSecret: " + testSecret);
    }
    
}

Determine how to use AzureCliCredentialBuilder in the authentication options first

@Netyyyy
Copy link
Member

Netyyyy commented Mar 14, 2024

create a springboot application with required azure dependencies

	<dependencies>
		<dependency>
			<groupId>com.azure.spring</groupId>
			<artifactId>spring-cloud-azure-starter-keyvault</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>com.azure.spring</groupId>
				<artifactId>spring-cloud-azure-dependencies</artifactId>
				<version>5.9.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

add this entry into your application.properties file that points to your working key vault spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=[Your key vault url]

Add a secret to your vault called TestSecret

Setup your main class like this

package com.mbc.poc.springbootazurekeyvault;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootAzureKeyvaultApplication implements CommandLineRunner {

    @Value("${TestSecret}")
    private String testSecret;

    public static void main(String[] args) {
        SpringApplication.run(SpringbootAzureKeyvaultApplication.class, args);
    }

    @Override
    public void run(String... args) {

        System.out.println("TestSecret: " + testSecret);
    }
    
}

Determine how to use AzureCliCredentialBuilder in the authentication options first

OK, I update your codes, hope this can help

package com.mbc.poc.springbootazurekeyvault;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import static com.azure.spring.cloud.autoconfigure.implementation.context.AzureContextUtils.DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME;

@SpringBootApplication
public class SpringbootAzureKeyvaultApplication implements CommandLineRunner {

    @Value("${TestSecret}")
    private String testSecret;

    public static void main(String[] args) {
        SpringApplication.run(SpringbootAzureKeyvaultApplication.class, args);
    }

    @Override
    public void run(String... args) {

        System.out.println("TestSecret: " + testSecret);
    }
    
    @Bean(name = DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)
    TokenCredential tokenCredential( ) {
        return new AzureCliCredentialBuilder().build();
    }
}

@justinholmes
Copy link

justinholmes commented Mar 14, 2024

This doesn't work for myself. We have a similar issue where development is done on Azure VMs and would like to override the Default to CLI so that property placeholders also work.

Setting the SecretClientBuilder bean to CLI works inside Application but then the KV EnvironmentPostProcessor just uses the Default.

@lavercr
Copy link
Author

lavercr commented Mar 14, 2024

I agree, this still seems to be using the default. I will see if I can find any logging category I can turn on.

Started SpringbootAzureKeyvaultApplication in 148.961 seconds (process running for 149.767)

@lavercr
Copy link
Author

lavercr commented Mar 14, 2024

Unable to find any logging I can turn on to give clarity to what is delaying startup. I am still assuming it is because it trys AzureCliCredential last to connect to azure key vault.

@lavercr
Copy link
Author

lavercr commented Mar 15, 2024

I believe there is a bug that needs fixing
spring.cloud.azure.keyvault.secret.property-sources does not adhere to

    @Bean(name = DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME)
    TokenCredential tokenCredential( ) {
        return new AzureCliCredentialBuilder().build();
    }

@justinholmes
Copy link

justinholmes commented Mar 15, 2024

I've got it working using a custom/changed version KeyVaultEnvironmentPostProcessor, setting it to use CLI, using a custom prefix for the properties and adding it to spring.factories in META-INF. It's a nasty hack but best available right now. Loading takes ~10s.

@lavercr
Copy link
Author

lavercr commented Mar 15, 2024

Can we confirm then that this is a bug. The fact that spring.cloud.azure.keyvault.secret.property-sources does not adhere to DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME

@lavercr
Copy link
Author

lavercr commented Mar 28, 2024

any update?

@Netyyyy
Copy link
Member

Netyyyy commented Apr 1, 2024

sorry for the late response and we will take a look about that

@saragluna
Copy link
Member

@lavercr, this is because the environment processor at an earlier stage, before the default azure credential bean's initialization. To change this behavior, we need to do some refactor, but users need to register the DAC bean in another way.

@lavercr
Copy link
Author

lavercr commented Apr 2, 2024

we need to do some refactor..
So there may be a fix coming our way ?

@lavercr
Copy link
Author

lavercr commented Apr 8, 2024

we need to be able to control the order.

@lavercr
Copy link
Author

lavercr commented Apr 9, 2024

@saragluna Can I have an update for this fix?

@Netyyyy
Copy link
Member

Netyyyy commented Apr 10, 2024

Sorry, this update requires code refactoring, which we need more time to discuss.

@lavercr
Copy link
Author

lavercr commented Apr 22, 2024

Do you have an update? This is going to be critical for our business unit in the next few months.

@lavercr
Copy link
Author

lavercr commented Apr 22, 2024

any possible way to get more frequent updates? or are you able to give me a patch to work around this issue ?

@Netyyyy
Copy link
Member

Netyyyy commented Apr 24, 2024

Not yet, but your contributions are welcome if you are interested

@lavercr
Copy link
Author

lavercr commented Apr 25, 2024

Okay. I get it. I will have to live with it or create a bandage.

@lavercr
Copy link
Author

lavercr commented Apr 26, 2024

@Netyyyy I have been asked for a date of fix. Please provide. This issue is holding up a security compliancy issue at our company. If there is another place or contact we can reach out to so we can get this fixed please let me know.
Thank you

@lavercr
Copy link
Author

lavercr commented Apr 26, 2024

For anyone not understanding what this is about. I am trying to get this solution to work for us.

https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-key-vault#use-spring-key-vault-propertysource

@saragluna
Copy link
Member

Hi @lavercr, sorry but we can't guarantee a date for the fix, but you could create a support tickect and it will help us prioritize this issue.

@lavercr
Copy link
Author

lavercr commented Apr 30, 2024

okay, do you have a link to create the support ticket, or do you mean go through some contract we have in our organization ?

@saragluna saragluna added this to the Backlog milestone Jul 29, 2024
@lavercr
Copy link
Author

lavercr commented Aug 19, 2024

any progress ??

@saragluna
Copy link
Member

saragluna commented Aug 21, 2024

Sorry for the late response, I just created #41580 to fix this issue. With this change, you might need to modify your application as the following to register a TokenCredential bean to the ConfigurableBootstrapContext for the KeyVaultEnvironmentPostProcessor to use that token credential.

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(PropertySourceApplication.class);
    application.addBootstrapRegistryInitializer(registry -> 
            registry.register(TokenCredential.class, context -> new AzureCliCredentialBuilder().build()));

    application.run(args);
}

This is a straightforward fix for this issue, but we may plan to provide finer grained configuration properties to configure the credential type for a component.

@saragluna saragluna modified the milestones: Backlog, 2024-09 Aug 21, 2024
@github-project-automation github-project-automation bot moved this from Todo to Done in Spring Cloud Azure Aug 28, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Nov 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
azure-spring All azure-spring related issues azure-spring-keyvault Spring keyvault related issues. Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that
Projects
Archived in project
6 participants