Skip to content

Conversation

@Anshgrover23
Copy link
Collaborator

@Anshgrover23 Anshgrover23 commented Jan 9, 2026

Related Issue

Closes #

Summary

  • Replaces plain-text API key storage in shell configs with Fernet-encrypted storage
  • API keys saved via first-run wizard now stored in ~/.cortex/environments/cortex.json
  • Updated API key detector to load from encrypted storage at startup
  • Encryption key stored with restricted permissions (chmod 600)

AI Disclosure

  • No AI used
  • AI/IDE/Agents used (please describe below)

Used Claude Code to implement the security fix.

Checklist

  • PR title follows format: type(scope): description or [scope] description
  • Tests pass (pytest tests/)
  • MVP label added if closing MVP issue
  • Update "Cortex -h" (if needed)

Summary by CodeRabbit

  • New Features

    • API keys can be saved to and loaded from encrypted persistent storage.
    • Detection now checks encrypted storage first when locating API keys.
  • Improvements

    • Better handling and messaging when encryption support is missing, with a fallback to session-only storage.
    • Added informational logging around encrypted storage operations.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 9, 2026

📝 Walkthrough

Walkthrough

Adds encrypted storage support for API keys: detection now checks secure encrypted storage before other sources; first-run wizard persists keys to encrypted storage via an environment manager with fallbacks when encryption support is unavailable.

Changes

Cohort / File(s) Summary
Encrypted API key handling
cortex/api_key_detector.py, cortex/first_run_wizard.py
Added _check_encrypted_storage() to APIKeyDetector and integrated it at the start of detection; added module logging. First-run wizard now uses get_env_manager().set_variable(..., encrypt=True) under CORTEX_APP_NAME to persist keys, normalizes provider names, logs success, and gracefully falls back to session-only when cryptography/env manager is unavailable or on errors.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as FirstRunWizard
  participant Detector as APIKeyDetector
  participant EnvMgr as EnvManager (encrypted store)
  participant Session as In-Memory Session

  CLI->>EnvMgr: set_variable(app="cortex", key=name, value, encrypt=true, desc)
  EnvMgr-->>CLI: success / error
  CLI->>Session: set session env var (always)

  Detector->>EnvMgr: read variable for provider (decrypt)
  EnvMgr-->>Detector: value / not found / error
  alt decrypted value returned
    Detector->>Session: set session env var
    Detector-->>CLI: return (found, provider, key, source="encrypted_storage")
  else not found or crypto missing
    Detector->>Detector: continue other checks (cached, saved provider, env, etc.)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

Suggested Reviewers

  • mikejmorgan-ai

Poem

🐰 I hid the keys where carrots dream,

encrypted beds beside the stream.
When crypto's present, snug they stay,
else in-session hops away. 🥕🔐

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: replacing plain-text API key storage with encrypted storage to address a security vulnerability (CWE-312).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description follows the required template with all essential sections: Related Issue, Summary, AI Disclosure, and Checklist. The description clearly explains the security fix objective, includes AI tool disclosure, and documents completed checklist items.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Jan 9, 2026

CLA Verification Passed

All contributors have signed the CLA.

Contributor Signed As
@Anshgrover23 @Anshgrover23
@Anshgrover23 @Anshgrover23

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Anshgrover23, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the security of API key storage by replacing plain-text storage in shell configs with Fernet-encrypted storage. It modifies the API key detection logic to prioritize the new encrypted storage location and gracefully handle cases where the cryptography package is not available. The first-run wizard now saves API keys to the encrypted storage, improving the overall security posture of the application.

Highlights

  • Security Enhancement: Implements Fernet encryption for storing API keys, addressing CWE-312 (Cleartext Storage of Sensitive Information).
  • Storage Location: API keys are now stored in ~/.cortex/environments/cortex.json instead of plain text in shell configuration files.
  • Key Management: The encryption key is stored with restricted permissions (chmod 600) to enhance security.
  • Detection Logic: Updated API key detection logic to prioritize encrypted storage and handle cases where the cryptography package is not installed.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great security improvement, replacing plaintext API key storage in shell configuration files with Fernet-encrypted storage. The changes in api_key_detector.py and first_run_wizard.py correctly implement reading from and writing to the new secure storage. The fallback mechanism for when the cryptography package is not installed is also well-handled. I've provided a couple of suggestions to improve maintainability by reducing code duplication and removing hardcoded strings. These changes will make the code cleaner and easier to manage in the future.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
cortex/api_key_detector.py (1)

133-159: Consider extracting the hardcoded app name to a constant.

The app name "cortex" is hardcoded on line 146, while first_run_wizard.py defines CORTEX_APP_NAME = "cortex" as a constant. For consistency and maintainability, consider defining this constant in api_key_detector.py at the module level alongside other app-related constants.

♻️ Suggested refactor

Add a module-level constant after line 42 with other constants:

 CORTEX_CACHE_FILE = ".api_key_cache"
+
+# Application name for encrypted storage
+CORTEX_APP_NAME = "cortex"

Then use it in the method:

-                value = env_mgr.get_variable(app="cortex", key=env_var, decrypt=True)
+                value = env_mgr.get_variable(app=CORTEX_APP_NAME, key=env_var, decrypt=True)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f248e9 and 32b13fc.

📒 Files selected for processing (2)
  • cortex/api_key_detector.py
  • cortex/first_run_wizard.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Follow PEP 8 style guide
Type hints required in Python code
Docstrings required for all public APIs

Files:

  • cortex/api_key_detector.py
  • cortex/first_run_wizard.py
🧬 Code graph analysis (1)
cortex/first_run_wizard.py (2)
tests/test_env_manager.py (1)
  • env_manager (63-67)
cortex/env_manager.py (3)
  • get_env_manager (1108-1110)
  • set_variable (689-738)
  • encrypt (502-514)
🔇 Additional comments (7)
cortex/api_key_detector.py (3)

26-26: Good addition of logging support.

The logging setup follows Python best practices and will be useful for debugging the new encrypted storage detection path.

Also applies to: 34-34


10-16: Documentation accurately reflects the new detection order.

The docstrings clearly document that encrypted storage is checked as the third-highest priority source, and the implementation matches this specification.

Also applies to: 81-87


105-108: Correct integration of encrypted storage check in detection flow.

The encrypted storage check is properly positioned in the detection priority order, running after environment variables but before cached keys. This ensures that securely stored keys are used when available.

cortex/first_run_wizard.py (4)

22-22: Good addition of constant for app name.

Defining CORTEX_APP_NAME as a module-level constant is a best practice and improves maintainability. The import of get_env_manager is correctly placed at the module level.

Also applies to: 26-27


793-823: Excellent error handling and graceful degradation.

The method properly handles the case where the cryptography package is not installed (ImportError) and other potential failures, always falling back to setting the variable in the current session. This ensures the wizard doesn't break even if encrypted storage is unavailable.

The implementation correctly uses the EnvironmentManager API and sets appropriate encryption and metadata parameters.


327-327: Call sites remain unchanged due to backward-compatible method signature.

The refactored _save_env_var method maintains the same signature, so existing calls continue to work without modification. This is good design for maintainability.

Also applies to: 348-348


807-807: Minor issue with description string formatting.

The description generation on line 807 produces slightly odd capitalization. For example, "ANTHROPIC_API_KEY" becomes "API key for Anthropic Api Key" where "Api Key" is incorrectly title-cased.

🐛 Proposed fix for description formatting
-                description=f"API key for {name.replace('_API_KEY', '').replace('_', ' ').title()}",
+                description=f"API key for {name.replace('_API_KEY', '').replace('_', ' ').lower().capitalize()}",

Or for better formatting:

-                description=f"API key for {name.replace('_API_KEY', '').replace('_', ' ').title()}",
+                provider_name = name.replace('_API_KEY', '').lower().replace('_', ' ').title()
+                description=f"API key for {provider_name}",

This would produce "API key for Anthropic" instead of "API key for Anthropic Api Key".

Likely an incorrect or invalid review comment.

@Anshgrover23
Copy link
Collaborator Author

@Suyashd999 Can I get a review on this one ?

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 9, 2026

@mikejmorgan-ai mikejmorgan-ai self-assigned this Jan 10, 2026
@Anshgrover23 Anshgrover23 merged commit 8676bb2 into cortexlinux:main Jan 10, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants