Fix genai variable handling and add API key masking

- Add has_variable() method to GenAI_Threads_Handler for variable validation
- Add genai- prefix check in is_valid_global_variable()
- Auto-initialize NL2SQL converter when genai-nl2sql_enabled is set to true at runtime
- Make init_nl2sql() public to allow runtime initialization
- Mask API keys in logs (show only first 2 chars, rest as 'x')
pull/5310/head
Rene Cannao 1 month ago
parent 1eb42c57d0
commit 3fe8a48f70

@ -71,7 +71,6 @@ private:
// Helper methods
int init_vector_db();
int init_nl2sql();
int init_anomaly_detector();
void close_vector_db();
void close_nl2sql();
@ -129,6 +128,16 @@ public:
*/
void shutdown();
/**
* @brief Initialize NL2SQL converter
*
* Initializes the NL2SQL converter if not already initialized.
* This can be called at runtime after enabling nl2sql.
*
* @return 0 on success, non-zero on failure
*/
int init_nl2sql();
/**
* @brief Acquire write lock for thread-safe operations
*

@ -301,6 +301,14 @@ public:
*/
char** get_variables_list();
/**
* @brief Check if a variable exists
*
* @param name The name of the variable to check
* @return true if the variable exists, false otherwise
*/
bool has_variable(const char* name);
/**
* @brief Print the version information
*/

@ -1079,6 +1079,14 @@ void ProxySQL_Admin::flush_genai_variables___database_to_runtime(SQLite3DB* db,
pthread_mutex_unlock(&GloVars.checksum_mutex);
}
// Check if NL2SQL needs to be initialized
if (GloAI && GloGATH->variables.genai_nl2sql_enabled && !GloAI->get_nl2sql()) {
proxy_info("NL2SQL enabled but not initialized, initializing now\n");
if (GloAI->init_nl2sql() != 0) {
proxy_error("Failed to initialize NL2SQL converter\n");
}
}
if (lock) wrunlock();
}
if (resultset) delete resultset;

@ -884,6 +884,40 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
return true;
}
// Creates a masked copy of the query string for logging, masking sensitive values like API keys
// Returns a newly allocated string that must be freed by the caller
static char* mask_sensitive_values_in_query(const char* query) {
if (!query || !strstr(query, "_key="))
return strdup(query);
char* masked = strdup(query);
char* key_pos = strstr(masked, "_key=");
if (key_pos) {
key_pos += 5; // Move past "_key="
char* value_start = key_pos;
// Find the end of the value (either single quote, space, or end of string)
char* value_end = value_start;
if (*value_start == '\'') {
value_start++; // Skip opening quote
value_end = value_start;
while (*value_end && *value_end != '\'')
value_end++;
} else {
while (*value_end && *value_end != ' ' && *value_end != '\0')
value_end++;
}
size_t value_len = value_end - value_start;
if (value_len > 2) {
// Keep first 2 chars, mask the rest
for (size_t i = 2; i < value_len; i++) {
value_start[i] = 'x';
}
}
}
return masked;
}
// Returns true if the given name is either a know mysql or admin global variable.
bool is_valid_global_variable(const char *var_name) {
if (strlen(var_name) > 6 && !strncmp(var_name, "mysql-", 6) && GloMTH->has_variable(var_name + 6)) {
@ -902,6 +936,8 @@ bool is_valid_global_variable(const char *var_name) {
#endif /* PROXYSQLCLICKHOUSE */
} else if (strlen(var_name) > 4 && !strncmp(var_name, "mcp-", 4) && GloMCPH && GloMCPH->has_variable(var_name + 4)) {
return true;
} else if (strlen(var_name) > 6 && !strncmp(var_name, "genai-", 6) && GloGATH && GloGATH->has_variable(var_name + 6)) {
return true;
} else {
return false;
}
@ -918,7 +954,9 @@ bool admin_handler_command_set(char *query_no_space, unsigned int query_no_space
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Received command %s\n", query_no_space);
if (strncasecmp(query_no_space,(char *)"set autocommit",strlen((char *)"set autocommit"))) {
if (strncasecmp(query_no_space,(char *)"SET @@session.autocommit",strlen((char *)"SET @@session.autocommit"))) {
proxy_info("Received command %s\n", query_no_space);
char* masked_query = mask_sensitive_values_in_query(query_no_space);
proxy_info("Received command %s\n", masked_query);
free(masked_query);
}
}
}

@ -673,6 +673,19 @@ char** GenAI_Threads_Handler::get_variables_list() {
return list;
}
bool GenAI_Threads_Handler::has_variable(const char* name) {
if (!name)
return false;
// Check if name exists in genai_thread_variables_names
for (int i = 0; genai_thread_variables_names[i]; i++) {
if (!strcmp(name, genai_thread_variables_names[i]))
return true;
}
return false;
}
void GenAI_Threads_Handler::print_version() {
fprintf(stderr, "GenAI Threads Handler rev. %s -- %s -- %s\n", GENAI_THREAD_VERSION, __FILE__, __TIMESTAMP__);
}

Loading…
Cancel
Save