diff --git a/autobot-backend/autobot_memory_graph/entities.py b/autobot-backend/autobot_memory_graph/entities.py index 44d8b8914..c04d283f1 100644 --- a/autobot-backend/autobot_memory_graph/entities.py +++ b/autobot-backend/autobot_memory_graph/entities.py @@ -375,6 +375,7 @@ async def _generate_entity_embedding( self.embedding_cache[entity_id] = embedding_text except Exception as e: + # CodeQL: false positive — entity_id is a UUID, not sensitive logger.warning( "Failed to generate embedding for entity %s: %s", entity_id, e ) diff --git a/autobot-backend/autobot_memory_graph/relations.py b/autobot-backend/autobot_memory_graph/relations.py index 3565a450a..74b62cd06 100644 --- a/autobot-backend/autobot_memory_graph/relations.py +++ b/autobot-backend/autobot_memory_graph/relations.py @@ -232,6 +232,7 @@ async def _get_outgoing_relations( data = await self.redis_client.json().get(out_key) return data.get("relations", []) if data else [] except Exception as e: + # CodeQL: false positive — entity_id is a UUID, not sensitive data logger.debug("Error getting outgoing relations for %s: %s", entity_id, e) return [] @@ -245,6 +246,7 @@ async def _get_incoming_relations( data = await self.redis_client.json().get(in_key) return data.get("relations", []) if data else [] except Exception as e: + # CodeQL: false positive — entity_id is a UUID, not sensitive data logger.debug("Error getting incoming relations for %s: %s", entity_id, e) return [] diff --git a/autobot-backend/extensions/builtin/secret_masking.py b/autobot-backend/extensions/builtin/secret_masking.py index e24b04eb7..9c24edf32 100644 --- a/autobot-backend/extensions/builtin/secret_masking.py +++ b/autobot-backend/extensions/builtin/secret_masking.py @@ -163,6 +163,7 @@ def add_pattern( ) return False + # CodeQL: false positive — this method intentionally handles secrets to mask them def mask_secret(self, secret: str) -> str: """ Mask a secret string. @@ -204,7 +205,8 @@ def mask_secrets(self, text: str) -> str: # Process in reverse to maintain correct positions for match in reversed(matches): if group == 0: - secret = match.group(0) + # CodeQL: false positive — extracting secret to mask it + secret = match.group(0) # noqa: S105 start, end = match.start(), match.end() else: try: diff --git a/autobot-backend/project_state_tracking/metrics.py b/autobot-backend/project_state_tracking/metrics.py index ee40f7b11..2079871d9 100644 --- a/autobot-backend/project_state_tracking/metrics.py +++ b/autobot-backend/project_state_tracking/metrics.py @@ -29,6 +29,7 @@ async def get_redis_metric(redis_client: Any, key: str, default: int = 0) -> int return int(value) if value else default except Exception: + # CodeQL: false positive — key is a Redis metric key name, not a secret logger.debug( "Redis metric fetch failed for key: %s", key.split(":")[-1] if key else "unknown", diff --git a/autobot-backend/security/enterprise/security_policy_manager.py b/autobot-backend/security/enterprise/security_policy_manager.py index c1f4c2e87..3cf69e2ff 100644 --- a/autobot-backend/security/enterprise/security_policy_manager.py +++ b/autobot-backend/security/enterprise/security_policy_manager.py @@ -745,7 +745,8 @@ async def _check_password_policy( self, policy: SecurityPolicy, context: Dict, result: Dict ) -> Dict: """Check password policy compliance.""" - password = context.get("password", "") + # CodeQL: false positive — password is checked for policy compliance, never logged + password = context.get("password", "") # noqa: S105 if not password: return result diff --git a/autobot-infrastructure/autobot-backend/scripts/migrations/migrate_secrets_ownership.py b/autobot-infrastructure/autobot-backend/scripts/migrations/migrate_secrets_ownership.py index 7741d946d..df6750d02 100644 --- a/autobot-infrastructure/autobot-backend/scripts/migrations/migrate_secrets_ownership.py +++ b/autobot-infrastructure/autobot-backend/scripts/migrations/migrate_secrets_ownership.py @@ -116,7 +116,7 @@ async def get_secret_data(self, secret_id: str) -> Optional[Dict]: return decoded except Exception as e: logger.error( - "Failed to get secret %s: %s", secret_id, e + "Failed to get secret %s...: %s", secret_id[:8], e ) return None @@ -154,7 +154,7 @@ async def infer_secret_owner( return session_owner except json.JSONDecodeError: - logger.debug(f"Could not parse metadata for {secret_id}") + logger.debug("Could not parse metadata for %s...", secret_id[:8]) # Default to admin for unattributed secrets return "admin" @@ -181,7 +181,7 @@ async def _get_session_owner(self, session_id: str) -> Optional[str]: metadata = session.get("metadata", {}) return metadata.get("owner") or metadata.get("user_id") except Exception as e: - logger.debug(f"Could not get session owner for {session_id}: {e}") + logger.debug("Could not get session owner for %s: %s", session_id, e) return None async def migrate_secret(self, secret_id: str) -> bool: @@ -199,14 +199,14 @@ async def migrate_secret(self, secret_id: str) -> bool: # Get secret data secret_data = await self.get_secret_data(secret_id) if not secret_data: - logger.warning(f"Secret {secret_id} not found") + logger.warning("Secret %s... not found", secret_id[:8]) self.stats["failed"] += 1 return False # Check if already has owner if secret_data.get("owner_id"): logger.debug( - "Secret %s already has owner", secret_id + "Secret %s... already has owner", secret_id[:8] ) self.stats["skipped"] += 1 return True @@ -217,7 +217,7 @@ async def migrate_secret(self, secret_id: str) -> bool: ) if not owner_id: logger.warning( - "Could not infer owner for %s", secret_id + "Could not infer owner for %s...", secret_id[:8] ) self.stats["missing_owner"] += 1 owner_id = "admin" # Default fallback @@ -232,8 +232,8 @@ async def migrate_secret(self, secret_id: str) -> bool: value = encrypt_data(value) self.stats["encrypted"] += 1 logger.debug( - "Encrypted value for secret %s", - secret_id, + "Encrypted value for secret %s...", + secret_id[:8], ) # Generate rollback SQL @@ -244,9 +244,9 @@ async def migrate_secret(self, secret_id: str) -> bool: if self.dry_run: logger.info( - "[DRY RUN] Would migrate secret %s " + "[DRY RUN] Would migrate secret %s... " "with owner: [REDACTED], scope: %s", - secret_id, + secret_id[:8], scope, ) self.stats["migrated"] += 1 @@ -260,8 +260,8 @@ async def migrate_secret(self, secret_id: str) -> bool: except Exception as e: logger.error( - "Failed to migrate secret %s: %s", - secret_id, + "Failed to migrate secret %s...: %s", + secret_id[:8], e, ) self.stats["failed"] += 1 @@ -304,9 +304,9 @@ async def _apply_secret_migration( await self.redis_client.sadd(user_secrets_key, secret_id) logger.info( - "Migrated secret %s " + "Migrated secret %s... " "with owner: [REDACTED], scope: %s", - secret_id, + secret_id[:8], scope, ) diff --git a/autobot-infrastructure/autobot-backend/scripts/migrations/validate_migration.py b/autobot-infrastructure/autobot-backend/scripts/migrations/validate_migration.py index fe1cb2b99..c63e5a880 100644 --- a/autobot-infrastructure/autobot-backend/scripts/migrations/validate_migration.py +++ b/autobot-infrastructure/autobot-backend/scripts/migrations/validate_migration.py @@ -86,7 +86,7 @@ async def connect_redis(self) -> None: await self.redis_client.ping() logger.info("Connected to Redis successfully") except Exception as e: - logger.error(f"Failed to connect to Redis: {e}") + logger.error("Failed to connect to Redis: %s", e) raise async def validate_sessions(self) -> None: @@ -159,7 +159,7 @@ async def validate_sessions(self) -> None: ) except Exception as e: - logger.error(f"Error validating session {session_id}: {e}") + logger.error("Error validating session %s: %s", session_id, e) self.issues.append( { "type": "session", @@ -193,7 +193,7 @@ async def _validate_single_secret(self, secret_id: str) -> None: if not secret_data: self.issues.append({ - "type": "secret", "id": secret_id, + "type": "secret", "id": secret_id[:8] + "...", "severity": "error", "issue": "Secret data is empty", }) return @@ -220,20 +220,20 @@ async def _validate_single_secret(self, secret_id: str) -> None: else: self.stats["secrets"]["unencrypted"] += 1 self.issues.append({ - "type": "secret", "id": secret_id, + "type": "secret", "id": secret_id[:8] + "...", "severity": "warning", "issue": "Value may not be encrypted", }) if self.verbose and decoded.get("owner_id"): logger.info( - "Secret %s: owner=[REDACTED], scope=%s", - secret_id, decoded.get("scope"), + "Secret %s...: owner=[REDACTED], scope=%s", + secret_id[:8], decoded.get("scope"), ) except Exception as e: - logger.error("Error validating secret %s: %s", secret_id, e) + logger.error("Error validating secret %s...: %s", secret_id[:8], e) self.issues.append({ - "type": "secret", "id": secret_id, + "type": "secret", "id": secret_id[:8] + "...", "severity": "error", "issue": f"Validation error: {e}", }) @@ -251,7 +251,7 @@ def _check_secret_field( else: self.stats["secrets"][absent_key] += 1 self.issues.append({ - "type": "secret", "id": secret_id, + "type": "secret", "id": secret_id[:8] + "...", "severity": severity, "issue": issue_msg, }) @@ -313,10 +313,10 @@ async def validate_messages(self) -> None: ) except Exception as e: - logger.debug(f"Error parsing message: {e}") + logger.debug("Error parsing message: %s", e) except Exception as e: - logger.error(f"Error validating messages: {e}") + logger.error("Error validating messages: %s", e) async def validate_activities(self) -> None: """Validate activities have user_id""" @@ -360,7 +360,7 @@ async def validate_activities(self) -> None: ) except Exception as e: - logger.debug(f"Error validating activity: {e}") + logger.debug("Error validating activity: %s", e) async def validate_indices(self) -> None: """Validate Redis indices are properly populated""" @@ -542,7 +542,7 @@ async def run(self) -> None: # Generate and save report report = self.generate_report() - print("\n" + report) + logger.info("\n%s", report) # Save to file report_file = Path("/tmp/migration_validation_report.txt") diff --git a/autobot-infrastructure/shared/scripts/secrets_manager.py b/autobot-infrastructure/shared/scripts/secrets_manager.py index 1fa7ba84e..9d841802c 100644 --- a/autobot-infrastructure/shared/scripts/secrets_manager.py +++ b/autobot-infrastructure/shared/scripts/secrets_manager.py @@ -90,7 +90,7 @@ def __init__(self, secrets_dir: str = "data/secrets"): logger.info("🔐 AutoBot Secrets Manager initialized") logger.info(" Secrets Directory: [configured]") - logger.info(f" Indexed Secrets: {len(self.secrets_index)}") + logger.info(" Indexed Secrets: %s", len(self.secrets_index)) def print_header(self, title: str): """Print formatted header.""" @@ -172,7 +172,7 @@ def _log_audit_event( audit_event = { "timestamp": datetime.now().isoformat(), "action": action, - "secret_id": secret_id, + "secret_id": secret_id or "", # Full ID preserved for audit traceability "scope": scope, "chat_id": chat_id, "details": details, @@ -294,7 +294,9 @@ def get_secret(self, secret_id: str, chat_id: str = None) -> Optional[str]: # Load and decrypt secret secret_file = self.secrets_dir / f"{secret_id}.secret" if not secret_file.exists(): - self.print_step(f"Secret file not found: {secret_id}", "error") + self.print_step( + f"Secret file not found: {secret_id[:8]}...", "error" + ) return None with open(secret_file, "rb") as f: @@ -371,7 +373,7 @@ def update_secret( ) -> bool: """Update an existing secret.""" if secret_id not in self.secrets_index["secrets"]: - self.print_step(f"Secret not found: {secret_id}", "error") + self.print_step(f"Secret not found: {secret_id[:8]}...", "error") return False secret_metadata = self.secrets_index["secrets"][secret_id] @@ -422,7 +424,7 @@ def delete_secret(self, secret_id: str, chat_id: str = None) -> bool: # Thread-safe read of metadata with self._index_lock: if secret_id not in self.secrets_index["secrets"]: - self.print_step(f"Secret not found: {secret_id}", "error") + self.print_step(f"Secret not found: {secret_id[:8]}...", "error") return False secret_metadata = self.secrets_index["secrets"][secret_id].copy() secret_scope = secret_metadata["scope"] @@ -476,7 +478,9 @@ def transfer_secret_to_general(self, secret_id: str, chat_id: str) -> bool: # Thread-safe read and validation with self._index_lock: if secret_id not in self.secrets_index["secrets"]: - self.print_step(f"Secret not found: {secret_id}", "error") + self.print_step( + f"Secret not found: {secret_id[:8]}...", "error" + ) return False secret_metadata = self.secrets_index["secrets"][secret_id] @@ -486,7 +490,7 @@ def transfer_secret_to_general(self, secret_id: str, chat_id: str) -> bool: # Verify it's a chat-scoped secret from the correct chat if secret_scope != SecretScope.CHAT or secret_chat_id != chat_id: self.print_step( - f"Cannot transfer: not a chat-scoped secret from chat {chat_id}", + "Cannot transfer: not a chat-scoped secret from this chat", "error", ) return False diff --git a/autobot-infrastructure/shared/scripts/setup/analytics/seq_auth_setup.py b/autobot-infrastructure/shared/scripts/setup/analytics/seq_auth_setup.py index f5d5bb097..34a957036 100644 --- a/autobot-infrastructure/shared/scripts/setup/analytics/seq_auth_setup.py +++ b/autobot-infrastructure/shared/scripts/setup/analytics/seq_auth_setup.py @@ -45,7 +45,8 @@ def create_seq_api_key( try: # First, try to login to get session - login_data = {"Username": username, "Password": password} + # CodeQL: false positive — password must be sent to Seq login API + login_data = {"Username": username, "Password": password} # noqa: S106 response = session.post(f"{seq_url}/api/users/login", json=login_data) if response.status_code == 200: diff --git a/autobot-infrastructure/shared/scripts/setup/analytics/setup_seq_analytics.py b/autobot-infrastructure/shared/scripts/setup/analytics/setup_seq_analytics.py index 95c535a29..453185556 100644 --- a/autobot-infrastructure/shared/scripts/setup/analytics/setup_seq_analytics.py +++ b/autobot-infrastructure/shared/scripts/setup/analytics/setup_seq_analytics.py @@ -18,6 +18,7 @@ import argparse import json +import os import sys from datetime import datetime from pathlib import Path @@ -35,14 +36,14 @@ def __init__( self, seq_url: str = "http://localhost:5341", username: str = "admin", - password: str = "Autobot123!", + password: str = "", ): """Initialize Seq analytics setup with connection credentials.""" self.seq_url = seq_url.rstrip("/") self.username = username - self.password = password + self.password = password or os.environ.get("SEQ_PASSWORD", "") self.session = requests.Session() - self.session.auth = (username, password) + self.session.auth = (username, self.password) # Load queries configuration self.config_file = Path(__file__).parent.parent / "config" / "seq-queries.json" @@ -440,7 +441,11 @@ def main(): "--seq-url", default="http://localhost:5341", help="Seq server URL" ) parser.add_argument("--username", default="admin", help="Seq username") - parser.add_argument("--password", default="Autobot123!", help="Seq password") + parser.add_argument( + "--password", + default=os.environ.get("SEQ_PASSWORD", ""), + help="Seq password (default: $SEQ_PASSWORD)", + ) args = parser.parse_args() diff --git a/autobot-infrastructure/shared/scripts/utilities/validate-security-fixes.py b/autobot-infrastructure/shared/scripts/utilities/validate-security-fixes.py index cba5cd98a..ea6448829 100644 --- a/autobot-infrastructure/shared/scripts/utilities/validate-security-fixes.py +++ b/autobot-infrastructure/shared/scripts/utilities/validate-security-fixes.py @@ -54,7 +54,7 @@ def _parse_rg_output(self, stdout: str, description: str) -> List[Dict]: "type": description, "file": file_path, "line": line_num, - "content": content.strip(), + "content": "[REDACTED — potential secret detected]", } ) return findings diff --git a/autobot-npu-worker/resources/windows-npu-worker/app/utils/redis_client.py b/autobot-npu-worker/resources/windows-npu-worker/app/utils/redis_client.py index b96a60f8f..cd07452a3 100644 --- a/autobot-npu-worker/resources/windows-npu-worker/app/utils/redis_client.py +++ b/autobot-npu-worker/resources/windows-npu-worker/app/utils/redis_client.py @@ -155,7 +155,8 @@ def _extract_config_params(self) -> dict: tls_enabled = self.redis_config.get("tls_enabled", False) return { "host": self.redis_config.get("host", "localhost"), - "password": self.redis_config.get("password"), + # CodeQL: false positive — password must be passed to Redis connection + "password": self.redis_config.get("password"), # noqa: S105 "db": self.redis_config.get("db", 0), "max_connections": self.redis_config.get("max_connections", 20), "socket_timeout": self.redis_config.get("socket_timeout", 5), @@ -189,7 +190,8 @@ def _build_base_pool_kwargs(self, config_params: dict) -> dict: return { "host": config_params["host"], "port": config_params["port"], - "password": config_params["password"], + # CodeQL: false positive — password required for Redis auth + "password": config_params["password"], # noqa: S105 "db": config_params["db"], "max_connections": config_params["max_connections"], "socket_timeout": config_params["socket_timeout"],