@@ -49,7 +49,26 @@ def get_token_url(cls) -> str:
4949 @classmethod
5050 def get_meta_url (cls ) -> str :
5151 return f"http://{ cls .AWS_METADATA } /latest/dynamic/instance-identity/document"
52-
52+
53+
54+ # Default URLs for core/optout by identity scope + environment
55+ # CloudFormation template injects these secrets, but this is a fallback in case
56+ # of a manual AMI_only upgrade
57+ DEFAULT_BASE_URLS = {
58+ "uid2" : {
59+ "integ" : {"core_base_url" : "https://core-integ.uidapi.com" ,
60+ "optout_base_url" : "https://optout-integ.uidapi.com" },
61+ "prod" : {"core_base_url" : "https://core-prod.uidapi.com" ,
62+ "optout_base_url" : "https://optout-prod.uidapi.com" },
63+ },
64+ "euid" : {
65+ "integ" : {"core_base_url" : "https://core.integ.euid.eu" ,
66+ "optout_base_url" : "https://optout.integ.euid.eu" },
67+ "prod" : {"core_base_url" : "https://core.prod.euid.eu" ,
68+ "optout_base_url" : "https://optout.prod.euid.eu" },
69+ }
70+ }
71+
5372
5473class EC2 (ConfidentialCompute ):
5574
@@ -112,6 +131,7 @@ def add_defaults(configs: Dict[str, any]) -> AWSConfidentialComputeConfig:
112131 configs .setdefault ("debug_mode" , False )
113132 configs .setdefault ("core_api_token" , configs .get ("operator_key" ))
114133 configs .setdefault ("optout_api_token" , configs .get ("operator_key" ))
134+ self .__set_base_url_defaults (configs )
115135 return configs
116136
117137 region = self .__get_current_region ()
@@ -129,6 +149,24 @@ def add_defaults(configs: Dict[str, any]) -> AWSConfidentialComputeConfig:
129149 except ClientError as _ :
130150 raise OperatorKeyNotFoundError (self .__class__ .__name__ , f"Secret Manager { secret_identifier } in { region } " )
131151
152+ @staticmethod
153+ def __get_identity_scope () -> str :
154+ """Reads the identity scope (uid2/euid) baked into the AMI at build time."""
155+ with open ("/opt/uid2operator/identity_scope.txt" ) as file :
156+ return file .read ().strip ().lower ()
157+
158+ def __set_base_url_defaults (self , configs : Dict [str , any ]) -> None :
159+ """Fills core_base_url/optout_base_url from environment + identity scope when the
160+ secret omits them. No-op when a value is already present, or when scope/environment
161+ is unrecognised (validate_configuration then surfaces the appropriate error)."""
162+ scope = self .__get_identity_scope ()
163+ environment = configs .get ("environment" )
164+ defaults = DEFAULT_BASE_URLS .get (scope , {}).get (environment , {})
165+ for key , url in defaults .items ():
166+ if not configs .get (key ):
167+ logging .info (f"{ key } not provided in secret; defaulting to { url } ({ scope } /{ environment } )" )
168+ configs [key ] = url
169+
132170 @staticmethod
133171 def __get_max_capacity ():
134172 try :
@@ -255,10 +293,8 @@ def __get_secret_name_from_userdata(self) -> str:
255293 response = requests .get (AuxiliaryConfig .get_user_data_url (), headers = {"X-aws-ec2-metadata-token" : token })
256294 user_data = response .text
257295
258- with open ("/opt/uid2operator/identity_scope.txt" ) as file :
259- identity_scope = file .read ().strip ()
260-
261- default_name = f"{ identity_scope .lower ()} -operator-config-key"
296+ identity_scope = self .__get_identity_scope ()
297+ default_name = f"{ identity_scope } -operator-config-key"
262298 hardcoded_value = f"{ identity_scope .upper ()} _CONFIG_SECRET_KEY"
263299 match = re .search (rf'^export { hardcoded_value } ="(.+?)"$' , user_data , re .MULTILINE )
264300 return match .group (1 ) if match else default_name
0 commit comments