Skip to content

Conversation

@cadenkoj
Copy link
Owner

@cadenkoj cadenkoj commented May 22, 2025

chore(env): provide detailed comments

fix(db): use relative migrations path

chore(db): safely drop tables on down

fix(api): minimise lock contention

chore: refactor

fix: sort tags when computing id hash

fix(db): handle insert conflicts, secure debug logs

fix(crypto): set keyfile permissions

fix(crypto): handle missing or corrupt keyfiles

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling and robustness for encryption, decryption, and key management, replacing panics and string errors with structured error types.
    • Enhanced key file security by enforcing strict file permissions.
  • New Features

    • Deterministic UUID generation for indicators by sorting tags before hashing.
    • Partial success handling for indicator processing, allowing continued operation when some insertions fail.
  • Chores

    • Updated environment variable configuration for unified logging and clearer documentation.
    • Changed migration and configuration paths for better portability.
    • Improved and clarified logging messages throughout the application.

@coderabbitai
Copy link

coderabbitai bot commented May 22, 2025

Walkthrough

This update introduces a new RUST_LOG environment variable for unified logging configuration and updates related references in .env.example. It enhances file permission security and error handling in cryptographic key management, improves deterministic UUID computation, refines logging and error types, and adjusts database conflict handling and migration scripts.

Changes

File(s) Change Summary
.env.example Added RUST_LOG="info" variable, updated DTIM__DEFAULT__LOG_LEVEL to reference RUST_LOG, and clarified comments for database-related variables.
diesel.toml Changed Diesel migration directory from an absolute to a relative path.
migrations/2025-05-21-234457_create_encrypted_indicators/down.sql Added IF EXISTS and CASCADE to the DROP TABLE statement for safer, more robust migration rollback.
src/api.rs Modified gossip_indicators_handler to decrypt all indicators, log errors instead of failing on partial insertions, and increment success count only for successful insertions.
src/crypto/mesh_identity.rs Updated key file creation to use OpenOptions with secure file permissions (0o600) for private/public keys.
src/crypto/symmetric_key_manager.rs Improved key file handling, error checking, and file permissions; changed generate_key to return Result, removed save_keys, integrated its logic elsewhere, and improved nonce validation in decryption.
src/logging.rs Simplified trait import for logger implementation by importing Log directly, removing the need for log:: prefix.
src/models.rs Sorted tags before hashing for deterministic UUIDs; replaced panics and string errors with structured std::io::Error in compute_id, encrypt, and decrypt methods for improved error handling.
src/node.rs Used Diesel's ON CONFLICT DO NOTHING for indicator insertion, improved logging, added a FIXME for future upsert logic, and standardized error types in indicator listing.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API
    participant Node
    participant Logger

    Client->>API: Submit encrypted indicators
    API->>API: Decrypt all indicators, filter failures
    API->>Logger: Log decryption errors (if any)
    loop For each decrypted indicator
        API->>Node: Attempt to add/increment indicator
        alt Success
            API->>API: Increment success count
        else Failure
            API->>Logger: Log insertion error
        end
    end
    API-->>Client: Return count of successful insertions
Loading

Possibly related PRs

  • chore(lint): fix linter warnings #18: Both PRs modify the .env.example file, specifically around the logging configuration, showing a direct connection in environment variable management.

Poem

🐇
In the warren, logs now sing,
With RUST_LOG set for everything.
Keys are safe with permissions tight,
Errors handled left and right.
Indicators sorted, UUIDs true—
Hopping forward, code anew!

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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
Owner Author

cadenkoj commented May 22, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@cadenkoj cadenkoj changed the title chore(env): provide detailed comments fix: issues with database implementation May 22, 2025
@cadenkoj cadenkoj marked this pull request as ready for review May 22, 2025 04:37
Copy link
Owner Author

cadenkoj commented May 22, 2025

Merge activity

  • May 22, 4:38 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 22, 4:39 AM UTC: Graphite rebased this pull request as part of a merge.
  • May 22, 4:41 AM UTC: @cadenkoj merged this pull request with Graphite.

@cadenkoj cadenkoj changed the base branch from 05-21-feat_db_rough_database_implementation to graphite-base/20 May 22, 2025 04:38
@cadenkoj cadenkoj changed the base branch from graphite-base/20 to main May 22, 2025 04:38
@cadenkoj cadenkoj merged commit 5065742 into main May 22, 2025
1 of 2 checks passed
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
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f670038 and 013ca14.

📒 Files selected for processing (9)
  • .env.example (1 hunks)
  • diesel.toml (1 hunks)
  • migrations/2025-05-21-234457_create_encrypted_indicators/down.sql (1 hunks)
  • src/api.rs (1 hunks)
  • src/crypto/mesh_identity.rs (2 hunks)
  • src/crypto/symmetric_key_manager.rs (5 hunks)
  • src/logging.rs (2 hunks)
  • src/models.rs (3 hunks)
  • src/node.rs (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/api.rs (3)
src/node.rs (1)
  • indicators (186-189)
src/crypto/symmetric_key_manager.rs (1)
  • decrypt (114-138)
src/models.rs (1)
  • decrypt (103-118)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-test-lint
🔇 Additional comments (23)
diesel.toml (1)

9-9: Excellent improvement: switched to relative path for migrations

Changing from an absolute path to a relative path makes the configuration portable across different development environments. This prevents path-related issues when different team members work on the project.

src/crypto/mesh_identity.rs (2)

5-5: Good imports to support secure file operations

The imports correctly include the necessary components for file operations with specific permissions.

Also applies to: 7-7


52-65:

Details

✅ Verification successful

Excellent security improvement: restricted file permissions for key files

Setting file permissions to mode 0o600 (owner read/write only) ensures that cryptographic key material is accessible only to the process owner, which is a crucial security practice.


🏁 Script executed:

#!/bin/bash
# Check if this implementation might have issues on non-Unix platforms
echo "Checking for Windows-specific handling for file permissions:"
rg -A 5 "OpenOptionsExt" --glob "!**/mesh_identity.rs" -C 5

Length of output: 991


Consistent Unix file-permission handling confirmed

Setting mode 0o600 for the private and public key files is a strong security improvement and aligns with the existing use of std::os::unix::fs::OpenOptionsExt in symmetric_key_manager.rs. There are no new cross-platform concerns beyond those already present.

src/logging.rs (2)

4-4: Clean import organization

Explicitly importing the Log trait improves code readability.


109-109: Code cleanup: simplified trait implementation

Removing the log:: prefix makes the code cleaner while maintaining the same functionality.

.env.example (3)

2-3: Good addition: centralized logging configuration

Adding a standardized RUST_LOG environment variable enables consistent application-level logging and follows Rust ecosystem conventions.


6-6: Smart configuration: unified log level reference

Referencing RUST_LOG from DTIM__DEFAULT__LOG_LEVEL creates a single source of truth for log level configuration.


9-9: Improved documentation: clearer database configuration guidance

The enhanced comments provide better guidance for users, especially regarding password usage in production and the relationship between different database connection strings.

Also applies to: 11-11

migrations/2025-05-21-234457_create_encrypted_indicators/down.sql (1)

1-1: Improved database safety with IF EXISTS and CASCADE

The addition of IF EXISTS prevents errors when the table doesn't exist, and CASCADE properly handles dependent objects during table removal. This makes the migration more robust during rollbacks.

src/api.rs (2)

203-206: Improved error handling for indicator decryption

The change properly filters out indicators that fail to decrypt instead of potentially crashing the entire process. This gracefully handles decryption failures while still processing valid indicators.


209-213: Better error resilience in indicator processing

The code now continues processing remaining indicators even when some fail to insert, logging errors instead of failing the entire batch. This improves system resilience by allowing partial success instead of complete failure.

src/crypto/symmetric_key_manager.rs (5)

4-6: Added imports for secure file operations

These imports support the secure file permission controls added throughout the file.


30-39: Improved key loading with better error handling

The code now properly checks both file existence AND successful reading before using a key, with graceful fallback to key generation. This prevents using partially read or corrupted key files.


61-72: Enhanced key generation with secure file permissions

The function now creates key files with proper Unix permissions (0o600 = owner read/write only) using OpenOptions, significantly improving security by preventing other users from accessing the key files.


82-94: Secure handling of previous keys during rotation

Key rotation now properly sets secure permissions (0o600) for the previous key file and adds cleanup logic to remove stale files when appropriate. This maintains the security of key material throughout its lifecycle.


121-123: Added nonce validation to prevent cryptographic errors

Early validation of nonce length prevents cryptographic operation failures later in the process and provides a clear error message.

src/node.rs (3)

84-85: Added conflict handling for database insertions

The inclusion of on_conflict(id).do_nothing() prevents database errors when inserting duplicate indicators. This aligns with the changes in the API handler, which now logs errors instead of failing when indicators can't be inserted.

Also applies to: 89-93


96-99: Improved logging to prevent sensitive data exposure

The log message now only includes the indicator ID instead of the entire record, reducing the risk of sensitive data exposure in logs.


189-189: Standardized error handling with std::io::Error

The change from string errors to std::io::Error standardizes error handling across the codebase, making error propagation more consistent and providing better error context.

src/models.rs (4)

75-77: Great improvement for deterministic ID computation!

Sorting tags before hashing ensures consistent UUID generation regardless of the original tag order. This is a solid fix that prevents the same set of tags in different orders from producing different UUIDs.


88-89: Good error handling improvement.

Converting serialization failures into proper std::io::Error instances rather than panicking improves robustness. This change properly propagates errors to the caller, allowing for graceful error handling.


106-106: Well-executed error standardization.

The changes to the decrypt method correctly standardize error handling by:

  1. Changing the return type to consistently use std::io::Error
  2. Properly handling both decryption and deserialization errors with detailed error messages

This aligns with the PR objective of improving error handling throughout the codebase.

Also applies to: 113-117


65-82:

Details

✅ Verification successful

Verify consistent hash generation in other methods.

The compute_id method now properly sorts tags, but note that a similar pattern exists in the Hash implementation for ThreatIndicator (lines 258-275). Confirm that both implementations are consistent.


🏁 Script executed:

#!/bin/bash
# Check if the Hash implementation for ThreatIndicator also sorts tags

echo "Checking Hash implementation in the same file..."
# The implementation does sort tags (lines 262-264)
cat src/models.rs | awk 'NR>=258 && NR<=275'

echo "Checking if sorting is used in all places that compute hashes from tags..."
rg -A 5 -B 5 "tags\.(\w+\.)*(sort|collect)" --type rust

Length of output: 2121


No action needed—tag sorting is consistent

Both compute_id and the std::hash::Hash implementation for ThreatIndicator sort tags lexicographically before hashing, ensuring identical ordering and consistent hash/UUID generation across methods.

Comment on lines +107 to +111
/// FIXME: `add_indicator` inserts unconditionally – handle primary-key clashes.
/// If an indicator with the same deterministic UUID already exists, this insertion will violate the primary-key constraint and bubble an error.
/// Possible solution:
/// Use ON CONFLICT (id) DO UPDATE (diesel::upsert) to increment sightings. (TODO: possibly make sightings unencrypted metadata, TBD)
/// Failing to do so exposes the API to 500s on legitimate duplicate submissions.
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Documented known issue with primary key conflicts

The detailed FIXME comment clearly explains the current limitation with indicator insertion and proposes a solution using Diesel's upsert functionality. This is good documentation for future improvements.

Consider implementing the suggested fix using Diesel's upsert to increment sightings on conflict, as this would further improve robustness:

- let res = diesel::insert_into(encrypted_indicators)
-     .values(&encrypted)
-     .returning(EncryptedIndicator::as_returning())
-     .get_result(&mut conn)?;
+ let res = diesel::insert_into(encrypted_indicators)
+     .values(&encrypted)
+     .on_conflict(id)
+     .do_update()
+     .set(ciphertext.eq(excluded(ciphertext))) // Update with the new values
+     .returning(EncryptedIndicator::as_returning())
+     .get_result(&mut conn)?;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/node.rs around lines 107 to 111, the current add_indicator function
inserts indicators unconditionally, causing primary-key conflicts and errors on
duplicates. To fix this, refactor the insertion logic to use Diesel's upsert
feature with ON CONFLICT (id) DO UPDATE, incrementing the sightings count
instead of failing. This will prevent 500 errors on duplicate submissions and
improve API robustness.

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.

2 participants