Skip to content
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

feat: add encryption while storing configuration values #326

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

Harish-osmosys
Copy link
Contributor

@Harish-osmosys Harish-osmosys commented Sep 23, 2024

API PR Checklist

Pre-requisites

  • I have gone through the Contributing guidelines for Submitting a Pull Request (PR) and ensured that this is not a duplicate PR.
  • I have performed unit testing for the new feature added or updated to ensure the new features added are working as expected.
  • I have added/updated test cases to the test suite as applicable.
  • I have performed preliminary testing using the test suite to ensure that any existing features are not impacted and any new features are working as expected as a whole.
  • I have added/updated the required api docs as applicable.
  • I have added/updated the .env.example file with the required values as applicable.

PR Details

PR details have been updated as per the given format (see below)

  • PR title adheres to the format specified in guidelines (e.g., feat: add admin login endpoint)
  • Description has been added
  • Related changes have been added (optional)
  • Screenshots have been added (optional)
  • Query request and response examples have been added (as applicable, in case added or updated)
  • Documentation changes have been listed (as applicable)
  • Test suite/unit testing output is added (as applicable)
  • Pending actions have been added (optional)
  • Any other additional notes have been added (optional)

Additional Information

  • Appropriate label(s) have been added (ready for review should be added if the PR is ready to be reviewed)
  • Assignee(s) and reviewer(s) have been added (optional)

Note: Reviewer should ensure that the checklist and description have been populated and followed correctly, and the PR should be merged only after resolving all conversations and verifying that CI checks pass.


Description:

This Pr udpate the storing method for the configuration

  • Encrypt the configuration before storing in the db
  • Decrypt the configuration before using in the notification sending

Related changes:

  • Update env file
  • Added changes in the .env.example

Screenshots:

image

Query request and response:

NA

Documentation changes:

NA

Test suite/unit testing output:

NA

Pending actions:

NA

Additional notes:

NA

Summary by CodeRabbit

  • New Features

    • Introduced encryption and decryption functionality for provider configurations, enhancing data security.
    • Added configuration parameters for cryptography in the environment setup.
    • Implemented utility functions for encrypting and decrypting text.
  • Documentation

    • Updated the .env.example file to include new cryptographic configuration variables.

@Harish-osmosys Harish-osmosys self-assigned this Sep 23, 2024
Copy link

coderabbitai bot commented Sep 23, 2024

Walkthrough

The changes introduce new cryptographic configurations and functionalities across several files. The .env.example file now includes entries for encryption parameters, specifically ALGORITHM and KEY. A new utility file, crypto.utils.ts, provides methods for encrypting and decrypting data. Additionally, the ProvidersService class has been updated to utilize these encryption and decryption methods, enhancing the handling of sensitive provider configurations.

Changes

File Path Change Summary
apps/api/.env.example Added new configuration variables: ALGORITHM and KEY for cryptographic operations.
apps/api/src/config/crypto.utils.ts Introduced utility functions encrypt(text: string): string and decrypt(text: string): string for encryption and decryption.
apps/api/src/modules/providers/providers.service.ts Updated methods createProvider and getConfigById to include encryption and decryption of provider configurations.

Possibly related PRs

  • feat: add encryption for api keys #331: The changes in this PR involve the addition of encryption for API keys, which is directly related to the cryptographic enhancements introduced in the main PR, specifically the new utility functions for encryption and decryption in crypto.utils.ts.

Poem

🐇 In a garden of code, where secrets do bloom,
A rabbit hops lightly, dispelling the gloom.
With keys and with IVs, we dance in delight,
Encrypting our treasures, keeping them tight.
So here’s to the changes, both clever and bright,
A hop and a skip, all feels just right! 🌟


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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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: 6

Outside diff range and nitpick comments (3)
apps/api/src/config/crypto.utils.ts (1)

1-25: Overall assessment: Functional but needs security improvements

The implementation provides basic encryption and decryption functionality, which aligns with the PR objective of enhancing security for storing configuration values. However, there are several areas where the code can be improved to enhance security and adhere to best practices:

  1. Use dependency injection for ConfigService instead of direct instantiation.
  2. Generate a unique IV for each encryption operation instead of using a constant IV.
  3. Implement error handling in both encrypt and decrypt functions.
  4. Add input validation in the decrypt function.
  5. Consider using a more secure key derivation method if the key is derived from a password.

Additionally, ensure that the ALGORITHM, KEY, and IV environment variables are properly set and kept secure. The .env.example file should be updated to reflect these new required variables without exposing actual secret values.

To further improve the security of this implementation:

  1. Consider using a key management service (KMS) for handling encryption keys.
  2. Implement key rotation mechanisms to periodically update encryption keys.
  3. Use authenticated encryption (e.g., AES-GCM) to provide integrity checks along with confidentiality.
apps/api/src/modules/providers/entities/provider.entity.ts (1)

Line range hint 1-77: Summary and Final Recommendations

The changes to the Provider entity align with the PR objective of adding encryption for configuration values. However, there are several areas that need attention to ensure a robust and maintainable implementation:

  1. Encryption/Decryption Process: Implement and document the encryption/decryption process, possibly in a separate service.
  2. Data Validation: Add custom validators to ensure data integrity of the encrypted string.
  3. Documentation: Update API documentation and add explanatory comments in the code.
  4. Data Migration: Create a migration script for existing data.
  5. Code Updates: Modify all code that interacts with the configuration property to handle the new string format.
  6. GraphQL Schema: Update the schema and inform API consumers of the changes.
  7. Performance: Assess the performance impact of the encryption/decryption process.

Consider creating a separate EncryptedConfiguration type or class to encapsulate the encryption/decryption logic and provide a clean interface for working with encrypted configurations. This would help maintain separation of concerns and make the codebase more maintainable.

Please address these points to ensure a successful implementation of the encrypted configuration feature.

apps/api/src/modules/providers/providers.service.ts (1)

57-58: LGTM: Configuration encryption implemented.

The implementation correctly encrypts the provider configuration before saving, which aligns with the PR objective of enhancing security.

Consider adding a comment explaining why the configuration is being encrypted, for better code readability:

+    // Encrypt the configuration to enhance security before storing in the database
     providerInput.configuration = encrypt(JSON.stringify(providerInput.configuration));
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6e51145 and 01400b6.

Files selected for processing (4)
  • apps/api/.env.example (1 hunks)
  • apps/api/src/config/crypto.utils.ts (1 hunks)
  • apps/api/src/modules/providers/entities/provider.entity.ts (2 hunks)
  • apps/api/src/modules/providers/providers.service.ts (3 hunks)
Additional comments not posted (4)
apps/api/src/modules/providers/entities/provider.entity.ts (2)

41-43: Consider broader implications of changing configuration type

The modification of the configuration property from a JSON object to a string has several important implications that should be addressed:

  1. Data Migration: Existing data in the database will need to be migrated. Ensure there's a migration script to encrypt existing configuration data.

  2. Code Updates: Any code that directly accesses or manipulates the configuration as an object will need to be updated to handle encryption/decryption.

  3. GraphQL Schema: The GraphQL schema will change, potentially breaking existing queries or mutations. Update the schema and inform API consumers of this change.

  4. Performance and Storage: Evaluate the impact on application performance (due to encryption/decryption overhead) and storage requirements.

Consider the following actions:

  1. Create a data migration script to handle existing data.
  2. Update all services and resolvers that interact with the configuration property.
  3. Revise GraphQL documentation and inform API consumers about the change.
  4. Perform benchmarks to assess performance impact.

To identify affected areas, run the following commands:

#!/bin/bash
# Find GraphQL operations involving provider configuration
rg "configuration.*provider" --type graphql

# Find TypeScript files that might need updating
rg "provider.*configuration" --type typescript

Review the results to ensure all affected areas are properly updated.


41-43: Encryption implementation needs clarification and additional safeguards

The changes to the configuration property align with the PR objective of adding encryption for configuration values. However, there are some areas that need attention:

  1. The encryption process is not explicitly shown in this file. Consider adding a comment to explain that the stored string is an encrypted value.
  2. There's no indication of how decryption will be handled when the configuration is needed. This should be addressed in the service layer.
  3. As per the PR objectives, the API documentation should be updated to reflect these changes. Consider adding JSDoc comments to explain the encryption.
  4. To ensure data integrity, consider adding a custom validator to check if the stored string is a valid encrypted value.

Here's a suggested improvement:

import { IsString } from 'class-validator';
import { IsEncryptedValue } from '../validators/is-encrypted-value.validator'; // You'll need to create this custom validator

// ...

/**
 * @field configuration
 * @description Encrypted configuration string for the provider.
 * This value is encrypted before storage and must be decrypted before use.
 */
@Column({ name: 'configuration' })
@Field(() => String, { description: 'Encrypted configuration string' })
@IsString()
@IsEncryptedValue() // Custom validator to ensure the value is properly encrypted
configuration: string;

To ensure this change doesn't break existing functionality, let's check for any direct access to the configuration property:

This will help identify any places where decryption might need to be added.

Verification successful

No direct access to provider.configuration found

The search did not reveal any direct access to the configuration property outside of the Provider entity. This suggests that the encryption implementation is correctly encapsulated.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for direct access to provider.configuration
rg "provider\.configuration" --type typescript

Length of output: 161


Script:

#!/bin/bash
# Search for direct access to provider.configuration in TypeScript files
rg "provider\.configuration" --type-add "custom_ts:*.ts" -t custom_ts

# Optionally, search in GraphQL files if relevant
rg "provider\.configuration" --type-add "custom_gql:*.graphql" -t custom_gql

Length of output: 270


Script:

#!/bin/bash
# Search for direct access to provider.configuration in TypeScript files
rg "provider\.configuration" --glob "*.ts"

# Optionally, search in GraphQL files if relevant
rg "provider\.configuration" --glob "*.graphql"

Length of output: 243


Script:

#!/bin/bash
# Search for direct access to provider.configuration in TypeScript and GraphQL files
rg "provider\\.configuration" -g "*.ts" -g "*.graphql"

Length of output: 55

apps/api/src/modules/providers/providers.service.ts (2)

13-13: LGTM: Crypto utility import added.

The import of decrypt and encrypt functions is correctly added and necessary for the new encryption functionality.


Line range hint 1-101: Overall implementation aligns well with PR objectives.

The changes in this file successfully implement encryption for provider configurations, enhancing the security of stored data. The implementation includes:

  1. Proper import of encryption utilities.
  2. Encryption of configuration data before storage in createProvider.
  3. Decryption of configuration data when retrieving in getConfigById.

These changes align well with the stated PR objective of enhancing the security of configuration values by implementing encryption before storage and decryption when needed.

To ensure that the encryption is used consistently throughout the codebase, please run the following verification script:

This script will help identify any places in the codebase where the new encryption might need to be applied or where decryption might be necessary when accessing provider configurations.

apps/api/.env.example Outdated Show resolved Hide resolved
apps/api/src/config/crypto.utils.ts Show resolved Hide resolved
apps/api/src/config/crypto.utils.ts Outdated Show resolved Hide resolved
apps/api/src/config/crypto.utils.ts Outdated Show resolved Hide resolved
apps/api/src/config/crypto.utils.ts Outdated Show resolved Hide resolved
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

🧹 Outside diff range and nitpick comments (1)
apps/api/src/modules/providers/providers.service.ts (1)

Line range hint 48-65: Add test coverage for encryption workflow.

The encryption/decryption implementation looks solid, but test coverage is crucial for security-related changes. Please add test cases to verify:

  1. Configuration is properly encrypted during creation
  2. Encrypted configuration can be successfully decrypted
  3. Invalid configurations are handled appropriately

Would you like me to help generate test cases for these scenarios?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between dcfaaa3 and 27a155f.

📒 Files selected for processing (2)
  • apps/api/.env.example (1 hunks)
  • apps/api/src/modules/providers/providers.service.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/api/.env.example
🧰 Additional context used
📓 Learnings (1)
apps/api/src/modules/providers/providers.service.ts (4)
Learnt from: Harish-osmosys
PR: OsmosysSoftware/osmo-x#326
File: apps/api/src/modules/providers/providers.service.ts:70-74
Timestamp: 2024-10-08T17:27:46.182Z
Learning: The `encrypt` and `decrypt` functions already handle exceptions internally, so additional error handling when using them is unnecessary.
Learnt from: Harish-osmosys
PR: OsmosysSoftware/osmo-x#326
File: apps/api/src/modules/providers/providers.service.ts:70-74
Timestamp: 2024-10-08T17:27:47.563Z
Learning: The `encrypt` and `decrypt` functions already handle exceptions internally, so additional error handling when using them is unnecessary.
Learnt from: Harish-osmosys
PR: OsmosysSoftware/osmo-x#326
File: apps/api/src/modules/providers/providers.service.ts:70-74
Timestamp: 2024-10-08T17:27:45.631Z
Learning: The `encrypt` and `decrypt` functions already handle exceptions internally, so additional error handling when using them is unnecessary.
Learnt from: Harish-osmosys
PR: OsmosysSoftware/osmo-x#326
File: apps/api/src/modules/providers/providers.service.ts:70-74
Timestamp: 2024-09-23T08:40:04.066Z
Learning: The `encrypt` and `decrypt` functions already handle exceptions internally, so additional error handling when using them is unnecessary.
🔇 Additional comments (3)
apps/api/src/modules/providers/providers.service.ts (3)

13-13: LGTM: Crypto utility import added correctly.


48-49: Verify database column capacity for encrypted data.

While the encryption implementation looks good, please ensure:

  1. The database column for configuration can accommodate the increased size of encrypted data
  2. Consider adding validation for the configuration structure before encryption

Let's check the database schema for the configuration column:

#!/bin/bash
# Search for the Provider entity definition and table schema
ast-grep --pattern 'class Provider {
  $$$
  configuration: $_
  $$$
}'

61-65: Verify centralized configuration access.

The decryption implementation looks good. As previously discussed, we need to ensure all configuration access goes through this method to maintain security.

Let's verify this:

✅ Verification successful

Let me generate additional verification scripts to check for any direct configuration access patterns:


Let me try one final verification with corrected patterns:


Based on the verification results, I can now provide the final response:

Configuration access is properly centralized through getConfigById

The verification confirms that:

  • All provider services (SMTP, SNS, Twilio, etc.) consistently use getConfigById to access configurations
  • The configuration field is properly encapsulated in the entity and DTO layers
  • No direct access to configuration data outside the providers service
  • No bypass of the decryption mechanism
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for direct access to provider configuration
rg -g '!*.test.*' -g '!*.spec.*' "configuration.*provider" 

# Search for getConfigById usage
rg -g '!*.test.*' -g '!*.spec.*' "getConfigById"

Length of output: 2514


Script:

#!/bin/bash
# Search for direct configuration access patterns
rg -g '!*.test.*' -g '!*.spec.*' "configEntity\.configuration|provider.*configuration\s*=|configuration:\s*{" -A 2

# Search for any database queries that might bypass the service
ast-grep --pattern 'findOne({
  where: {
    $$$
    configuration: $_
    $$$
  }
})'

Length of output: 417


Script:

#!/bin/bash
# Search for direct configuration access patterns with fixed regex
rg -g '!*.test.*' -g '!*.spec.*' "configEntity.configuration|configuration:" -A 2

# Search for repository usage to check database access
ast-grep --pattern 'class $_ {
  $$$
  configuration($$$) {
    $$$
  }
  $$$
}'

Length of output: 4828

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants