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

Remove and replace additional operations in enclave start #1289

Merged
merged 21 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
38 changes: 0 additions & 38 deletions scripts/aws/conf/default-config.json

This file was deleted.

15 changes: 0 additions & 15 deletions scripts/aws/conf/integ-euid-config.json

This file was deleted.

15 changes: 0 additions & 15 deletions scripts/aws/conf/integ-uid2-config.json

This file was deleted.

31 changes: 0 additions & 31 deletions scripts/aws/conf/prod-euid-config.json

This file was deleted.

26 changes: 0 additions & 26 deletions scripts/aws/conf/prod-uid2-config.json

This file was deleted.

15 changes: 15 additions & 0 deletions scripts/aws/conf/uid2-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"sites_metadata_path": "https://core.uidapi.com/sites/refresh",
"clients_metadata_path": "https://core.uidapi.com/clients/refresh",
"keysets_metadata_path": "https://core.uidapi.com/key/keyset/refresh",
"keyset_keys_metadata_path": "https://core.uidapi.com/key/keyset-keys/refresh",
"client_side_keypairs_metadata_path": "https://core.uidapi.com/client_side_keypairs/refresh",
"salts_metadata_path": "https://core.uidapi.com/salt/refresh",
"services_metadata_path": "https://core.uidapi.com/services/refresh",
"service_links_metadata_path": "https://core.uidapi.com/service_links/refresh",
"optout_metadata_path": "https://optout.uidapi.com/optout/refresh",
"core_attest_url": "https://core.uidapi.com/attest",
"optout_api_uri": "https://optout.uidapi.com/optout/replicate",
"optout_s3_folder": "optout-v2/",
"identity_token_expires_after_seconds": 259200
}
19 changes: 0 additions & 19 deletions scripts/aws/config-server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,6 @@ def get_config():
with open('/etc/secret/secret-value/config', 'r') as secret_file:
secret_value = secret_file.read().strip()
secret_value_json = json.loads(secret_value)
secret_value_json["environment"] = secret_value_json["environment"].lower()
Copy link
Contributor Author

@abuabraham-ttd abuabraham-ttd Jan 16, 2025

Choose a reason for hiding this comment

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

Is this needed now? @Ian-Nara
We populate configs after processing in

config_path = "/etc/secret/secret-value/config"

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the lower() calls to these is still useful, unless I missed that in the ec2.py

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we ensure it is lower as part of validations

if "core_base_url" in secret_value_json:
secret_value_json["core_base_url"] = secret_value_json["core_base_url"].lower()
if "optout_base_url" in secret_value_json:
secret_value_json["optout_base_url"] = secret_value_json["optout_base_url"].lower()
if "operator_type" in secret_value_json and secret_value_json["operator_type"].lower() == "public":
mount_path = '/etc/config/config-values'
abuabraham-ttd marked this conversation as resolved.
Show resolved Hide resolved
if os.path.exists(mount_path):
config_keys = [f for f in os.listdir(mount_path) if os.path.isfile(os.path.join(mount_path, f))]
config = {}
for k in config_keys:
with open(os.path.join(mount_path, k), 'r') as value:
config[k] = value.read()
try:
json.loads(config[k])
config[k] = json.loads(config[k])
except Exception:
pass
secret_value_json.update(config)
return json.dumps(secret_value_json)
except Exception as e:
return str(e), 500
Expand Down
123 changes: 53 additions & 70 deletions scripts/aws/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,82 +18,65 @@ ifconfig lo 127.0.0.1
echo "Starting vsock proxy..."
/app/vsockpx --config /app/proxies.nitro.yaml --daemon --workers $(( ( $(nproc) + 3 ) / 4 )) --log-level 3

# -- load config from identity service
echo "Loading config from identity service via proxy..."

#wait for config service, then download config
OVERRIDES_CONFIG="/app/conf/config-overrides.json"

RETRY_COUNT=0
MAX_RETRY=20
until curl -s -f -o "${OVERRIDES_CONFIG}" -x socks5h://127.0.0.1:3305 http://127.0.0.1:27015/getConfig
do
echo "Waiting for config service to be available"
RETRY_COUNT=$(( RETRY_COUNT + 1))
if [ $RETRY_COUNT -gt $MAX_RETRY ]; then
echo "Config Server did not return a response. Exiting"
exit 1
fi
sleep 2
done
/usr/sbin/syslog-ng --verbose

DEBUG_MODE=$(jq -r ".debug_mode" < "${OVERRIDES_CONFIG}")

if [[ "$DEBUG_MODE" == "true" ]]; then
LOGBACK_CONF="./conf/logback-debug.xml"
else
LOGBACK_CONF="./conf/logback.xml"
# -- setup syslog-ng
echo "Starting syslog-ng..."
/usr/sbin/syslog-ng --verbose
fi
PARAMETERIZED_CONFIG="/app/conf/config-overrides.json"
OPERATOR_CONFIG="/tmp/final-config.json"

# check the config is valid. Querying for a known missing element (empty) makes jq parse the file, but does not echo the results
if jq empty "${OVERRIDES_CONFIG}"; then
echo "Identity service returned valid config"
else
echo "Failed to get a valid config from identity service"
exit 1
fi
build_parameterized_config() {
curl -s -f -o "${PARAMETERIZED_CONFIG}" -x socks5h://127.0.0.1:3305 http://127.0.0.1:27015/getConfig
REQUIRED_KEYS=("optout_base_url" "core_base_url" "api_token" "environment")
for key in "${REQUIRED_KEYS[@]}"; do
if ! jq -e "has(\"${key}\")" "${PARAMETERIZED_CONFIG}" > /dev/null; then
echo "Error: Key '${key}' is missing. Please add it to flask config server"
exit 1
fi
done
FILTER=$(printf '. | {')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do this logic differently in each implementation: In GCP in Java code, in Azure in MAA attestation, and in AWS it was in make_config.py.

for key in "${REQUIRED_KEYS[@]}"; do
FILTER+="$key: .${key}, "
done
FILTER+="debug_mode: .debug_mode, "
FILTER=${FILTER%, }'}'
jq "${FILTER}" "${PARAMETERIZED_CONFIG}" > "${PARAMETERIZED_CONFIG}.tmp" && mv "${PARAMETERIZED_CONFIG}.tmp" "${PARAMETERIZED_CONFIG}"
}

build_operator_config() {
CORE_BASE_URL=$(jq -r ".core_base_url" < "${PARAMETERIZED_CONFIG}")
OPTOUT_BASE_URL=$(jq -r ".optout_base_url" < "${PARAMETERIZED_CONFIG}")
DEPLOYMENT_ENVIRONMENT=$(jq -r ".environment" < "${OPERATOR_CONFIG}")
DEBUG_MODE=$(jq -r ".debug_mode" < "${OPERATOR_CONFIG}")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we need to ensure CORE_BASE_URL is not set to random core, as this will result in operator sending token + pcr0 to overridden malicious core.

Basically, updates the logic to always replace URL in config. If prod, use default prod URL otherwise allow override.

This check is not done in GCP, as we attest GCP confidential compute by calling GCP endpoints. Please correct if wrong @atarassov-ttd

if [[ "$DEPLOYMENT_ENVIRONMENT" == "prod" ]]; then
if [[ "${IDENTITY_SCOPE}" == "UID2" ]]; then
CORE_BASE_URL="https://core-prod.uidapi.com"
OPTOUT_BASE_URL="https://optout-prod.uidapi.com"
else
CORE_BASE_URL="https://core.prod.euid.eu"
OPTOUT_BASE_URL="https://core-prod.uidapi.com"
fi
if [[ "$DEPLOYMENT_ENVIRONMENT" == "prod" ]]; then
echo "Cannot run in DEBUG_MODE in production environment. Exiting."
exit 1
fi
fi

export DEPLOYMENT_ENVIRONMENT=$(jq -r ".environment" < "${OVERRIDES_CONFIG}")
export CORE_BASE_URL=$(jq -r ".core_base_url" < "${OVERRIDES_CONFIG}")
export OPTOUT_BASE_URL=$(jq -r ".optout_base_url" < "${OVERRIDES_CONFIG}")
echo "DEPLOYMENT_ENVIRONMENT=${DEPLOYMENT_ENVIRONMENT}"
if [ -z "${DEPLOYMENT_ENVIRONMENT}" ]; then
echo "DEPLOYMENT_ENVIRONMENT cannot be empty"
exit 1
fi
if [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "integ" ]; then
echo "Unrecognized DEPLOYMENT_ENVIRONMENT ${DEPLOYMENT_ENVIRONMENT}"
exit 1
fi
DEFAULT_CONFIG="/app/conf/uid2-config.json"

echo "Loading config final..."
export FINAL_CONFIG="/app/conf/config-final.json"
if [ "${IDENTITY_SCOPE}" = "UID2" ]; then
python3 /app/make_config.py /app/conf/prod-uid2-config.json /app/conf/integ-uid2-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG}
elif [ "${IDENTITY_SCOPE}" = "EUID" ]; then
python3 /app/make_config.py /app/conf/prod-euid-config.json /app/conf/integ-euid-config.json ${OVERRIDES_CONFIG} "$(nproc)" > ${FINAL_CONFIG}
else
echo "Unrecognized IDENTITY_SCOPE ${IDENTITY_SCOPE}"
exit 1
fi
jq -s '.[0] * .[1]' "${DEFAULT_CONFIG}" "${PARAMETERIZED_CONFIG}" > "${OPERATOR_CONFIG}"
echo "-- replacing URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}"
sed -i "s#https://core.uidapi.com#${CORE_BASE_URL}#g" ${OPERATOR_CONFIG}
sed -i "s#https://optout.uidapi.com#${OPTOUT_BASE_URL}#g" ${OPERATOR_CONFIG}
}

# -- replace base URLs if both CORE_BASE_URL and OPTOUT_BASE_URL are provided
# -- using hardcoded domains is fine because they should not be changed frequently
if [ -n "${CORE_BASE_URL}" ] && [ "${CORE_BASE_URL}" != "null" ] && [ -n "${OPTOUT_BASE_URL}" ] && [ "${OPTOUT_BASE_URL}" != "null" ] && [ "${DEPLOYMENT_ENVIRONMENT}" != "prod" ]; then
echo "Replacing core and optout URLs by ${CORE_BASE_URL} and ${OPTOUT_BASE_URL}..."
build_parameterized_config
build_operator_config

sed -i "s#https://core-integ.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}"
sed -i "s#https://core-prod.uidapi.com#${CORE_BASE_URL}#g" "${FINAL_CONFIG}"
sed -i "s#https://core.integ.euid.eu#${CORE_BASE_URL}#g" "${FINAL_CONFIG}"
sed -i "s#https://core.prod.euid.eu#${CORE_BASE_URL}#g" "${FINAL_CONFIG}"
DEBUG_MODE=$(jq -r ".debug_mode" < "${OPERATOR_CONFIG}")
LOGBACK_CONF="./conf/logback.xml"

sed -i "s#https://optout-integ.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}"
sed -i "s#https://optout-prod.uidapi.com#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}"
sed -i "s#https://optout.integ.euid.eu#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}"
sed -i "s#https://optout.prod.euid.eu#${OPTOUT_BASE_URL}#g" "${FINAL_CONFIG}"
if [[ "$DEBUG_MODE" == "true" ]]; then
LOGBACK_CONF="./conf/logback-debug.xml"
fi

# -- set pwd to /app so we can find default configs
Expand All @@ -106,7 +89,7 @@ java \
-XX:MaxRAMPercentage=95 -XX:-UseCompressedOops -XX:+PrintFlagsFinal \
-Djava.security.egd=file:/dev/./urandom \
-Djava.library.path=/app/lib \
-Dvertx-config-path="${FINAL_CONFIG}" \
-Dvertx-config-path="${OPERATOR_CONFIG}" \
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory \
-Dlogback.configurationFile=${LOGBACK_CONF} \
-Dhttp_proxy=socks5://127.0.0.1:3305 \
Expand Down
41 changes: 0 additions & 41 deletions scripts/aws/load_config.py

This file was deleted.

Loading
Loading