Skip to content

feat: add encryption support #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 31, 2024
Merged

feat: add encryption support #20

merged 4 commits into from
Aug 31, 2024

Conversation

WHALEEYE
Copy link
Contributor

@WHALEEYE WHALEEYE commented Aug 29, 2024

Add encryption support for communication between client and server. User can enable encryption by setting env variable CRAB_ENC_KEY.

Summary by CodeRabbit

  • New Features

    • Introduced conditional encryption and decryption for action data in the environment, enhancing security.
    • Updated the API to support dual response mechanisms based on the presence of an encryption key.
    • Added a new utilities module for base64 encoding/decoding and encryption functionalities.
  • Bug Fixes

    • Improved response handling in the API to ensure correct processing of encrypted content.
  • Tests

    • Added unit tests to validate encryption and decryption functionalities, ensuring reliability.
    • Enhanced test structure for the API to cover both encrypted and unencrypted scenarios.
  • Chores

    • Included a new dependency for cryptographic functionalities in the project configuration.
    • Updated linting exclusions to improve code quality checks.

Copy link

coderabbitai bot commented Aug 29, 2024

Walkthrough

The changes introduce enhancements to the crab project by implementing encryption and decryption mechanisms for secure data handling. Key functionalities include conditional encryption in action handling, updates to the API for raw action processing, and the introduction of utility functions for encryption. A new dependency on the cryptography package is added, along with unit tests to validate the encryption processes.

Changes

Files Change Summary
crab/core/environment.py Added _enc_key for encryption; modified _action_endpoint for conditional encryption and decryption.
crab/server/api.py Updated raw_action endpoint to read raw content and conditionally decrypt or encrypt responses based on the key.
crab/utils/__init__.py Introduced file to initialize utilities; imported functions for base64 and encryption handling.
crab/utils/encryption.py Implemented AES 256 encryption functions: encrypt_message, decrypt_message, and generate_key_from_env.
pyproject.toml Added cryptography package dependency for cryptographic functionalities.
test/core/test_utils.py Created unit test test_encrypt_decrypt to validate encryption and decryption functionality.
test/server/test_api.py Replaced test_raw_action with test_raw_action_unencrypted and test_raw_action_encrypted; added mock_env fixture.
crab/agents/backend_models/camel_model.py Updated type annotations to use pipe (`

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API
    participant Environment
    participant Utils

    Client->>API: Send Action
    API->>Environment: Process Action
    Environment->>Utils: Encrypt Action Data (if key present)
    Utils-->>Environment: Encrypted Data
    Environment->>API: Send Encrypted Data
    API->>Client: Return Response
    Client->>API: Request Response
    API->>Environment: Process Response
    Environment->>Utils: Decrypt Response Data (if key present)
    Utils-->>Environment: Decrypted Data
    Environment->>API: Send Decrypted Data
    API->>Client: Return Decrypted Response
Loading

Poem

🐇 In the burrow deep, where secrets lie,
A key was found, oh my, oh my!
With whispers of code, the data's tight,
Encryption dances in the moonlight.
Hops of joy, let’s cheer and play,
For safety's here in a brand new way! 🌙✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 3f37965 and 34e17f6.

Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
Files selected for processing (6)
  • crab/core/environment.py (3 hunks)
  • crab/server/api.py (1 hunks)
  • crab/utils/init.py (1 hunks)
  • crab/utils/encryption.py (1 hunks)
  • pyproject.toml (1 hunks)
  • test/core/test_utils.py (1 hunks)
Additional comments not posted (14)
test/core/test_utils.py (3)

1-13: LGTM!

The copyright notice follows the Apache License, Version 2.0.

The code changes are approved.


16-18: LGTM!

The import statements are necessary for the test function.

The code changes are approved.


21-26: LGTM!

The test_encrypt_decrypt function is correctly implemented and tests the encryption and decryption process.

The code changes are approved.

crab/utils/__init__.py (3)

1-13: LGTM!

The copyright notice follows the Apache License, Version 2.0.

The code changes are approved.


15-25: LGTM!

The import statements are necessary for the public API.

The code changes are approved.


27-35: LGTM!

The __all__ list is correctly defined and includes all necessary functions.

The code changes are approved.

crab/server/api.py (2)

14-24: LGTM!

The import statements are necessary for the functionality of the raw_action endpoint.

The code changes are approved.


29-29: LGTM!

The ENC_KEY variable is necessary for encryption and decryption.

The code changes are approved.

crab/utils/encryption.py (3)

26-40: Ensure key length and add error handling.

The function is correctly implemented, but consider the following improvements:

  • Verify that the key length is 256 bits (32 bytes).
  • Add error handling for encryption failures.
 def encrypt_message(plaintext: str, key: bytes) -> str:
+    if len(key) != 32:
+        raise ValueError("Key must be 256 bits (32 bytes) long.")
     nounce = os.urandom(12)
     cipher = Cipher(algorithms.AES(key), modes.GCM(nounce), backend=default_backend())
     encryptor = cipher.encryptor()
     ciphertext = encryptor.update(plaintext.encode()) + encryptor.finalize()
     return base64.b64encode(nounce + ciphertext + encryptor.tag).decode("utf-8")

43-61: Ensure key length and add error handling.

The function is correctly implemented, but consider the following improvements:

  • Verify that the key length is 256 bits (32 bytes).
  • Add error handling for decryption failures.
 def decrypt_message(encrypted: str, key: bytes) -> str:
+    if len(key) != 32:
+        raise ValueError("Key must be 256 bits (32 bytes) long.")
     encrypted = base64.b64decode(encrypted)
     nounce = encrypted[:12]
     ciphertext = encrypted[12:-16]
     tag = encrypted[-16:]
     cipher = Cipher(
         algorithms.AES(key), modes.GCM(nounce, tag), backend=default_backend()
     )
     decryptor = cipher.decryptor()
     return (decryptor.update(ciphertext) + decryptor.finalize()).decode("utf-8")

64-77: Ensure secure handling of environment variable and add error handling.

The function is correctly implemented, but consider the following improvements:

  • Ensure that the environment variable is securely handled.
  • Add error handling for missing or invalid environment variables.
 def generate_key_from_env() -> Optional[bytes]:
     enc_key = os.environ.get("CRAB_ENC_KEY")
     if not enc_key:
         logger.warning("CRAB_ENC_KEY is not set, connection will not be encrypted.")
         return None
+    if len(enc_key) < 32:
+        logger.warning("CRAB_ENC_KEY is too short, it should be at least 32 characters long.")
+        return None
     return hashlib.sha256(enc_key.encode("utf-8")).digest()
pyproject.toml (1)

29-29: LGTM!

The addition of the cryptography dependency is appropriate for the encryption functionality.

The code changes are approved.

crab/core/environment.py (2)

95-96: LGTM!

The initialization of _enc_key using generate_key_from_env() is appropriate for the encryption functionality.

The code changes are approved.


218-241: Ensure correct application of encryption and decryption logic and add error handling.

The function is correctly implemented, but consider the following improvements:

  • Ensure that the encryption and decryption logic is correctly applied.
  • Add error handling for encryption and decryption failures.
 def _action_endpoint(self, action: Action, parameters: dict[str, Any]):
     if self._client is not None and not action.local:
         data = json.dumps(
             {
                 "action": action.to_raw_action(),
                 "parameters": action.parameters(**parameters).model_dump(),
             }
         )
         content_type = "application/json"
         if self._enc_key is not None:
             data = encrypt_message(data, self._enc_key)
             content_type = "text/plain"

         # send action to remote machine
         response = self._client.post(
             "/raw_action",
             content=data,
             headers={"Content-Type": content_type},
         )

         resp_content = response.content.decode("utf-8")
         if self._enc_key is not None:
             resp_content = decrypt_message(resp_content, self._enc_key)

         resp_json = json.loads(resp_content)
         return resp_json["action_returns"]
     else:
         # or directly execute it
         action = action.set_kept_param(env=self)
         return action.run(**parameters)

@dandansamax
Copy link
Collaborator

Overall it looks very good. We can consider add an API test for encrypt mode.

Ref:

https://github.com/camel-ai/crab/blob/main/test/server/test_api.py

@dandansamax
Copy link
Collaborator

dandansamax commented Aug 29, 2024

close #18

@WHALEEYE WHALEEYE linked an issue Aug 29, 2024 that may be closed by this pull request
1 task
@WHALEEYE WHALEEYE self-assigned this Aug 29, 2024
Copy link

@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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 34e17f6 and 440f46e.

Files selected for processing (3)
  • crab/server/api.py (2 hunks)
  • pyproject.toml (2 hunks)
  • test/server/test_api.py (2 hunks)
Files skipped from review as they are similar to previous changes (2)
  • crab/server/api.py
  • pyproject.toml
Additional comments not posted (4)
test/server/test_api.py (4)

15-18: LGTM!

The imports are necessary and correctly included.


27-33: LGTM!

The mock_env fixture is correctly implemented and promotes code reuse.


36-41: LGTM!

The test_raw_action_unencrypted function is correctly implemented and tests various scenarios with unencrypted actions.


44-50: LGTM!

The test_raw_action_encrypted function is correctly implemented and tests various scenarios with encrypted actions.

Copy link

@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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 440f46e and 48b6f4e.

Files selected for processing (1)
  • crab/agents/backend_models/camel_model.py (7 hunks)
Additional comments not posted (8)
crab/agents/backend_models/camel_model.py (8)

47-47: Type annotation updated to modern syntax.

The update from Union[ModelType, str] to ModelType | str aligns with the latest Python typing standards, enhancing readability and maintainability.


64-64: Updated type annotations in constructor.

The change from Optional[Dict[str, Any]] to dict[str, Any] | None in the constructor's parameters argument improves clarity and aligns with modern Python typing practices.


73-73: Type annotation for client attribute updated.

The update from Optional[ExternalToolAgent] to ExternalToolAgent | None for the client attribute is a positive change, enhancing type clarity and consistency.


85-85: Type annotation updated in reset method.

The change from Optional[List[Action]] to list[Action] | None for the action_space parameter in the reset method is a good practice, aligning with the newer Python typing conventions.


114-115: Updated return type annotation in _convert_action_to_schema.

The update from Optional[List[OpenAIFunction]] to list[OpenAIFunction] | None improves type clarity and aligns with modern Python typing standards.


121-121: Simplified list type annotation in _convert_tool_calls_to_action_list.

The change from List[ActionOutput] to list[ActionOutput] simplifies the type annotation and aligns with the newer, more readable Python typing conventions.


133-133: Updated parameter type annotation in chat method.

The change from List[Tuple[str, MessageType]] to list[tuple[str, MessageType]] in the messages parameter of the chat method enhances readability and consistency with modern Python typing practices.


135-135: Updated variable type annotation within chat method.

The update from List[Image.Image] to list[Image.Image] for the image_list variable within the chat method aligns with the latest Python typing conventions, improving clarity.

This reverts commit 48b6f4e.
@dandansamax dandansamax merged commit eb406b6 into main Aug 31, 2024
1 check passed
@dandansamax dandansamax deleted the feature/encryption branch August 31, 2024 20:31
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.

[Feature Request] Add authorization key in action execution network API
2 participants