Skip to content

Commit

Permalink
if secret version not found via explicit version label, failover to '…
Browse files Browse the repository at this point in the history
…latest' alias
  • Loading branch information
eschultink committed Dec 10, 2024
1 parent 29e3c03 commit ae887b8
Showing 1 changed file with 30 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public class SecretManagerConfigService implements WritableConfigService, LockSe
private static final String VERSION_LABEL = "latest-version";
private static final int NUMBER_OF_VERSIONS_TO_RETRIEVE = 20;

/**
* GCP-level alias for the latest version of the secret
*
* NOTE: accessing secrets via aliases, including 'latest', is NOT strongly consistent
* see: https://cloud.google.com/secret-manager/docs/access-secret-version#resource_consistency
*/
public static final String LATEST_VERSION_ALIAS = "latest";

@Inject
EnvVarsConfigService envVarsConfigService;
@Inject
Expand Down Expand Up @@ -108,7 +116,7 @@ public Optional<String> getConfigPropertyAsOptional(ConfigProperty property) {

try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {

String versionName = "latest";
String versionName = LATEST_VERSION_ALIAS;
try {
Secret secret = client.getSecret(secretName);

Expand All @@ -130,15 +138,26 @@ public Optional<String> getConfigPropertyAsOptional(ConfigProperty property) {
SecretVersionName secretVersionName =
SecretVersionName.of(projectId, secretName.getSecret(), versionName);

// Access the secret version.
AccessSecretVersionResponse response = client.accessSecretVersion(secretVersionName);
return accessSecretVersion(client, secretVersionName);

return Optional.of(response.getPayload().getData().toStringUtf8());
} catch (com.google.api.gax.rpc.NotFoundException e) {
if (accessViaExplicitVersion) {
// in this case, manual rotation of the secret without relying on our code may have occurred; a new version was written, but the value of the label referencing the latest version was not updated
// log that we're here, then try to failover to getting the latest version using the GCP Secret Manager 'latest' reference.
log.log(Level.WARNING, "Could not find secret " + paramName + " in Secret Manager using explicit version; check value of label '" + VERSION_LABEL + "' on the secret itself vs what versions of that secret exist.");

try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
// try to get the latest version
SecretVersionName secretVersionName =
SecretVersionName.of(projectId, secretName.getSecret(), LATEST_VERSION_ALIAS);
return accessSecretVersion(client, secretVersionName);
} catch (com.google.api.gax.rpc.NotFoundException notFoundException) {
log.log(Level.WARNING, "Failover to getting 'latest' version of secret " + paramName + " also failed; check if secret exists and has versions.", notFoundException);
} catch (Exception ignored) {
log.log(Level.WARNING, "Failover to getting 'latest' version of secret " + paramName + " failed due to something other than 'NotFound' case.", ignored);
}
}

if (envVarsConfigService.isDevelopment()) {
log.log(Level.INFO, "Could not find secret " + paramName + " in Secret Manager", e);
}
Expand All @@ -152,6 +171,13 @@ public Optional<String> getConfigPropertyAsOptional(ConfigProperty property) {
}
}

Optional<String> accessSecretVersion(SecretManagerServiceClient client, SecretVersionName secretVersionName) {
// Access the secret version.
AccessSecretVersionResponse response = client.accessSecretVersion(secretVersionName);

return Optional.of(response.getPayload().getData().toStringUtf8());
}

@Override
public boolean acquire(@NonNull String lockId, @NonNull java.time.Duration expires) {
Preconditions.checkArgument(StringUtils.isNotBlank(lockId), "lockId cannot be blank");
Expand Down

0 comments on commit ae887b8

Please sign in to comment.