Skip to content

Commit 4c8e872

Browse files
abuabraham-ttdRelease Workflow
andauthored
Abu UI d2 4557 gcp validation support (#1286)
* Adding validations in GCP --------- Co-authored-by: Release Workflow <[email protected]>
1 parent 9b94fd5 commit 4c8e872

File tree

10 files changed

+180
-144
lines changed

10 files changed

+180
-144
lines changed

.github/workflows/publish-gcp-oidc-enclave-docker.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ jobs:
9393
echo "jar_version=$(mvn help:evaluate -Dexpression=project.version | grep -e '^[1-9][^\[]')" >> $GITHUB_OUTPUT
9494
echo "git_commit=$(git show --format="%h" --no-patch)" >> $GITHUB_OUTPUT
9595
cp -r target ${{ env.DOCKER_CONTEXT_PATH }}/
96+
cp scripts/confidential_compute.py ${{ env.DOCKER_CONTEXT_PATH }}/
9697
9798
- name: Log in to the Docker container registry
9899
uses: docker/login-action@v3

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.uid2</groupId>
88
<artifactId>uid2-operator</artifactId>
9-
<version>5.44.6</version>
9+
<version>5.45.7-alpha-169-SNAPSHOT</version>
1010

1111
<properties>
1212
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

scripts/confidential_compute.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ def __init__(self, error_name, provider, extra_message=None):
1919
urls = {
2020
"EC2": "https://unifiedid.com/docs/guides/operator-guide-aws-marketplace#uid2-operator-error-codes",
2121
"Azure": "https://unifiedid.com/docs/guides/operator-guide-azure-enclave#uid2-operator-error-codes",
22-
"GCP": "https://unifiedid.com/docs/guides/operator-private-gcp-confidential-space#uid2-operator-error-codes",
22+
"GCPEntrypoint": "https://unifiedid.com/docs/guides/operator-private-gcp-confidential-space#uid2-operator-error-codes",
2323
}
2424
url = urls.get(provider)
2525
super().__init__(f"{error_name}\n" + (extra_message if extra_message else "") + f"\nVisit {url} for more details")
2626

2727
class MissingInstanceProfile(ConfidentialComputeStartupException):
28-
def __init__(self, cls):
29-
super().__init__(error_name=f"E01: {self.__class__.__name__}", provider=cls)
28+
def __init__(self, cls, message = None):
29+
super().__init__(error_name=f"E01: {self.__class__.__name__}", provider=cls, extra_message=message)
3030

3131
class ConfigNotFound(ConfidentialComputeStartupException):
3232
def __init__(self, cls, message = None):

scripts/gcp-oidc/Dockerfile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ LABEL "tee.launch_policy.allow_env_override"="API_TOKEN_SECRET_NAME,DEPLOYMENT_E
55
LABEL "tee.launch_policy.log_redirect"="always"
66

77
# Install Packages
8-
RUN apk update && apk add jq
8+
RUN apk update && apk add --no-cache jq python3 py3-pip && \
9+
python3 -m venv /venv && \
10+
. /venv/bin/activate && \
11+
pip install --no-cache-dir google-cloud-secret-manager google-auth google-api-core && \
12+
rm -rf /var/cache/apk/*
913

1014
WORKDIR /app
1115
EXPOSE 8080
@@ -18,7 +22,6 @@ ENV JAR_NAME=${JAR_NAME}
1822
ENV JAR_VERSION=${JAR_VERSION}
1923
ENV IMAGE_VERSION=${IMAGE_VERSION}
2024
ENV REGION=default
21-
ENV LOKI_HOSTNAME=loki
2225

2326
COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar
2427
COPY ./target/${JAR_NAME}-${JAR_VERSION}-sources.jar /app
@@ -28,9 +31,10 @@ COPY ./conf/*.xml /app/conf/
2831

2932
RUN tar xzvf /app/static.tar.gz --no-same-owner --no-same-permissions && rm -f /app/static.tar.gz
3033

31-
COPY ./entrypoint.sh /app/
32-
RUN chmod a+x /app/entrypoint.sh
34+
COPY ./gcp.py /app/
35+
COPY ./confidential_compute.py /app
36+
RUN chmod a+x /app/gcp.py
3337

3438
RUN mkdir -p /opt/uid2 && chmod 777 -R /opt/uid2 && mkdir -p /app && chmod 705 -R /app && mkdir -p /app/file-uploads && chmod 777 -R /app/file-uploads
3539

36-
CMD ["/app/entrypoint.sh"]
40+
CMD ["/venv/bin/python", "/app/gcp.py"]
Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
{
2-
"service_verbose": true,
3-
"service_instances": 12,
4-
"core_s3_bucket": null,
5-
"core_attest_url": null,
6-
"core_api_token": null,
7-
"storage_mock": false,
8-
"optout_s3_bucket": null,
9-
"optout_s3_folder": "optout/",
10-
"optout_s3_path_compat": false,
11-
"optout_data_dir": "/opt/uid2/operator-optout/",
12-
"optout_api_token": null,
13-
"optout_api_uri": null,
14-
"optout_bloom_filter_size": 8192,
15-
"optout_delta_rotate_interval": 300,
16-
"optout_delta_backtrack_in_days": 1,
17-
"optout_partition_interval": 86400,
18-
"optout_max_partitions": 30,
19-
"optout_heap_default_capacity": 8192,
20-
"cloud_download_threads": 8,
21-
"cloud_upload_threads": 2,
22-
"cloud_refresh_interval": 60,
23-
"sites_metadata_path": "sites/metadata.json",
24-
"clients_metadata_path": "clients/metadata.json",
25-
"client_side_keypairs_metadata_path": "client_side_keypairs/metadata.json",
26-
"keysets_metadata_path": "keysets/metadata.json",
27-
"keyset_keys_metadata_path": "keyset_keys/metadata.json",
28-
"salts_metadata_path": "salts/metadata.json",
29-
"services_metadata_path": "services/metadata.json",
30-
"service_links_metadata_path": "service_links/metadata.json",
31-
"optout_metadata_path": null,
32-
"enclave_platform": "gcp-oidc",
33-
"optout_inmem_cache": true,
34-
"identity_token_expires_after_seconds": 86400,
35-
"refresh_token_expires_after_seconds": 2592000,
36-
"refresh_identity_token_after_seconds": 3600,
37-
"allow_legacy_api": false,
38-
"failure_shutdown_wait_hours": 120,
39-
"sharing_token_expiry_seconds": 2592000,
40-
"validate_service_links": false,
41-
"operator_type": "private"
42-
}
1+
{
2+
"service_verbose": true,
3+
"service_instances": 12,
4+
"core_s3_bucket": null,
5+
"core_attest_url": null,
6+
"core_api_token": null,
7+
"storage_mock": false,
8+
"optout_s3_bucket": null,
9+
"optout_s3_folder": "optout/",
10+
"optout_s3_path_compat": false,
11+
"optout_data_dir": "/opt/uid2/operator-optout/",
12+
"optout_api_token": null,
13+
"optout_api_uri": null,
14+
"optout_bloom_filter_size": 8192,
15+
"optout_delta_rotate_interval": 300,
16+
"optout_delta_backtrack_in_days": 1,
17+
"optout_partition_interval": 86400,
18+
"optout_max_partitions": 30,
19+
"optout_heap_default_capacity": 8192,
20+
"cloud_download_threads": 8,
21+
"cloud_upload_threads": 2,
22+
"cloud_refresh_interval": 60,
23+
"sites_metadata_path": "sites/metadata.json",
24+
"clients_metadata_path": "clients/metadata.json",
25+
"client_side_keypairs_metadata_path": "client_side_keypairs/metadata.json",
26+
"keysets_metadata_path": "keysets/metadata.json",
27+
"keyset_keys_metadata_path": "keyset_keys/metadata.json",
28+
"salts_metadata_path": "salts/metadata.json",
29+
"services_metadata_path": "services/metadata.json",
30+
"service_links_metadata_path": "service_links/metadata.json",
31+
"optout_metadata_path": null,
32+
"enclave_platform": "gcp-oidc",
33+
"optout_inmem_cache": true,
34+
"identity_token_expires_after_seconds": 86400,
35+
"refresh_token_expires_after_seconds": 2592000,
36+
"refresh_identity_token_after_seconds": 3600,
37+
"allow_legacy_api": false,
38+
"failure_shutdown_wait_hours": 120,
39+
"sharing_token_expiry_seconds": 2592000,
40+
"validate_service_links": false,
41+
"operator_type": "private"
42+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"sites_metadata_path": "https://core.uidapi.com/sites/refresh",
3+
"clients_metadata_path": "https://core.uidapi.com/clients/refresh",
4+
"keysets_metadata_path": "https://core.uidapi.com/key/keyset/refresh",
5+
"keyset_keys_metadata_path": "https://core.uidapi.com/key/keyset-keys/refresh",
6+
"client_side_keypairs_metadata_path": "https://core.uidapi.com/client_side_keypairs/refresh",
7+
"salts_metadata_path": "https://core.uidapi.com/salt/refresh",
8+
"services_metadata_path": "https://core.uidapi.com/services/refresh",
9+
"service_links_metadata_path": "https://core.uidapi.com/service_links/refresh",
10+
"optout_metadata_path": "https://optout.uidapi.com/optout/refresh",
11+
"core_attest_url": "https://core.uidapi.com/attest",
12+
"optout_api_uri": "https://optout.uidapi.com/optout/replicate",
13+
"optout_s3_folder": "uid-optout-integ/"
14+
}

scripts/gcp-oidc/conf/integ-uid2-config.json

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
{
2-
"sites_metadata_path": "https://core.uidapi.com/sites/refresh",
3-
"clients_metadata_path": "https://core.uidapi.com/clients/refresh",
4-
"keysets_metadata_path": "https://core.uidapi.com/key/keyset/refresh",
5-
"keyset_keys_metadata_path": "https://core.uidapi.com/key/keyset-keys/refresh",
6-
"client_side_keypairs_metadata_path": "https://core.uidapi.com/client_side_keypairs/refresh",
7-
"salts_metadata_path": "https://core.uidapi.com/salt/refresh",
8-
"services_metadata_path": "https://core.uidapi.com/services/refresh",
9-
"service_links_metadata_path": "https://core.uidapi.com/service_links/refresh",
10-
"optout_metadata_path": "https://optout.uidapi.com/optout/refresh",
11-
"core_attest_url": "https://core.uidapi.com/attest",
12-
"optout_api_uri": "https://optout.uidapi.com/optout/replicate",
13-
"optout_s3_folder": "optout-v2/",
14-
"identity_token_expires_after_seconds": 259200
15-
}
1+
{
2+
"sites_metadata_path": "https://core.uidapi.com/sites/refresh",
3+
"clients_metadata_path": "https://core.uidapi.com/clients/refresh",
4+
"keysets_metadata_path": "https://core.uidapi.com/key/keyset/refresh",
5+
"keyset_keys_metadata_path": "https://core.uidapi.com/key/keyset-keys/refresh",
6+
"client_side_keypairs_metadata_path": "https://core.uidapi.com/client_side_keypairs/refresh",
7+
"salts_metadata_path": "https://core.uidapi.com/salt/refresh",
8+
"services_metadata_path": "https://core.uidapi.com/services/refresh",
9+
"service_links_metadata_path": "https://core.uidapi.com/service_links/refresh",
10+
"optout_metadata_path": "https://optout.uidapi.com/optout/refresh",
11+
"core_attest_url": "https://core.uidapi.com/attest",
12+
"optout_api_uri": "https://optout.uidapi.com/optout/replicate",
13+
"optout_s3_folder": "optout-v2/",
14+
"identity_token_expires_after_seconds": 259200
15+
}

scripts/gcp-oidc/entrypoint.sh

Lines changed: 0 additions & 64 deletions
This file was deleted.

scripts/gcp-oidc/gcp.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import shutil
5+
from typing import Dict
6+
import sys
7+
from google.cloud import secretmanager
8+
from google.auth import default
9+
from google.auth.exceptions import DefaultCredentialsError
10+
from google.api_core.exceptions import PermissionDenied, NotFound
11+
12+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13+
from confidential_compute import ConfidentialCompute, ConfidentialComputeConfig, MissingConfig, ConfigNotFound, MissingInstanceProfile, ConfidentialComputeStartupException
14+
15+
class GCPEntrypoint(ConfidentialCompute):
16+
17+
def __init__(self):
18+
super().__init__()
19+
20+
def _get_secret(self, secret_identifier=None) -> ConfidentialComputeConfig:
21+
keys_mapping = {
22+
"core_base_url": "CORE_BASE_URL",
23+
"optout_base_url": "OPTOUT_BASE_URL",
24+
"environment": "DEPLOYMENT_ENVIRONMENT",
25+
"skip_validations": "SKIP_VALIDATIONS",
26+
"debug_mode": "DEBUG_MODE",
27+
}
28+
config: ConfidentialComputeConfig = {
29+
key: (os.environ[env_var].lower() == "true" if key in ["skip_validations", "debug_mode"] else os.environ[env_var])
30+
for key, env_var in keys_mapping.items() if env_var in os.environ
31+
}
32+
33+
if not os.getenv("API_TOKEN_SECRET_NAME"):
34+
raise MissingConfig(self.__class__.__name__, ["API_TOKEN_SECRET_NAME"])
35+
try:
36+
client = secretmanager.SecretManagerServiceClient()
37+
secret_version_name = f"{os.getenv("API_TOKEN_SECRET_NAME")}"
38+
response = client.access_secret_version(name=secret_version_name)
39+
secret_value = response.payload.data.decode("UTF-8")
40+
except (PermissionDenied, DefaultCredentialsError) as e:
41+
raise MissingInstanceProfile(self.__class__.__name__, str(e))
42+
except NotFound:
43+
raise ConfigNotFound(self.__class__.__name__, f"Secret Manager {os.getenv("API_TOKEN_SECRET_NAME")}")
44+
config["api_token"] = secret_value
45+
return config
46+
47+
def __populate_operator_config(self, destination):
48+
target_config = f"/app/conf/{self.configs["environment"].lower()}-config.json"
49+
shutil.copy(target_config, destination)
50+
with open(destination, 'r') as file:
51+
config = file.read()
52+
config = config.replace("https://core.uidapi.com", self.configs.get("core_base_url"))
53+
config = config.replace("https://optout.uidapi.com", self.configs.get("optout_base_url"))
54+
with open(destination, 'w') as file:
55+
file.write(config)
56+
57+
def _setup_auxiliaries(self) -> None:
58+
""" No Auxiliariy service required for GCP Confidential compute. """
59+
pass
60+
61+
def _validate_auxiliaries(self) -> None:
62+
""" No Auxiliariy service required for GCP Confidential compute. """
63+
pass
64+
65+
def run_compute(self) -> None:
66+
self.configs = self._get_secret('read_from_env_vars')
67+
print(f"Fetched configs")
68+
if not self.configs.get("skip_validations"):
69+
self.validate_configuration()
70+
config_locaton = "/tmp/final-config.json"
71+
self.__populate_operator_config(config_locaton)
72+
os.environ["gcp_secret_version_name"] = os.getenv("API_TOKEN_SECRET_NAME")
73+
java_command = [
74+
"java",
75+
"-XX:MaxRAMPercentage=95",
76+
"-XX:-UseCompressedOops",
77+
"-XX:+PrintFlagsFinal",
78+
"-Djava.security.egd=file:/dev/./urandom",
79+
"-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory",
80+
"-Dlogback.configurationFile=/app/conf/logback.xml",
81+
f"-Dvertx-config-path={config_locaton}",
82+
"-jar",
83+
f"{os.getenv("JAR_NAME")}-{os.getenv("JAR_VERSION")}.jar"
84+
]
85+
self.run_command(java_command)
86+
87+
if __name__ == "__main__":
88+
try:
89+
gcp = GCP()
90+
gcp.run_compute()
91+
except ConfidentialComputeStartupException as e:
92+
print("Failed starting up Confidential Compute. Please checks the logs for errors and retry \n", e)
93+
except Exception as e:
94+
print("Unexpected failure while starting up Confidential Compute. Please contact UID support team with this log \n ", e)
95+

0 commit comments

Comments
 (0)