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

Load azure secret from vault in JAVA code #254

Merged
merged 23 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/publish-azure-cc-enclave-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
BUILD_TARGET=${{ env.ENCLAVE_PROTOCOL }}

- name: Generate Trivy vulnerability scan report
uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@0.12.0
if: inputs.publish_vulnerabilities == 'true'
with:
image-ref: ${{ steps.meta.outputs.tags }}
Expand All @@ -133,7 +133,7 @@ jobs:
sarif_file: 'trivy-results.sarif'

- name: Test with Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@0.12.0
with:
image-ref: ${{ steps.meta.outputs.tags }}
format: 'table'
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
<vertx.verticle>com.uid2.operator.vertx.UIDOperatorVerticle</vertx.verticle>
<!-- check micrometer.version vertx-micrometer-metrics consumes before bumping up -->
<micrometer.version>1.1.0</micrometer.version>
<enclave-api.version>1.4.0-e5df2e10aa</enclave-api.version>
<enclave-api.version>1.5.0-676519b018</enclave-api.version>
<enclave-aws.version>1.1.0</enclave-aws.version>
<enclave-azure.version>1.3.0-1246054713</enclave-azure.version>
<enclave-azure.version>1.4.0-2195ee834a</enclave-azure.version>
<enclave-gcp.version>1.3.4-649b0b4f7f</enclave-gcp.version>
<uid2-shared.version>5.13.0-a714a3ef26</uid2-shared.version>
<uid2-shared.version>5.14.0-f627d5e88c</uid2-shared.version>
<image.version>${project.version}</image.version>
</properties>

Expand Down
17 changes: 2 additions & 15 deletions scripts/azure-cc/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#
# This script must be compatible with Ash (provided in eclipse-temurin Docker image) and Bash

# -- set API tokens
if [ -z "${VAULT_NAME}" ]; then
echo "VAULT_NAME cannot be empty"
exit 1
Expand All @@ -13,20 +12,8 @@ if [ -z "${OPERATOR_KEY_SECRET_NAME}" ]; then
exit 1
fi

ACCESS_TOKEN=$(wget "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net" -q --header "Metadata: true" -O -| jq -e -r ".access_token")
if [ $? -ne 0 -o -z "${ACCESS_TOKEN}" ]; then
echo "Failed to get access token"
exit 1
fi

OPERATOR_KEY=$(wget "https://${VAULT_NAME}.vault.azure.net/secrets/${OPERATOR_KEY_SECRET_NAME}/?api-version=7.4" -q --header "authorization: Bearer ${ACCESS_TOKEN}" --header "content-type: application/json" -O - | jq -e -r ".value")
if [ $? -ne 0 -o -z "${OPERATOR_KEY}" ]; then
echo "Failed to get operator key"
exit 1
fi

export core_api_token="${OPERATOR_KEY}"
export optout_api_token="${OPERATOR_KEY}"
export azure_vault_name="${VAULT_NAME}"
export azure_secret_name="${OPERATOR_KEY_SECRET_NAME}"

# -- locate config file
if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/uid2/operator/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public class Config extends com.uid2.shared.Const.Config {
public static final String OptOutBloomFilterSizeProp = "optout_bloom_filter_size";
public static final String OptOutHeapDefaultCapacityProp = "optout_heap_default_capacity";
public static final String OptOutS3PathCompatProp = "optout_s3_path_compat";
public static final String OptOutApiTokenProp = "optout_api_token";
public static final String OptOutApiUriProp = "optout_api_uri";
public static final String OptOutInMemCacheProp = "optout_inmem_cache";
public static final String StorageMockProp = "storage_mock";
Expand All @@ -16,5 +15,9 @@ public class Config extends com.uid2.shared.Const.Config {
public static final String SharingTokenExpiryProp = "sharing_token_expiry_seconds";
public static final String EnableClientSideTokenGenerate = "client_side_token_generate";
public static final String ValidateServiceLinks = "validate_service_links";

public static final String AzureVaultNameProp = "azure_vault_name";
public static final String AzureSecretNameProp = "azure_secret_name";

}
}
28 changes: 24 additions & 4 deletions src/main/java/com/uid2/operator/Main.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.uid2.operator;

import ch.qos.logback.classic.LoggerContext;
import com.uid2.enclave.IOperatorKeyRetriever;
import com.uid2.operator.model.KeyManager;
import com.uid2.operator.monitoring.IStatsCollectorQueue;
import com.uid2.operator.monitoring.OperatorMetrics;
import com.uid2.operator.monitoring.StatsCollectorVerticle;
import com.uid2.operator.service.SecureLinkValidatorService;
import com.uid2.operator.store.*;
import com.uid2.operator.store.CloudSyncOptOutStore;
import com.uid2.operator.store.OptOutCloudStorage;
import com.uid2.operator.vertx.OperatorDisableHandler;
import com.uid2.operator.vertx.UIDOperatorVerticle;
import com.uid2.shared.ApplicationVersion;
Expand Down Expand Up @@ -92,13 +94,16 @@ public Main(Vertx vertx, JsonObject config) throws Exception {
this.validateServiceLinks = config.getBoolean(Const.Config.ValidateServiceLinks, false);

String coreAttestUrl = this.config.getString(Const.Config.CoreAttestUrlProp);

var operatorKeyRetriever = createOperatorKeyRetriever();
var operatorKey = operatorKeyRetriever.retrieve();

DownloadCloudStorage fsStores;
if (coreAttestUrl != null) {
String coreApiToken = this.config.getString(Const.Config.CoreApiTokenProp);
Duration disableWaitTime = Duration.ofHours(this.config.getInteger(Const.Config.FailureShutdownWaitHoursProp, 120));
this.disableHandler = new OperatorDisableHandler(disableWaitTime, Clock.systemUTC());

var clients = createUidClients(this.vertx, coreAttestUrl, coreApiToken, this.disableHandler::handleResponseStatus);
var clients = createUidClients(this.vertx, coreAttestUrl, operatorKey, this.disableHandler::handleResponseStatus);
UidCoreClient coreClient = clients.getKey();
UidOptOutClient optOutClient = clients.getValue();
fsStores = coreClient;
Expand Down Expand Up @@ -133,7 +138,7 @@ public Main(Vertx vertx, JsonObject config) throws Exception {
this.keysetProvider = new RotatingKeysetProvider(fsStores, new GlobalScope(new CloudPath(keysetMdPath)));
String saltsMdPath = this.config.getString(Const.Config.SaltsMetadataPathProp);
this.saltProvider = new RotatingSaltProvider(fsStores, saltsMdPath);
this.optOutStore = new CloudSyncOptOutStore(vertx, fsLocal, this.config);
this.optOutStore = new CloudSyncOptOutStore(vertx, fsLocal, this.config, operatorKey);

if (this.validateServiceLinks) {
String serviceMdPath = this.config.getString(Const.Config.ServiceMetadataPathProp);
Expand Down Expand Up @@ -484,4 +489,19 @@ private Map.Entry<UidCoreClient, UidOptOutClient> createUidClients(Vertx vertx,
UidOptOutClient optOutClient = new UidOptOutClient(clientApiToken, CloudUtils.defaultProxy, enforceHttps, attestationTokenRetriever);
return new AbstractMap.SimpleEntry<>(coreClient, optOutClient);
}

private IOperatorKeyRetriever createOperatorKeyRetriever() throws Exception {
var enclavePlatform = this.config.getString("enclave_platform", "");
yishi-ttd marked this conversation as resolved.
Show resolved Hide resolved
switch (enclavePlatform) {
case "azure-cc": {
var vaultName = this.config.getString(Const.Config.AzureVaultNameProp);
var secretName = this.config.getString(Const.Config.AzureSecretNameProp);
return OperatorKeyRetrieverFactory.getAzureOperatorKeyRetriever(vaultName, secretName);
}
default: {
// default to load from config
return () -> this.config.getString(Const.Config.CoreApiTokenProp);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.vertx.ext.web.client.HttpResponse;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.codec.BodyCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -48,7 +48,7 @@ public class CloudSyncOptOutStore implements IOptOutStore {
private final String remoteApiPath;
private final String remoteApiBearerToken;

public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonConfig) throws MalformedURLException {
public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonConfig, String operatorKey) throws MalformedURLException {
this.fsLocal = fsLocal;
this.webClient = WebClient.create(vertx);

Expand All @@ -58,7 +58,7 @@ public CloudSyncOptOutStore(Vertx vertx, ICloudStorage fsLocal, JsonObject jsonC
this.remoteApiPort = -1 == url.getPort() ? 80 : url.getPort();
this.remoteApiHost = url.getHost();
this.remoteApiPath = url.getPath();
this.remoteApiBearerToken = "Bearer " + jsonConfig.getString(Const.Config.OptOutApiTokenProp);
this.remoteApiBearerToken = "Bearer " + operatorKey;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we changing this? It is also used directly above on line 55

Copy link
Contributor Author

Choose a reason for hiding this comment

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

L55 is a different config.
Currently we will set the same operator key for both "OptOutApiToken" and "CoreApiToken".

The value of "OptOutApiToken" should also be fetched from vault - actually it's just operator key.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, but this would mean we are actually getting rid of the config setting for optout_api_token. In that case, we need to remove it from the code, and from all the config. This could be another ticket, but I don't think we should leave unused config settings in the code / config files

Copy link
Contributor Author

@yishi-ttd yishi-ttd Oct 27, 2023

Choose a reason for hiding this comment

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

I will remove OptOutApiTokenProp config first in this PR.
This is the only place that will use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As for the places to set this env, I will create a ticket to track.

} else {
this.remoteApiPort = -1;
this.remoteApiHost = null;
Expand Down