diff --git a/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md b/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md index 9c2ca54e8377..5c8eccf5dca6 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md +++ b/sdk/keyvault/azure-security-keyvault-secrets/CHANGELOG.md @@ -1,17 +1,16 @@ # Release History -## 4.11.0-beta.1 (Unreleased) +## 4.11.0-beta.1 (2026-03-18) ### Features Added -### Breaking Changes +- Added `getPreviousVersion()` method to `KeyVaultSecret` and related response models to return the previous version of a certificate, if applicable. Only applies to certificates created after June 1, 2025. +- Added `outContentType` query parameter to `getSecret` and `getSecretVersion` operations to support PFX to PEM conversion for certificate-backed secrets. ### Bugs Fixed - Fixed an issue where certain `HttpResponseException.getResponse()` calls could cause a `NullPointerException`. ([#47801](https://github.com/Azure/azure-sdk-for-java/issues/47801)) -### Other Changes - ## 4.10.5 (2026-01-29) ### Other Changes diff --git a/sdk/keyvault/azure-security-keyvault-secrets/customizations/src/main/java/SecretsCustomizations.java b/sdk/keyvault/azure-security-keyvault-secrets/customizations/src/main/java/SecretsCustomizations.java index aafa25c66d76..c07f044ee70b 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/customizations/src/main/java/SecretsCustomizations.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/customizations/src/main/java/SecretsCustomizations.java @@ -34,6 +34,11 @@ private static void removeFiles(Editor editor) { editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java"); editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/SecretClient.java"); editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/SecretClientBuilder.java"); + // The generator now emits these names; they are replaced by our hand-crafted versions. + editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/implementation/KeyVaultClientImpl.java"); + editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/KeyVaultClientBuilder.java"); + editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/KeyVaultClient.java"); + editor.removeFile("src/main/java/com/azure/security/keyvault/secrets/KeyVaultAsyncClient.java"); } private static void customizeServiceVersion(LibraryCustomization customization) { @@ -49,7 +54,8 @@ private static void customizeServiceVersion(LibraryCustomization customization) .addImplementedType("ServiceVersion") .setJavadocComment("The versions of Azure Key Vault Secrets supported by this client library."); - for (String version : Arrays.asList("7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6")) { + for (String version : Arrays.asList("7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6", + "2025-06-01-preview", "2025-07-01")) { enumDeclaration.addEnumConstant("V" + version.replace('.', '_').replace('-', '_').toUpperCase()) .setJavadocComment("Service version {@code " + version + "}.") .addArgument(new StringLiteralExpr(version)); @@ -72,14 +78,21 @@ private static void customizeServiceVersion(LibraryCustomization customization) .addBlockTag("return", "The latest {@link SecretServiceVersion}.")) .setBody(StaticJavaParser.parseBlock("{ return V7_6; }")); - customization.getRawEditor() - .addFile("src/main/java/com/azure/security/keyvault/secrets/SecretServiceVersion.java", - compilationUnit.toString()); + Editor editor = customization.getRawEditor(); + String svFileName = "src/main/java/com/azure/security/keyvault/secrets/SecretServiceVersion.java"; + String svContent = compilationUnit.toString(); + if (editor.getFileContent(svFileName) != null) { + editor.replaceFile(svFileName, svContent); + } else { + editor.addFile(svFileName, svContent); + } String fileName = "src/main/java/com/azure/security/keyvault/secrets/implementation/SecretClientImpl.java"; String fileContent = customization.getRawEditor().getFileContent(fileName); - fileContent = fileContent.replace("KeyVaultServiceVersion", "SecretServiceVersion"); - customization.getRawEditor().replaceFile(fileName, fileContent); + if (fileContent != null) { + fileContent = fileContent.replace("KeyVaultServiceVersion", "SecretServiceVersion"); + customization.getRawEditor().replaceFile(fileName, fileContent); + } } private static void customizeModuleInfo(Editor editor) { diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java index ec81887f62c2..fd67c3238732 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretAsyncClient.java @@ -34,6 +34,7 @@ import com.azure.security.keyvault.secrets.implementation.models.SecretsModelsUtils; import com.azure.security.keyvault.secrets.models.DeletedSecret; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretContentType; import com.azure.security.keyvault.secrets.models.SecretProperties; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -440,6 +441,94 @@ public Mono> getSecretWithResponse(String name, String } } + /** + * Gets the latest version of the specified certificate-backed secret from the key vault, requesting on-demand + * format conversion. Use this method to retrieve a certificate stored as a secret and convert it from PFX to + * PEM format in a single service call. This operation requires the {@code secrets/get} permission. + * + *

This method is only supported for service version {@code 2025-07-01} and later. + * Currently only PFX ({@link SecretContentType#PFX}) to PEM ({@link SecretContentType#PEM}) + * conversion is supported.

+ * + *

Code sample

+ *

Gets a certificate-backed secret in PEM format.

+ * + *
+     * secretAsyncClient.getSecret("myCertificateSecret", SecretContentType.PEM)
+     *     .subscribe(pemSecret ->
+     *         System.out.printf("Retrieved secret in PEM format, value starts with: %s%n",
+     *             pemSecret.getValue().substring(0, 27)));
+     * 
+ * + * + * @param name The name of the certificate-backed secret. + * @param outContentType The desired output format. Use {@link SecretContentType#PEM} to request + * PFX-to-PEM conversion. + * @return A {@link Mono} containing the requested {@link KeyVaultSecret} with its value in the + * specified format. + * @throws ResourceNotFoundException When a secret with the given {@code name} doesn't exist in the vault. + * @throws IllegalArgumentException If {@code name} is either {@code null} or empty. + * @throws HttpResponseException If {@code outContentType} specifies an unsupported format. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getSecret(String name, SecretContentType outContentType) { + return getSecretWithResponse(name, "", outContentType).map(Response::getValue); + } + + /** + * Gets the specified version of a certificate-backed secret from the key vault, requesting on-demand + * format conversion. Use this method to retrieve a certificate stored as a secret and convert it from PFX to + * PEM format in a single service call. This operation requires the {@code secrets/get} permission. + * + *

This method is only supported for service version {@code 2025-07-01} and later. + * Currently only PFX ({@link SecretContentType#PFX}) to PEM ({@link SecretContentType#PEM}) + * conversion is supported.

+ * + *

Code sample

+ *

Gets a specific version of a certificate-backed secret in PEM format.

+ * + *
+     * String secretVersion = "6A385B124DEF4096AF1361A85B16C204";
+     * secretAsyncClient.getSecretWithResponse("myCertificateSecret", secretVersion, SecretContentType.PEM)
+     *     .subscribe(pemResponse ->
+     *         System.out.printf("Retrieved secret in PEM format with status: %d%n",
+     *             pemResponse.getStatusCode()));
+     * 
+ * + * + * @param name The name of the certificate-backed secret, cannot be null. + * @param version The version of the secret to retrieve. If this is an empty string or null, the latest + * version is retrieved. + * @param outContentType The desired output format. Use {@link SecretContentType#PEM} to request + * PFX-to-PEM conversion. + * @return A {@link Mono} containing a {@link Response} whose {@link Response#getValue() value} contains the + * requested {@link KeyVaultSecret} with its value in the specified format. + * @throws ResourceNotFoundException When a secret with the given {@code name} and {@code version} doesn't + * exist in the vault. + * @throws IllegalArgumentException If {@code name} is either {@code null} or empty. + * @throws HttpResponseException If {@code outContentType} specifies an unsupported format. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getSecretWithResponse(String name, String version, + SecretContentType outContentType) { + if (CoreUtils.isNullOrEmpty(name)) { + return monoError(LOGGER, new IllegalArgumentException("'name' cannot be null or empty.")); + } + + try { + RequestOptions requestOptions = new RequestOptions(); + if (outContentType != null) { + requestOptions.addQueryParam("outContentType", outContentType.toString()); + } + return implClient.getSecretWithResponseAsync(name, version != null ? version : "", requestOptions) + .onErrorMap(HttpResponseException.class, SecretAsyncClient::mapGetSecretException) + .map(response -> new SimpleResponse<>(response, + createKeyVaultSecret(response.getValue().toObject(SecretBundle.class)))); + } catch (RuntimeException e) { + return monoError(LOGGER, e); + } + } + // For some reason, the service does not return a 409 when a secret with the same name exists. Instead, it returns // a 403. static HttpResponseException mapGetSecretException(HttpResponseException e) { diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java index 80598d9a596c..49895071e136 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretClient.java @@ -32,6 +32,7 @@ import com.azure.security.keyvault.secrets.implementation.models.SecretUpdateParameters; import com.azure.security.keyvault.secrets.models.DeletedSecret; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretContentType; import com.azure.security.keyvault.secrets.models.SecretProperties; import java.time.Duration; @@ -401,6 +402,70 @@ public Response getSecretWithResponse(String name, String versio }, SecretAsyncClient::mapGetSecretException); } + /** + * Gets the latest version of the specified certificate-backed secret from the key vault, requesting + * on-demand format conversion. Use this method to retrieve a certificate stored as a secret and convert + * it from PFX to PEM format in a single service call. + * This operation requires the {@code secrets/get} permission. + * + *

Only available with service version {@link SecretServiceVersion#V2025_07_01} and later. + * Currently only PFX to PEM conversion is supported.

+ * + * @param name The name of the certificate-backed secret. + * @param outContentType The desired output format. Use {@link SecretContentType#PEM} to request + * PFX-to-PEM conversion. + * @return The requested {@link KeyVaultSecret} with its value in the specified format. + * @throws ResourceNotFoundException When a secret with the given {@code name} does not exist in the vault. + * @throws IllegalArgumentException If {@code name} is either {@code null} or empty. + * @throws HttpResponseException If {@code outContentType} specifies an unsupported format. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public KeyVaultSecret getSecret(String name, SecretContentType outContentType) { + return getSecretWithResponse(name, "", outContentType, Context.NONE).getValue(); + } + + /** + * Gets the specified version of a certificate-backed secret from the key vault, requesting on-demand + * format conversion. Use this method to retrieve a certificate stored as a secret and convert it from + * PFX to PEM format in a single service call. + * This operation requires the {@code secrets/get} permission. + * + *

Only available with service version {@link SecretServiceVersion#V2025_07_01} and later. + * Currently only PFX to PEM conversion is supported.

+ * + * @param name The name of the certificate-backed secret, cannot be null. + * @param version The version of the secret to retrieve. If this is an empty string or null, the latest + * version is retrieved. + * @param outContentType The desired output format. Use {@link SecretContentType#PEM} to request + * PFX-to-PEM conversion. + * @param context Additional context that is passed through the HTTP pipeline during the service call. + * @return A {@link Response} whose {@link Response#getValue() value} contains the requested + * {@link KeyVaultSecret} with its value in the specified format. + * @throws ResourceNotFoundException When a secret with the given {@code name} and {@code version} does + * not exist in the vault. + * @throws IllegalArgumentException If {@code name} is either {@code null} or empty. + * @throws HttpResponseException If {@code outContentType} specifies an unsupported format. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getSecretWithResponse(String name, String version, SecretContentType outContentType, + Context context) { + if (CoreUtils.isNullOrEmpty(name)) { + throw LOGGER.logExceptionAsError(new IllegalArgumentException("'name' cannot be null or empty.")); + } + + return callWithMappedException(() -> { + RequestOptions requestOptions = new RequestOptions().setContext(context); + if (outContentType != null) { + requestOptions.addQueryParam("outContentType", outContentType.toString()); + } + Response response + = implClient.getSecretWithResponse(name, version != null ? version : "", requestOptions); + + return new SimpleResponse<>(response, + createKeyVaultSecret(response.getValue().toObject(SecretBundle.class))); + }, SecretAsyncClient::mapGetSecretException); + } + /** * Updates the attributes associated with the secret. The value of the secret in the key vault cannot be changed. * Only attributes populated in {@code secretProperties} are changed. Attributes not specified in the request are diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretServiceVersion.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretServiceVersion.java index 941bbc4eaab2..f24df6f2a86b 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretServiceVersion.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/SecretServiceVersion.java @@ -37,7 +37,15 @@ public enum SecretServiceVersion implements ServiceVersion { /** * Service version {@code 7.6}. */ - V7_6("7.6"); + V7_6("7.6"), + /** + * Service version {@code 2025-06-01-preview}. + */ + V2025_06_01_PREVIEW("2025-06-01-preview"), + /** + * Service version {@code 2025-07-01}. + */ + V2025_07_01("2025-07-01"); private final String version; @@ -59,6 +67,6 @@ public String getVersion() { * @return The latest {@link SecretServiceVersion}. */ public static SecretServiceVersion getLatest() { - return V7_6; + return V2025_07_01; } } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/SecretClientImpl.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/SecretClientImpl.java index 1563bba24bb7..25c64666ee58 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/SecretClientImpl.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/SecretClientImpl.java @@ -61,7 +61,7 @@ public final class SecretClientImpl { /** * Gets. - * + * * @return the vaultBaseUrl value. */ public String getVaultBaseUrl() { @@ -75,7 +75,7 @@ public String getVaultBaseUrl() { /** * Gets Service version. - * + * * @return the serviceVersion value. */ public SecretServiceVersion getServiceVersion() { @@ -89,7 +89,7 @@ public SecretServiceVersion getServiceVersion() { /** * Gets The HTTP pipeline to send requests through. - * + * * @return the httpPipeline value. */ public HttpPipeline getHttpPipeline() { @@ -103,7 +103,7 @@ public HttpPipeline getHttpPipeline() { /** * Gets The serializer to serialize an object into a string. - * + * * @return the serializerAdapter value. */ public SerializerAdapter getSerializerAdapter() { @@ -112,7 +112,7 @@ public SerializerAdapter getSerializerAdapter() { /** * Initializes an instance of SecretClient client. - * + * * @param vaultBaseUrl * @param serviceVersion Service version. */ @@ -123,7 +123,7 @@ public SecretClientImpl(String vaultBaseUrl, SecretServiceVersion serviceVersion /** * Initializes an instance of SecretClient client. - * + * * @param httpPipeline The HTTP pipeline to send requests through. * @param vaultBaseUrl * @param serviceVersion Service version. @@ -134,7 +134,7 @@ public SecretClientImpl(HttpPipeline httpPipeline, String vaultBaseUrl, SecretSe /** * Initializes an instance of SecretClient client. - * + * * @param httpPipeline The HTTP pipeline to send requests through. * @param serializerAdapter The serializer to serialize an object into a string. * @param vaultBaseUrl @@ -331,7 +331,7 @@ Response getDeletedSecretSync(@HostParam("vaultBaseUrl") String vaul @UnexpectedResponseExceptionType(HttpResponseException.class) Mono> purgeDeletedSecret(@HostParam("vaultBaseUrl") String vaultBaseUrl, @QueryParam("api-version") String apiVersion, @PathParam("secret-name") String secretName, - @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + RequestOptions requestOptions, Context context); @Delete("/deletedsecrets/{secret-name}") @ExpectedResponses({ 204 }) @@ -341,7 +341,7 @@ Mono> purgeDeletedSecret(@HostParam("vaultBaseUrl") String vaultB @UnexpectedResponseExceptionType(HttpResponseException.class) Response purgeDeletedSecretSync(@HostParam("vaultBaseUrl") String vaultBaseUrl, @QueryParam("api-version") String apiVersion, @PathParam("secret-name") String secretName, - @HeaderParam("Accept") String accept, RequestOptions requestOptions, Context context); + RequestOptions requestOptions, Context context); @Post("/deletedsecrets/{secret-name}/recover") @ExpectedResponses({ 200 }) @@ -468,11 +468,11 @@ Response getDeletedSecretsNextSync(@PathParam(value = "nextLink", en /** * Sets a secret in a specified key vault. - * + * * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault * creates a new version of that secret. This operation requires the secrets/set permission. *

Request Body Schema

- * + * *
      * {@code
      * {
@@ -493,9 +493,9 @@ Response getDeletedSecretsNextSync(@PathParam(value = "nextLink", en
      * }
      * }
      * 
- * + * *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -519,7 +519,7 @@ Response getDeletedSecretsNextSync(@PathParam(value = "nextLink", en
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. The value you provide may be copied globally for the purpose of running * the service. The value provided should not include personally identifiable or sensitive information. * @param parameters The parameters for setting the secret. @@ -543,11 +543,11 @@ public Mono> setSecretWithResponseAsync(String secretName, /** * Sets a secret in a specified key vault. - * + * * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault * creates a new version of that secret. This operation requires the secrets/set permission. *

Request Body Schema

- * + * *
      * {@code
      * {
@@ -568,9 +568,9 @@ public Mono> setSecretWithResponseAsync(String secretName,
      * }
      * }
      * 
- * + * *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -594,7 +594,7 @@ public Mono> setSecretWithResponseAsync(String secretName,
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. The value you provide may be copied globally for the purpose of running * the service. The value provided should not include personally identifiable or sensitive information. * @param parameters The parameters for setting the secret. @@ -616,11 +616,11 @@ public Response setSecretWithResponse(String secretName, BinaryData /** * Deletes a secret from a specified key vault. - * + * * The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied to an individual * version of a secret. This operation requires the secrets/delete permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -647,7 +647,7 @@ public Response setSecretWithResponse(String secretName, BinaryData
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -666,11 +666,11 @@ public Mono> deleteSecretWithResponseAsync(String secretNam /** * Deletes a secret from a specified key vault. - * + * * The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied to an individual * version of a secret. This operation requires the secrets/delete permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -697,7 +697,7 @@ public Mono> deleteSecretWithResponseAsync(String secretNam
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -716,12 +716,12 @@ public Response deleteSecretWithResponse(String secretName, RequestO /** * Updates the attributes associated with a specified secret in a given key vault. - * + * * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified * in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the * secrets/set permission. *

Request Body Schema

- * + * *
      * {@code
      * {
@@ -741,9 +741,9 @@ public Response deleteSecretWithResponse(String secretName, RequestO
      * }
      * }
      * 
- * + * *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -767,7 +767,7 @@ public Response deleteSecretWithResponse(String secretName, RequestO
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param secretVersion The version of the secret. * @param parameters The parameters for update secret operation. @@ -791,12 +791,12 @@ public Mono> updateSecretWithResponseAsync(String secretNam /** * Updates the attributes associated with a specified secret in a given key vault. - * + * * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified * in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the * secrets/set permission. *

Request Body Schema

- * + * *
      * {@code
      * {
@@ -816,9 +816,9 @@ public Mono> updateSecretWithResponseAsync(String secretNam
      * }
      * }
      * 
- * + * *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -842,7 +842,7 @@ public Mono> updateSecretWithResponseAsync(String secretNam
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param secretVersion The version of the secret. * @param parameters The parameters for update secret operation. @@ -864,11 +864,22 @@ public Response updateSecretWithResponse(String secretName, String s /** * Get a specified secret from a given key vault. - * + * * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get * permission. + *

Query Parameters

+ * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
outContentTypeString(application/x-pkcs12/application/x-pem-file)NoThe + * media type (MIME type) of the certificate. If a supported format is specified, the certificate content is + * converted to the requested format. Currently, only PFX to PEM conversion is supported. If an unsupported format + * is specified, the request is rejected. If not specified, the certificate is returned in its original format + * without conversion. Available in service version 2025-07-01 and later.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -889,10 +900,11 @@ public Response updateSecretWithResponse(String secretName, String s
      *     }
      *     kid: String (Optional)
      *     managed: Boolean (Optional)
+     *     previousVersion: String (Optional)
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param secretVersion The version of the secret. This URI fragment is optional. If not specified, the latest * version of the secret is returned. @@ -902,7 +914,7 @@ public Response updateSecretWithResponse(String secretName, String s * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. * @return a specified secret from a given key vault. - * + * * The GET operation is applicable to any secret stored in Azure Key Vault along with {@link Response} on successful * completion of {@link Mono}. */ @@ -916,11 +928,22 @@ public Mono> getSecretWithResponseAsync(String secretName, /** * Get a specified secret from a given key vault. - * + * * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get * permission. + *

Query Parameters

+ * + * + * + * + *
Query Parameters
NameTypeRequiredDescription
outContentTypeString(application/x-pkcs12/application/x-pem-file)NoThe + * media type (MIME type) of the certificate. If a supported format is specified, the certificate content is + * converted to the requested format. Currently, only PFX to PEM conversion is supported. If an unsupported format + * is specified, the request is rejected. If not specified, the certificate is returned in its original format + * without conversion. Available in service version 2025-07-01 and later.
+ * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -941,10 +964,11 @@ public Mono> getSecretWithResponseAsync(String secretName,
      *     }
      *     kid: String (Optional)
      *     managed: Boolean (Optional)
+     *     previousVersion: String (Optional)
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param secretVersion The version of the secret. This URI fragment is optional. If not specified, the latest * version of the secret is returned. @@ -954,7 +978,7 @@ public Mono> getSecretWithResponseAsync(String secretName, * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. * @return a specified secret from a given key vault. - * + * * The GET operation is applicable to any secret stored in Azure Key Vault along with {@link Response}. */ @ServiceMethod(returns = ReturnType.SINGLE) @@ -967,7 +991,7 @@ public Response getSecretWithResponse(String secretName, String secr /** * List secrets in a specified key vault. - * + * * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its * attributes are provided in the response. Individual secret versions are not listed in the response. This * operation requires the secrets/list permission. @@ -980,7 +1004,7 @@ public Response getSecretWithResponse(String secretName, String secr * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1002,7 +1026,7 @@ public Response getSecretWithResponse(String secretName, String secr
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1022,7 +1046,7 @@ private Mono> getSecretsSinglePageAsync(RequestOptions /** * List secrets in a specified key vault. - * + * * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its * attributes are provided in the response. Individual secret versions are not listed in the response. This * operation requires the secrets/list permission. @@ -1035,7 +1059,7 @@ private Mono> getSecretsSinglePageAsync(RequestOptions * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1057,7 +1081,7 @@ private Mono> getSecretsSinglePageAsync(RequestOptions
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1076,7 +1100,7 @@ public PagedFlux getSecretsAsync(RequestOptions requestOptions) { /** * List secrets in a specified key vault. - * + * * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its * attributes are provided in the response. Individual secret versions are not listed in the response. This * operation requires the secrets/list permission. @@ -1089,7 +1113,7 @@ public PagedFlux getSecretsAsync(RequestOptions requestOptions) { * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1111,7 +1135,7 @@ public PagedFlux getSecretsAsync(RequestOptions requestOptions) {
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1130,7 +1154,7 @@ private PagedResponse getSecretsSinglePage(RequestOptions requestOpt /** * List secrets in a specified key vault. - * + * * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its * attributes are provided in the response. Individual secret versions are not listed in the response. This * operation requires the secrets/list permission. @@ -1143,7 +1167,7 @@ private PagedResponse getSecretsSinglePage(RequestOptions requestOpt * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1165,7 +1189,7 @@ private PagedResponse getSecretsSinglePage(RequestOptions requestOpt
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1184,7 +1208,7 @@ public PagedIterable getSecrets(RequestOptions requestOptions) { /** * List all versions of the specified secret. - * + * * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. * This operations requires the secrets/list permission. *

Query Parameters

@@ -1196,7 +1220,7 @@ public PagedIterable getSecrets(RequestOptions requestOptions) { * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1218,7 +1242,7 @@ public PagedIterable getSecrets(RequestOptions requestOptions) {
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1240,7 +1264,7 @@ private Mono> getSecretVersionsSinglePageAsync(String /** * List all versions of the specified secret. - * + * * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. * This operations requires the secrets/list permission. *

Query Parameters

@@ -1252,7 +1276,7 @@ private Mono> getSecretVersionsSinglePageAsync(String * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1274,7 +1298,7 @@ private Mono> getSecretVersionsSinglePageAsync(String
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1294,7 +1318,7 @@ public PagedFlux getSecretVersionsAsync(String secretName, RequestOp /** * List all versions of the specified secret. - * + * * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. * This operations requires the secrets/list permission. *

Query Parameters

@@ -1306,7 +1330,7 @@ public PagedFlux getSecretVersionsAsync(String secretName, RequestOp * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1328,7 +1352,7 @@ public PagedFlux getSecretVersionsAsync(String secretName, RequestOp
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1348,7 +1372,7 @@ private PagedResponse getSecretVersionsSinglePage(String secretName, /** * List all versions of the specified secret. - * + * * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. * This operations requires the secrets/list permission. *

Query Parameters

@@ -1360,7 +1384,7 @@ private PagedResponse getSecretVersionsSinglePage(String secretName, * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1382,7 +1406,7 @@ private PagedResponse getSecretVersionsSinglePage(String secretName,
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1402,7 +1426,7 @@ public PagedIterable getSecretVersions(String secretName, RequestOpt /** * Lists deleted secrets for the specified vault. - * + * * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. * This operation requires the secrets/list permission. *

Query Parameters

@@ -1414,7 +1438,7 @@ public PagedIterable getSecretVersions(String secretName, RequestOpt * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1439,7 +1463,7 @@ public PagedIterable getSecretVersions(String secretName, RequestOpt
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1459,7 +1483,7 @@ private Mono> getDeletedSecretsSinglePageAsync(Request /** * Lists deleted secrets for the specified vault. - * + * * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. * This operation requires the secrets/list permission. *

Query Parameters

@@ -1471,7 +1495,7 @@ private Mono> getDeletedSecretsSinglePageAsync(Request * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1496,7 +1520,7 @@ private Mono> getDeletedSecretsSinglePageAsync(Request
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1515,7 +1539,7 @@ public PagedFlux getDeletedSecretsAsync(RequestOptions requestOption /** * Lists deleted secrets for the specified vault. - * + * * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. * This operation requires the secrets/list permission. *

Query Parameters

@@ -1527,7 +1551,7 @@ public PagedFlux getDeletedSecretsAsync(RequestOptions requestOption * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1552,7 +1576,7 @@ public PagedFlux getDeletedSecretsAsync(RequestOptions requestOption
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1571,7 +1595,7 @@ private PagedResponse getDeletedSecretsSinglePage(RequestOptions req /** * Lists deleted secrets for the specified vault. - * + * * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. * This operation requires the secrets/list permission. *

Query Parameters

@@ -1583,7 +1607,7 @@ private PagedResponse getDeletedSecretsSinglePage(RequestOptions req * * You can add these to a request with {@link RequestOptions#addQueryParam} *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1608,7 +1632,7 @@ private PagedResponse getDeletedSecretsSinglePage(RequestOptions req
      * }
      * }
      * 
- * + * * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401. @@ -1627,11 +1651,11 @@ public PagedIterable getDeletedSecrets(RequestOptions requestOptions /** * Gets the specified deleted secret. - * + * * The Get Deleted Secret operation returns the specified deleted secret along with its attributes. This operation * requires the secrets/get permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1658,7 +1682,7 @@ public PagedIterable getDeletedSecrets(RequestOptions requestOptions
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1666,7 +1690,7 @@ public PagedIterable getDeletedSecrets(RequestOptions requestOptions * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. * @return the specified deleted secret. - * + * * The Get Deleted Secret operation returns the specified deleted secret along with its attributes along with * {@link Response} on successful completion of {@link Mono}. */ @@ -1680,11 +1704,11 @@ public Mono> getDeletedSecretWithResponseAsync(String secre /** * Gets the specified deleted secret. - * + * * The Get Deleted Secret operation returns the specified deleted secret along with its attributes. This operation * requires the secrets/get permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1711,7 +1735,7 @@ public Mono> getDeletedSecretWithResponseAsync(String secre
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1719,7 +1743,7 @@ public Mono> getDeletedSecretWithResponseAsync(String secre * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404. * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409. * @return the specified deleted secret. - * + * * The Get Deleted Secret operation returns the specified deleted secret along with its attributes along with * {@link Response}. */ @@ -1732,11 +1756,11 @@ public Response getDeletedSecretWithResponse(String secretName, Requ /** * Permanently deletes the specified secret. - * + * * The purge deleted secret operation removes the secret permanently, without the possibility of recovery. This * operation can only be enabled on a soft-delete enabled vault. This operation requires the secrets/purge * permission. - * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1747,18 +1771,17 @@ public Response getDeletedSecretWithResponse(String secretName, Requ */ @ServiceMethod(returns = ReturnType.SINGLE) public Mono> purgeDeletedSecretWithResponseAsync(String secretName, RequestOptions requestOptions) { - final String accept = "application/json"; return FluxUtil.withContext(context -> service.purgeDeletedSecret(this.getVaultBaseUrl(), - this.getServiceVersion().getVersion(), secretName, accept, requestOptions, context)); + this.getServiceVersion().getVersion(), secretName, requestOptions, context)); } /** * Permanently deletes the specified secret. - * + * * The purge deleted secret operation removes the secret permanently, without the possibility of recovery. This * operation can only be enabled on a soft-delete enabled vault. This operation requires the secrets/purge * permission. - * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1769,18 +1792,17 @@ public Mono> purgeDeletedSecretWithResponseAsync(String secretNam */ @ServiceMethod(returns = ReturnType.SINGLE) public Response purgeDeletedSecretWithResponse(String secretName, RequestOptions requestOptions) { - final String accept = "application/json"; return service.purgeDeletedSecretSync(this.getVaultBaseUrl(), this.getServiceVersion().getVersion(), secretName, - accept, requestOptions, Context.NONE); + requestOptions, Context.NONE); } /** * Recovers the deleted secret to the latest version. - * + * * Recovers the deleted secret in the specified vault. This operation can only be performed on a soft-delete enabled * vault. This operation requires the secrets/recover permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1804,7 +1826,7 @@ public Response purgeDeletedSecretWithResponse(String secretName, RequestO
      * }
      * }
      * 
- * + * * @param secretName The name of the deleted secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1824,11 +1846,11 @@ public Mono> recoverDeletedSecretWithResponseAsync(String s /** * Recovers the deleted secret to the latest version. - * + * * Recovers the deleted secret in the specified vault. This operation can only be performed on a soft-delete enabled * vault. This operation requires the secrets/recover permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1852,7 +1874,7 @@ public Mono> recoverDeletedSecretWithResponseAsync(String s
      * }
      * }
      * 
- * + * * @param secretName The name of the deleted secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1870,11 +1892,11 @@ public Response recoverDeletedSecretWithResponse(String secretName, /** * Backs up the specified secret. - * + * * Requests that a backup of the specified secret be downloaded to the client. All versions of the secret will be * downloaded. This operation requires the secrets/backup permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1882,7 +1904,7 @@ public Response recoverDeletedSecretWithResponse(String secretName,
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1901,11 +1923,11 @@ public Mono> backupSecretWithResponseAsync(String secretNam /** * Backs up the specified secret. - * + * * Requests that a backup of the specified secret be downloaded to the client. All versions of the secret will be * downloaded. This operation requires the secrets/backup permission. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1913,7 +1935,7 @@ public Mono> backupSecretWithResponseAsync(String secretNam
      * }
      * }
      * 
- * + * * @param secretName The name of the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1931,11 +1953,11 @@ public Response backupSecretWithResponse(String secretName, RequestO /** * Restores a backed up secret to a vault. - * + * * Restores a backed up secret, and all its versions, to a vault. This operation requires the secrets/restore * permission. *

Request Body Schema

- * + * *
      * {@code
      * {
@@ -1943,9 +1965,9 @@ public Response backupSecretWithResponse(String secretName, RequestO
      * }
      * }
      * 
- * + * *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -1969,7 +1991,7 @@ public Response backupSecretWithResponse(String secretName, RequestO
      * }
      * }
      * 
- * + * * @param parameters The parameters to restore the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -1990,11 +2012,11 @@ public Mono> restoreSecretWithResponseAsync(BinaryData para /** * Restores a backed up secret to a vault. - * + * * Restores a backed up secret, and all its versions, to a vault. This operation requires the secrets/restore * permission. *

Request Body Schema

- * + * *
      * {@code
      * {
@@ -2002,9 +2024,9 @@ public Mono> restoreSecretWithResponseAsync(BinaryData para
      * }
      * }
      * 
- * + * *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2028,7 +2050,7 @@ public Mono> restoreSecretWithResponseAsync(BinaryData para
      * }
      * }
      * 
- * + * * @param parameters The parameters to restore the secret. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -2047,10 +2069,10 @@ public Response restoreSecretWithResponse(BinaryData parameters, Req /** * List secrets in a specified key vault. - * + * * Get the next page of items. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2072,7 +2094,7 @@ public Response restoreSecretWithResponse(BinaryData parameters, Req
      * }
      * }
      * 
- * + * * @param nextLink The URL to get the next list of items. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -2094,10 +2116,10 @@ private Mono> getSecretsNextSinglePageAsync(String nex /** * List secrets in a specified key vault. - * + * * Get the next page of items. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2119,7 +2141,7 @@ private Mono> getSecretsNextSinglePageAsync(String nex
      * }
      * }
      * 
- * + * * @param nextLink The URL to get the next list of items. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -2139,10 +2161,10 @@ private PagedResponse getSecretsNextSinglePage(String nextLink, Requ /** * List all versions of the specified secret. - * + * * Get the next page of items. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2164,7 +2186,7 @@ private PagedResponse getSecretsNextSinglePage(String nextLink, Requ
      * }
      * }
      * 
- * + * * @param nextLink The URL to get the next list of items. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -2185,10 +2207,10 @@ private Mono> getSecretVersionsNextSinglePageAsync(Str /** * List all versions of the specified secret. - * + * * Get the next page of items. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2210,7 +2232,7 @@ private Mono> getSecretVersionsNextSinglePageAsync(Str
      * }
      * }
      * 
- * + * * @param nextLink The URL to get the next list of items. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -2230,10 +2252,10 @@ private PagedResponse getSecretVersionsNextSinglePage(String nextLin /** * Lists deleted secrets for the specified vault. - * + * * Get the next page of items. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2258,7 +2280,7 @@ private PagedResponse getSecretVersionsNextSinglePage(String nextLin
      * }
      * }
      * 
- * + * * @param nextLink The URL to get the next list of items. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. @@ -2279,10 +2301,10 @@ private Mono> getDeletedSecretsNextSinglePageAsync(Str /** * Lists deleted secrets for the specified vault. - * + * * Get the next page of items. *

Response Body Schema

- * + * *
      * {@code
      * {
@@ -2307,7 +2329,7 @@ private Mono> getDeletedSecretsNextSinglePageAsync(Str
      * }
      * }
      * 
- * + * * @param nextLink The URL to get the next list of items. * @param requestOptions The options to configure the HTTP request before HTTP client sends it. * @throws HttpResponseException thrown if the request is rejected by server. diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/ContentType.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/ContentType.java new file mode 100644 index 000000000000..dff791b1a3f5 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/ContentType.java @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) TypeSpec Code Generator. + +package com.azure.security.keyvault.secrets.implementation.models; + +import com.azure.core.annotation.Generated; +import com.azure.core.util.ExpandableStringEnum; +import java.util.Collection; + +/** + * The media type (MIME type). + */ +public final class ContentType extends ExpandableStringEnum { + /** + * The PKCS#12 file format. + */ + @Generated + public static final ContentType PFX = fromString("application/x-pkcs12"); + + /** + * The PEM file format. + */ + @Generated + public static final ContentType PEM = fromString("application/x-pem-file"); + + /** + * Creates a new instance of ContentType value. + * + * @deprecated Use the {@link #fromString(String)} factory method. + */ + @Generated + @Deprecated + public ContentType() { + } + + /** + * Creates or finds a ContentType from its string representation. + * + * @param name a name to look for. + * @return the corresponding ContentType. + */ + @Generated + public static ContentType fromString(String name) { + return fromString(name, ContentType.class); + } + + /** + * Gets known ContentType values. + * + * @return known ContentType values. + */ + @Generated + public static Collection values() { + return values(ContentType.class); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/DeletedSecretBundle.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/DeletedSecretBundle.java index 4731e6b9d279..10f6cfbb145e 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/DeletedSecretBundle.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/DeletedSecretBundle.java @@ -66,6 +66,13 @@ public final class DeletedSecretBundle implements JsonSerializable writer.writeString(element)); + jsonWriter.writeStringField("previousVersion", this.previousVersion); jsonWriter.writeStringField("recoveryId", this.recoveryId); return jsonWriter.writeEndObject(); } @@ -246,6 +265,8 @@ public static DeletedSecretBundle fromJson(JsonReader jsonReader) throws IOExcep deserializedDeletedSecretBundle.kid = reader.getString(); } else if ("managed".equals(fieldName)) { deserializedDeletedSecretBundle.managed = reader.getNullable(JsonReader::getBoolean); + } else if ("previousVersion".equals(fieldName)) { + deserializedDeletedSecretBundle.previousVersion = reader.getString(); } else if ("recoveryId".equals(fieldName)) { deserializedDeletedSecretBundle.recoveryId = reader.getString(); } else if ("scheduledPurgeDate".equals(fieldName)) { diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/SecretBundle.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/SecretBundle.java index c86e8e1403f6..29e9b43f7975 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/SecretBundle.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/implementation/models/SecretBundle.java @@ -62,6 +62,13 @@ public final class SecretBundle implements JsonSerializable { @Generated private Boolean managed; + /* + * The version of the previous certificate, if applicable. Applies only to certificates created after June 1, 2025. + * Certificates created before this date are not retroactively updated. + */ + @Generated + private String previousVersion; + /** * Creates an instance of SecretBundle class. */ @@ -141,6 +148,17 @@ public Boolean isManaged() { return this.managed; } + /** + * Get the previousVersion property: The version of the previous certificate, if applicable. Applies only to + * certificates created after June 1, 2025. Certificates created before this date are not retroactively updated. + * + * @return the previousVersion value. + */ + @Generated + public String getPreviousVersion() { + return this.previousVersion; + } + /** * {@inheritDoc} */ @@ -153,6 +171,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { jsonWriter.writeStringField("contentType", this.contentType); jsonWriter.writeJsonField("attributes", this.attributes); jsonWriter.writeMapField("tags", this.tags, (writer, element) -> writer.writeString(element)); + jsonWriter.writeStringField("previousVersion", this.previousVersion); return jsonWriter.writeEndObject(); } @@ -187,6 +206,8 @@ public static SecretBundle fromJson(JsonReader jsonReader) throws IOException { deserializedSecretBundle.kid = reader.getString(); } else if ("managed".equals(fieldName)) { deserializedSecretBundle.managed = reader.getNullable(JsonReader::getBoolean); + } else if ("previousVersion".equals(fieldName)) { + deserializedSecretBundle.previousVersion = reader.getString(); } else { reader.skipChildren(); } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/models/SecretContentType.java b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/models/SecretContentType.java new file mode 100644 index 000000000000..e9c9beb3df1a --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/main/java/com/azure/security/keyvault/secrets/models/SecretContentType.java @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.security.keyvault.secrets.models; + +import com.azure.core.util.ExpandableStringEnum; + +import java.util.Collection; + +/** + * The media type (MIME type) of a certificate-backed secret. + * + *

Used with {@link com.azure.security.keyvault.secrets.SecretClient#getSecret(String, SecretContentType)} to + * request on-demand format conversion when retrieving a certificate-backed secret from Azure Key Vault.

+ * + *

Currently only PFX ({@code application/x-pkcs12}) to PEM ({@code application/x-pem-file}) conversion is + * supported. If an unsupported conversion is requested, the service will return an error.

+ * + *

This feature is available in service version {@code 2025-07-01} and later.

+ */ +public final class SecretContentType extends ExpandableStringEnum { + /** + * The PKCS#12 (PFX) file format ({@code application/x-pkcs12}). + */ + public static final SecretContentType PFX = fromString("application/x-pkcs12"); + + /** + * The PEM file format ({@code application/x-pem-file}). + */ + public static final SecretContentType PEM = fromString("application/x-pem-file"); + + /** + * Creates a new instance of {@link SecretContentType} with no string value. + * + * @deprecated Use {@link #fromString(String)} to create or get an instance of {@link SecretContentType} instead. + */ + @Deprecated + public SecretContentType() { + } + + /** + * Creates or finds a {@link SecretContentType} from its string representation. + * + * @param name The string value to look up. + * @return The corresponding {@link SecretContentType}. + */ + public static SecretContentType fromString(String name) { + return fromString(name, SecretContentType.class); + } + + /** + * Gets the known {@link SecretContentType} values. + * + * @return The known {@link SecretContentType} values. + */ + public static Collection values() { + return values(SecretContentType.class); + } +} diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretAsyncClientJavaDocCodeSnippets.java b/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretAsyncClientJavaDocCodeSnippets.java index 8cbe0001e494..279547405887 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretAsyncClientJavaDocCodeSnippets.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretAsyncClientJavaDocCodeSnippets.java @@ -8,6 +8,7 @@ import com.azure.core.http.policy.HttpLogOptions; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretContentType; import com.azure.security.keyvault.secrets.models.SecretProperties; import reactor.util.context.Context; @@ -353,4 +354,28 @@ public void listSecretVersionsCodeSnippets() { secret.getName(), secret.getValue())); // END: com.azure.keyvault.secrets.SecretClient.listSecretVersions#string } + + /** + * Method to insert code snippets for + * {@link SecretAsyncClient#getSecret(String, SecretContentType)} and + * {@link SecretAsyncClient#getSecretWithResponse(String, String, SecretContentType)}. + */ + public void getSecretWithOutContentTypeCodeSnippets() { + SecretAsyncClient secretAsyncClient = getAsyncSecretClient(); + + // BEGIN: com.azure.keyvault.secrets.SecretAsyncClient.getSecret#string-SecretContentType + secretAsyncClient.getSecret("myCertificateSecret", SecretContentType.PEM) + .subscribe(pemSecret -> + System.out.printf("Retrieved secret in PEM format, value starts with: %s%n", + pemSecret.getValue().substring(0, 27))); + // END: com.azure.keyvault.secrets.SecretAsyncClient.getSecret#string-SecretContentType + + // BEGIN: com.azure.keyvault.secrets.SecretAsyncClient.getSecretWithResponse#string-string-SecretContentType + String secretVersion = "6A385B124DEF4096AF1361A85B16C204"; + secretAsyncClient.getSecretWithResponse("myCertificateSecret", secretVersion, SecretContentType.PEM) + .subscribe(pemResponse -> + System.out.printf("Retrieved secret in PEM format with status: %d%n", + pemResponse.getStatusCode())); + // END: com.azure.keyvault.secrets.SecretAsyncClient.getSecretWithResponse#string-string-SecretContentType + } } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretClientJavaDocCodeSnippets.java b/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretClientJavaDocCodeSnippets.java index 7a0625a9b159..32f8d61407db 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretClientJavaDocCodeSnippets.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/samples/java/com/azure/security/keyvault/secrets/SecretClientJavaDocCodeSnippets.java @@ -10,6 +10,7 @@ import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.security.keyvault.secrets.models.DeletedSecret; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretContentType; import com.azure.security.keyvault.secrets.models.SecretProperties; import java.time.OffsetDateTime; @@ -380,4 +381,27 @@ public void listSecretVersionsCodeSnippets() { }); // END: com.azure.security.keyvault.SecretClient.listSecretVersions#string-Context-iterableByPage } + + /** + * Method to insert code snippets for + * {@link SecretClient#getSecret(String, SecretContentType)} and + * {@link SecretClient#getSecretWithResponse(String, String, SecretContentType, Context)}. + */ + public void getSecretWithOutContentTypeCodeSnippets() { + SecretClient secretClient = getSecretClient(); + + // BEGIN: com.azure.security.keyvault.SecretClient.getSecret#string-SecretContentType + KeyVaultSecret pemSecret = secretClient.getSecret("myCertificateSecret", SecretContentType.PEM); + System.out.printf("Retrieved secret in PEM format, value starts with: %s%n", + pemSecret.getValue().substring(0, 27)); + // END: com.azure.security.keyvault.SecretClient.getSecret#string-SecretContentType + + // BEGIN: com.azure.security.keyvault.SecretClient.getSecretWithResponse#string-string-SecretContentType-Context + String secretVersion = "6A385B124DEF4096AF1361A85B16C204"; + Response pemResponse = secretClient.getSecretWithResponse( + "myCertificateSecret", secretVersion, SecretContentType.PEM, Context.NONE); + System.out.printf("Retrieved secret in PEM format with status: %d%n", + pemResponse.getStatusCode()); + // END: com.azure.security.keyvault.SecretClient.getSecretWithResponse#string-string-SecretContentType-Context + } } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretAsyncClientTest.java b/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretAsyncClientTest.java index 54ded6d8a1a2..eb8ad98f341a 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretAsyncClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretAsyncClientTest.java @@ -7,6 +7,7 @@ import com.azure.core.exception.ResourceModifiedException; import com.azure.core.exception.ResourceNotFoundException; import com.azure.core.http.HttpClient; +import com.azure.core.test.annotation.DoNotRecord; import com.azure.core.test.http.AssertingHttpClientBuilder; import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.logging.LogLevel; @@ -15,8 +16,10 @@ import com.azure.security.keyvault.secrets.implementation.KeyVaultCredentialPolicy; import com.azure.security.keyvault.secrets.models.DeletedSecret; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretContentType; import com.azure.security.keyvault.secrets.models.SecretProperties; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import reactor.core.publisher.Mono; @@ -550,6 +553,75 @@ public void listSecrets(HttpClient httpClient, SecretServiceVersion serviceVersi }); } + /** + * Tests retrieving a certificate-backed secret with PFX-to-PEM format conversion using the outContentType + * parameter. Only available in service version {@link SecretServiceVersion#V2025_07_01} and later. + * + *

This test requires a live Azure Key Vault. No recording is available yet.

+ */ + @ParameterizedTest(name = DISPLAY_NAME_WITH_ARGUMENTS) + @MethodSource("getTestParameters") + @DoNotRecord(skipInPlayback = true) + public void getSecretWithOutContentType(HttpClient httpClient, SecretServiceVersion serviceVersion) { + Assumptions.assumeTrue(serviceVersion.ordinal() >= SecretServiceVersion.V2025_07_01.ordinal(), + "getSecretWithOutContentType requires SecretServiceVersion.V2025_07_01 or later."); + Assumptions.assumeTrue(interceptorManager.isLiveMode(), + "getSecretWithOutContentType requires a live Azure Key Vault service (no recording available)."); + + createSecretAsyncClient(httpClient, serviceVersion); + + String secretName = testResourceNamer.randomName("testSecretOutContentType", 30); + KeyVaultSecret pfxSecret = new KeyVaultSecret(secretName, "placeholder-pfx-value") + .setProperties(new SecretProperties().setContentType("application/x-pkcs12")); + + StepVerifier + .create(secretAsyncClient.setSecret(pfxSecret) + .then(secretAsyncClient.getSecret(secretName, SecretContentType.PEM))) + .assertNext(pemSecret -> { + assertNotNull(pemSecret); + assertEquals(secretName, pemSecret.getName()); + assertEquals("application/x-pem-file", pemSecret.getProperties().getContentType()); + assertTrue(pemSecret.getValue() != null && !pemSecret.getValue().isEmpty()); + }) + .verifyComplete(); + } + + /** + * Tests retrieving a certificate-backed secret with PFX-to-PEM format conversion using + * {@link SecretAsyncClient#getSecretWithResponse(String, String, SecretContentType)}. + * Only available in service version {@link SecretServiceVersion#V2025_07_01} and later. + * + *

This test requires a live Azure Key Vault. No recording is available yet.

+ */ + @ParameterizedTest(name = DISPLAY_NAME_WITH_ARGUMENTS) + @MethodSource("getTestParameters") + @DoNotRecord(skipInPlayback = true) + public void getSecretWithResponseOutContentType(HttpClient httpClient, SecretServiceVersion serviceVersion) { + Assumptions.assumeTrue(serviceVersion.ordinal() >= SecretServiceVersion.V2025_07_01.ordinal(), + "getSecretWithResponseOutContentType requires SecretServiceVersion.V2025_07_01 or later."); + Assumptions.assumeTrue(interceptorManager.isLiveMode(), + "getSecretWithResponseOutContentType requires a live Azure Key Vault service (no recording available)."); + + createSecretAsyncClient(httpClient, serviceVersion); + + String secretName = testResourceNamer.randomName("testSecretOutContentTypeResp", 30); + KeyVaultSecret pfxSecret = new KeyVaultSecret(secretName, "placeholder-pfx-value") + .setProperties(new SecretProperties().setContentType("application/x-pkcs12")); + + StepVerifier + .create(secretAsyncClient.setSecret(pfxSecret) + .then(secretAsyncClient.getSecretWithResponse(secretName, null, SecretContentType.PEM))) + .assertNext(response -> { + assertNotNull(response); + assertEquals(200, response.getStatusCode()); + KeyVaultSecret pemSecret = response.getValue(); + assertNotNull(pemSecret); + assertEquals(secretName, pemSecret.getName()); + assertEquals("application/x-pem-file", pemSecret.getProperties().getContentType()); + }) + .verifyComplete(); + } + private void pollOnSecretPurge(String secretName) { int pendingPollCount = 0; diff --git a/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretClientTest.java b/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretClientTest.java index 9629109b55f7..12c7e31350a8 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretClientTest.java +++ b/sdk/keyvault/azure-security-keyvault-secrets/src/test/java/com/azure/security/keyvault/secrets/SecretClientTest.java @@ -7,6 +7,7 @@ import com.azure.core.exception.ResourceModifiedException; import com.azure.core.exception.ResourceNotFoundException; import com.azure.core.http.HttpClient; +import com.azure.core.test.annotation.DoNotRecord; import com.azure.core.test.http.AssertingHttpClientBuilder; import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.logging.LogLevel; @@ -14,8 +15,10 @@ import com.azure.security.keyvault.secrets.implementation.KeyVaultCredentialPolicy; import com.azure.security.keyvault.secrets.models.DeletedSecret; import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretContentType; import com.azure.security.keyvault.secrets.models.SecretProperties; import io.netty.handler.codec.http.HttpResponseStatus; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -482,6 +485,78 @@ public void listSecretVersions(HttpClient httpClient, SecretServiceVersion servi } + /** + * Tests retrieving a certificate-backed secret with PFX-to-PEM format conversion using the outContentType + * parameter. Only available in service version {@link SecretServiceVersion#V2025_07_01} and later. + * + *

This test requires a live Azure Key Vault. No recording is available yet.

+ */ + @ParameterizedTest(name = DISPLAY_NAME_WITH_ARGUMENTS) + @MethodSource("getTestParameters") + @DoNotRecord(skipInPlayback = true) + public void getSecretWithOutContentType(HttpClient httpClient, SecretServiceVersion serviceVersion) { + // This feature requires service version 2025-07-01 or later. + Assumptions.assumeTrue(serviceVersion.ordinal() >= SecretServiceVersion.V2025_07_01.ordinal(), + "getSecretWithOutContentType requires SecretServiceVersion.V2025_07_01 or later."); + // This test requires a live service because no recording exists yet. + Assumptions.assumeTrue(interceptorManager.isLiveMode(), + "getSecretWithOutContentType requires a live Azure Key Vault service (no recording available)."); + + createClient(httpClient, serviceVersion); + + String secretName = testResourceNamer.randomName("testSecretOutContentType", 30); + + // Set a certificate-backed secret with PFX content type. + // In a real scenario this value would be a valid base64-encoded PFX. + // The Azure Key Vault service will attempt to convert the PFX to PEM when outContentType is requested. + KeyVaultSecret pfxSecret = new KeyVaultSecret(secretName, "placeholder-pfx-value") + .setProperties(new SecretProperties().setContentType("application/x-pkcs12")); + secretClient.setSecret(pfxSecret); + + // Retrieve the certificate secret requesting PEM format conversion. + KeyVaultSecret pemSecret = secretClient.getSecret(secretName, SecretContentType.PEM); + + assertNotNull(pemSecret); + assertEquals(secretName, pemSecret.getName()); + assertEquals("application/x-pem-file", pemSecret.getProperties().getContentType()); + assertTrue(pemSecret.getValue() != null && !pemSecret.getValue().isEmpty()); + } + + /** + * Tests retrieving a certificate-backed secret with PFX-to-PEM format conversion using + * {@link SecretClient#getSecretWithResponse(String, String, SecretContentType, + * com.azure.core.util.Context)}. + * Only available in service version {@link SecretServiceVersion#V2025_07_01} and later. + * + *

This test requires a live Azure Key Vault. No recording is available yet.

+ */ + @ParameterizedTest(name = DISPLAY_NAME_WITH_ARGUMENTS) + @MethodSource("getTestParameters") + @DoNotRecord(skipInPlayback = true) + public void getSecretWithResponseOutContentType(HttpClient httpClient, SecretServiceVersion serviceVersion) { + Assumptions.assumeTrue(serviceVersion.ordinal() >= SecretServiceVersion.V2025_07_01.ordinal(), + "getSecretWithResponseOutContentType requires SecretServiceVersion.V2025_07_01 or later."); + Assumptions.assumeTrue(interceptorManager.isLiveMode(), + "getSecretWithResponseOutContentType requires a live Azure Key Vault service (no recording available)."); + + createClient(httpClient, serviceVersion); + + String secretName = testResourceNamer.randomName("testSecretOutContentTypeResp", 30); + KeyVaultSecret pfxSecret = new KeyVaultSecret(secretName, "placeholder-pfx-value") + .setProperties(new SecretProperties().setContentType("application/x-pkcs12")); + secretClient.setSecret(pfxSecret); + + com.azure.core.http.rest.Response response = secretClient.getSecretWithResponse(secretName, + null, SecretContentType.PEM, com.azure.core.util.Context.NONE); + + assertNotNull(response); + assertEquals(200, response.getStatusCode()); + KeyVaultSecret pemSecret = response.getValue(); + assertNotNull(pemSecret); + assertEquals(secretName, pemSecret.getName()); + assertEquals("application/x-pem-file", pemSecret.getProperties().getContentType()); + } + private void pollOnSecretPurge(String secretName) { int pendingPollCount = 0; diff --git a/sdk/keyvault/azure-security-keyvault-secrets/tsp-location.yaml b/sdk/keyvault/azure-security-keyvault-secrets/tsp-location.yaml index a7133e413678..d3a380d2f7f0 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/tsp-location.yaml +++ b/sdk/keyvault/azure-security-keyvault-secrets/tsp-location.yaml @@ -1,6 +1,5 @@ -directory: specification/keyvault/Security.KeyVault.Secrets -commit: 396ab529763b7195ab089f58e2eefb011e1b290d +directory: specification/keyvault/data-plane/Secrets +commit: b49f87d0b8c5b9d1d4fa78e56ddfe5e566b140d2 repo: Azure/azure-rest-api-specs -cleanup: true additionalDirectories: -- specification/keyvault/Security.KeyVault.Common/ +- specification/keyvault/data-plane/Secrets/common \ No newline at end of file