From 1e16c815d25e3f747037d8309a685576d3aecc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6ssler?= Date: Fri, 3 Jul 2026 11:42:07 +0200 Subject: [PATCH] Add data regions support --- lib/php-extension/Environment.cpp | 15 +++++++++- lib/php-extension/RequestProcessor.cpp | 3 ++ lib/php-extension/Utils.cpp | 39 +++++++++++++++++++++++++ lib/php-extension/include/Environment.h | 2 ++ lib/php-extension/include/Utils.h | 4 +++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/php-extension/Environment.cpp b/lib/php-extension/Environment.cpp index bc2903f8e..d33386a82 100644 --- a/lib/php-extension/Environment.cpp +++ b/lib/php-extension/Environment.cpp @@ -212,6 +212,19 @@ unsigned int GetEnvNumber(const std::vector& envGetters, const std: return default_value; } +/* Uses AIKIDO_ENDPOINT if set, otherwise picks the guard endpoint for the region encoded in the token */ +std::string GetGuardEndpoint(const std::vector& envGetters, const std::string& token) { + std::string configuredEndpoint = GetEnvVariable(envGetters, "AIKIDO_ENDPOINT"); + if (!configuredEndpoint.empty()) { + return configuredEndpoint; + } + return GetGuardEndpointForRegion(ExtractRegionFromToken(token)); +} + +std::string GetGuardEndpointWithAllGetters(const std::string& token) { + return GetGuardEndpoint(completeEnvGetters, token); +} + void LoadEnvironmentFromGetters(const std::vector& envGetters) { auto& logLevelStr = AIKIDO_GLOBAL(log_level_str); auto& logLevel = AIKIDO_GLOBAL(log_level); @@ -231,7 +244,7 @@ void LoadEnvironmentFromGetters(const std::vector& envGetters) { AIKIDO_GLOBAL(disk_logs) = GetEnvBool(envGetters, "AIKIDO_DISK_LOGS", false); AIKIDO_GLOBAL(sapi_name) = sapi_module.name; AIKIDO_GLOBAL(token) = GetEnvString(envGetters, "AIKIDO_TOKEN", ""); - AIKIDO_GLOBAL(endpoint) = GetEnvString(envGetters, "AIKIDO_ENDPOINT", "https://guard.aikido.dev/"); + AIKIDO_GLOBAL(endpoint) = GetGuardEndpoint(envGetters, AIKIDO_GLOBAL(token)); AIKIDO_GLOBAL(config_endpoint) = GetEnvString(envGetters, "AIKIDO_REALTIME_ENDPOINT", "https://runtime.aikido.dev/"); AIKIDO_GLOBAL(report_stats_interval_to_agent) = GetEnvNumber(envGetters, "AIKIDO_REPORT_STATS_INTERVAL", 100); } diff --git a/lib/php-extension/RequestProcessor.cpp b/lib/php-extension/RequestProcessor.cpp index df74b87e3..eae9b61e9 100644 --- a/lib/php-extension/RequestProcessor.cpp +++ b/lib/php-extension/RequestProcessor.cpp @@ -82,6 +82,9 @@ std::string RequestProcessor::GetInitData(const std::string& userProvidedToken) if (!userProvidedToken.empty()) { globalToken = userProvidedToken; } + // Recompute using the final token, since \aikido\set_token() can override the token + // loaded above from the environment (see HandleSetToken.cpp). + AIKIDO_GLOBAL(endpoint) = GetGuardEndpointWithAllGetters(globalToken); unordered_map packages = GetPackages(); AIKIDO_GLOBAL(uses_symfony_http_foundation) = packages.find("symfony/http-foundation") != packages.end(); json initData = { diff --git a/lib/php-extension/Utils.cpp b/lib/php-extension/Utils.cpp index b09d6b152..0606ac8e4 100644 --- a/lib/php-extension/Utils.cpp +++ b/lib/php-extension/Utils.cpp @@ -205,6 +205,45 @@ std::string AnonymizeToken(const std::string& str) { return str.length() > 4 ? "AIK_RUNTIME_***" + str.substr(str.length() - 4) : "AIK_RUNTIME_***"; } +std::string ExtractRegionFromToken(const std::string& token) { + const std::string prefix = "AIK_RUNTIME_"; + if (token.empty() || !StartsWith(token, prefix)) { + return "EU"; + } + + std::string tokenWithoutPrefix = token.substr(prefix.length()); + + std::vector parts; + size_t start = 0; + size_t sepPos; + while ((sepPos = tokenWithoutPrefix.find('_', start)) != std::string::npos) { + parts.push_back(tokenWithoutPrefix.substr(start, sepPos - start)); + start = sepPos + 1; + } + parts.push_back(tokenWithoutPrefix.substr(start)); + + // New format: AIK_RUNTIME_{sys_group_id}_{service_id}_{region}_{random} + // Old format: AIK_RUNTIME_{sys_group_id}_{service_id}_{random} + if (parts.size() == 4) { + return parts[2]; + } + + return "EU"; +} + +std::string GetGuardEndpointForRegion(const std::string& region) { + if (region == "US") { + return "https://guard.us.aikido.dev/"; + } + if (region == "ME") { + return "https://guard.me.aikido.dev/"; + } + if (region == "AU") { + return "https://guard.au.aikido.dev/"; + } + return "https://guard.aikido.dev/"; +} + bool FileExists(const std::string& filePath) { struct stat buffer; if (stat(filePath.c_str(), &buffer) == 0) { diff --git a/lib/php-extension/include/Environment.h b/lib/php-extension/include/Environment.h index 0895d5033..c2b3623e2 100644 --- a/lib/php-extension/include/Environment.h +++ b/lib/php-extension/include/Environment.h @@ -7,3 +7,5 @@ void LoadSystemEnvironment(); bool LoadLaravelEnvFile(); bool GetEnvBoolWithAllGetters(const std::string& env_key, bool default_value); + +std::string GetGuardEndpointWithAllGetters(const std::string& token); diff --git a/lib/php-extension/include/Utils.h b/lib/php-extension/include/Utils.h index ffdf98ff2..d6c29be1d 100644 --- a/lib/php-extension/include/Utils.h +++ b/lib/php-extension/include/Utils.h @@ -31,6 +31,10 @@ json CallPhpFunctionParseUrl(const std::string& url); std::string AnonymizeToken(const std::string& str); +std::string ExtractRegionFromToken(const std::string& token); + +std::string GetGuardEndpointForRegion(const std::string& region); + bool FileExists(const std::string& filePath); bool RemoveFile(const std::string& filePath);