Skip to content

Conversation

@NiveditJain
Copy link
Member

No description provided.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 5, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added secure secret management for nodes and graph templates, including encryption and API endpoints to retrieve secrets for states.
    • Introduced support for defining and injecting secrets into nodes at runtime using a dedicated schema.
    • Added new fields to API models and responses to reflect secret usage and graph template names.
    • Updated documentation with guidance on working with secrets.
  • Bug Fixes

    • Ensured that secret fields are validated and handled securely across API requests and database models.
  • Chores

    • Updated dependencies to include cryptography for encryption support.
    • Incremented SDK version to 0.0.7b3.

Walkthrough

This update introduces encrypted secret management to graph templates. It adds secret fields to request and response models, implements AES-GCM encryption/decryption utilities, and extends the graph template model with secret storage, validation, and accessor methods. The upsert controller is updated to handle secrets securely during graph template creation and update. Additionally, node registration now supports a secrets attribute with validation and response updates, and the SDK runtime enforces secret schema correctness. New API endpoints enable retrieval of secrets for states, and states now track the associated graph name.

Changes

Cohort / File(s) Change Summary
Controller Secret Handling
state-manager/app/controller/upsert_graph_template.py
Modifies upsert logic to set secrets before insert/update; response now returns a secrets presence map instead of raw names/namespace.
GraphTemplate Model Secret Support
state-manager/app/models/db/graph_template_model.py
Adds secrets field, validation, and methods for encrypted secret storage, retrieval, and validation using an encrypter utility.
Graph Template API Models
state-manager/app/models/graph_models.py
Adds secrets field to both request and response models; request uses Dict[str, str] and response uses Dict[str, bool].
Encryption Utility
state-manager/app/utils/encrypter.py
Introduces Encrypter class for AES-256-GCM encryption/decryption, including key management and encoding/decoding helpers.
Dependency Update
state-manager/pyproject.toml
Adds cryptography>=45.0.5 as a required dependency.
Node Registration Secret Support
state-manager/app/controller/register_nodes.py, state-manager/app/models/db/registered_node.py, state-manager/app/models/register_nodes_request.py, state-manager/app/models/register_nodes_response.py
Adds secrets field to node registration models and controller logic to handle secrets during node registration and response.
SDK Runtime Secret Validation
python-sdk/exospherehost/runtime.py
Extends node registration validation to require a Secrets class inheriting from pydantic.BaseModel with all string fields; adds secrets field in registration payload; fetches secrets at runtime and passes to node execution.
SDK BaseNode Secrets Placeholder
python-sdk/exospherehost/node/BaseNode.py
Adds a placeholder nested Secrets class in BaseNode as a pydantic model for future secret schema definitions; updates _execute to accept secrets.
Secrets Retrieval API
state-manager/app/controller/get_secrets.py, state-manager/app/routes.py
Adds new API endpoint to fetch secrets for a given state, with validation and error handling.
State Model Updates
state-manager/app/models/db/state.py, state-manager/app/models/create_models.py, state-manager/app/controller/create_states.py
Adds graph_name field to state models and ensures it is stored and returned in API responses.
Secrets Response Model
state-manager/app/models/secrets_response.py
Adds a Pydantic model for wrapping secrets dictionary in API responses.
Kubernetes Deployment Update
.github/workflows/deploy-kubernetes.yml
Adds SECRETS_ENCRYPTION_KEY as a secret in Kubernetes deployment workflow.
Python SDK Documentation
python-sdk/README.md
Adds documentation on working with secrets securely in nodes.
Version Bump
python-sdk/exospherehost/_version.py
Updates SDK version from 0.0.7b2 to 0.0.7b3.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller
    participant GraphTemplateModel
    participant Encrypter

    Client->>Controller: UpsertGraphTemplateRequest (with secrets)
    Controller->>GraphTemplateModel: set_secrets(body.secrets)
    GraphTemplateModel->>Encrypter: encrypt(secret_value) for each secret
    Encrypter-->>GraphTemplateModel: encrypted_secret
    Controller->>GraphTemplateModel: insert() or update()
    Controller->>GraphTemplateModel: get_secrets()
    GraphTemplateModel->>Encrypter: decrypt(encrypted_secret) for each secret
    Encrypter-->>GraphTemplateModel: secret_value
    Controller-->>Client: UpsertGraphTemplateResponse (secrets presence map)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Possibly related PRs

Poem

In burrows deep, a secret’s kept—
Now templates guard what once they wept.
With cryptic keys and ciphered lore,
The graphs are safer than before.
A hop, a skip, encryption done—
This rabbit’s work is never one!
🐇🔐

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15d4f72 and 509db82.

📒 Files selected for processing (2)
  • state-manager/app/controller/get_secrets.py (1 hunks)
  • state-manager/app/routes.py (2 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 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.
  • 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.

Support

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

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 generate unit tests to generate unit tests for 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.

@NiveditJain
Copy link
Member Author

Fixing secrets as in this issue: #140

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: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1fbe9a and 1f705c5.

⛔ Files ignored due to path filters (1)
  • state-manager/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • state-manager/app/controller/upsert_graph_template.py (2 hunks)
  • state-manager/app/models/db/graph_template_model.py (2 hunks)
  • state-manager/app/models/graph_models.py (1 hunks)
  • state-manager/app/utils/encrypter.py (1 hunks)
  • state-manager/pyproject.toml (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: NiveditJain
PR: exospherehost/exospherehost#132
File: state-manager/app/controller/upsert_graph_template.py:11-27
Timestamp: 2025-08-03T16:46:04.030Z
Learning: In the exospherehost codebase, for upsert operations on graph templates, the team prioritizes API idempotency over avoiding race conditions in the database layer implementation. The approach of separate find and insert/update operations is acceptable when the API behavior remains consistent.
📚 Learning: the exospherehost project requires python versions > 3.12 for the ci workflow, meaning python 3.13 o...
Learnt from: NiveditJain
PR: exospherehost/exospherehost#130
File: .github/workflows/ci.yml:22-22
Timestamp: 2025-08-02T12:43:35.075Z
Learning: The exospherehost project requires Python versions > 3.12 for the CI workflow, meaning Python 3.13 or higher should be used despite potential stability concerns with pre-release versions.

Applied to files:

  • state-manager/pyproject.toml
📚 Learning: in the exospherehost codebase, for upsert operations on graph templates, the team prioritizes api id...
Learnt from: NiveditJain
PR: exospherehost/exospherehost#132
File: state-manager/app/controller/upsert_graph_template.py:11-27
Timestamp: 2025-08-03T16:46:04.030Z
Learning: In the exospherehost codebase, for upsert operations on graph templates, the team prioritizes API idempotency over avoiding race conditions in the database layer implementation. The approach of separate find and insert/update operations is acceptable when the API behavior remains consistent.

Applied to files:

  • state-manager/app/controller/upsert_graph_template.py
🔇 Additional comments (12)
state-manager/pyproject.toml (1)

9-9: cryptography>=45.0.5 verified on PyPI and secured

  • Version 45.0.5 is published on PyPI and is the current latest release.
  • All known security advisories (including the OpenSSL issue patched in 44.0.1) apply only to versions < 44.0.1.
  • Since 45.0.5 > 44.0.1, it includes all fixes and has no outstanding vulnerabilities in its version range.

No further changes required here.

state-manager/app/utils/encrypter.py (4)

7-9: LGTM!

The key generation method correctly creates a 256-bit AES key with proper URL-safe base64 encoding.


11-21: Well-implemented key initialization with proper validation.

The constructor correctly validates the encryption key from the environment variable, ensuring it's properly formatted base64 and exactly 32 bytes for AES-256.


23-26: Secure encryption implementation.

The method correctly uses a 12-byte random nonce, prepends it to the ciphertext, and returns URL-safe base64 encoded output.


28-32: Correct decryption implementation.

The method properly extracts the nonce and ciphertext, then decrypts and decodes the result.

state-manager/app/models/graph_models.py (1)

9-9: Good security design for secrets handling.

The API design correctly accepts plaintext secrets in requests and returns only presence indicators in responses, preventing secret value exposure.

Also applies to: 15-15

state-manager/app/controller/upsert_graph_template.py (3)

21-27: Clean implementation of secret handling during update.

The chaining of set_secrets() with update() ensures secrets are properly encrypted before database operations.


36-44: Consistent secret handling for new templates.

The implementation properly encrypts secrets before insertion, maintaining consistency with the update operation.


50-50: Secure response construction.

The response correctly exposes only the presence of secrets without revealing their values.

state-manager/app/models/db/graph_template_model.py (3)

1-2: Proper setup for secrets functionality.

The imports and field definition are appropriate, with correct use of default_factory to avoid mutable default issues.

Also applies to: 5-5, 10-11, 19-19


30-42: Comprehensive validation of secrets dictionary.

The validator properly checks for empty values and correct types before delegating to value-specific validation.


70-72: Good use of fluent interface pattern.

Returning self from set_secrets enables clean method chaining as demonstrated in the controller.

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: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f705c5 and 8de165c.

📒 Files selected for processing (6)
  • python-sdk/exospherehost/node/BaseNode.py (1 hunks)
  • python-sdk/exospherehost/runtime.py (2 hunks)
  • state-manager/app/controller/register_nodes.py (3 hunks)
  • state-manager/app/models/db/registered_node.py (1 hunks)
  • state-manager/app/models/register_nodes_request.py (1 hunks)
  • state-manager/app/models/register_nodes_response.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: NiveditJain
PR: exospherehost/exospherehost#132
File: state-manager/app/controller/upsert_graph_template.py:11-27
Timestamp: 2025-08-03T16:46:04.030Z
Learning: In the exospherehost codebase, for upsert operations on graph templates, the team prioritizes API idempotency over avoiding race conditions in the database layer implementation. The approach of separate find and insert/update operations is acceptable when the API behavior remains consistent.
🪛 GitHub Actions: Ruff check on changed files only
python-sdk/exospherehost/runtime.py

[error] 261-261: Ruff: Use is and is not for type comparisons, or isinstance() for isinstance checks (E721) at line 261.

🔇 Additional comments (10)
state-manager/app/models/register_nodes_response.py (1)

9-9: LGTM!

The addition of the secrets field follows the established pattern and aligns with the broader secret management functionality being introduced across the system.

state-manager/app/models/register_nodes_request.py (2)

9-9: LGTM!

The secrets field addition is consistent with the corresponding response model and follows proper Pydantic field definition patterns.


14-14: Good housekeeping.

Removing trailing whitespace improves code cleanliness.

state-manager/app/models/db/registered_node.py (1)

12-12: Good housekeeping.

Removing trailing whitespace improves code cleanliness.

python-sdk/exospherehost/node/BaseNode.py (1)

45-49: LGTM!

The Secrets class follows the established pattern of Inputs and Outputs nested classes, providing a clean foundation for nodes to define their secret schemas.

python-sdk/exospherehost/runtime.py (2)

138-140: LGTM!

The secrets field registration correctly extracts field names from the node's Secrets model, maintaining consistency with the inputs and outputs schema registration.


255-259: Excellent validation logic for Secrets schema.

The validation ensures that nodes properly define their Secrets class and inherit from BaseModel, maintaining consistency with the existing Inputs and Outputs validation pattern.

state-manager/app/controller/register_nodes.py (3)

46-47: LGTM! Consistent secrets handling in node creation.

The addition of the secrets parameter to the RegisteredNode constructor maintains consistency with the update operation and ensures proper initialization of the secrets field for new nodes.


56-57: LGTM! Complete end-to-end secrets handling.

The inclusion of secrets in the response model completes the end-to-end implementation, ensuring that secrets are properly handled from request input through database storage to API response.


33-34: Secrets field integration looks solid—just clean up the type‐checker noise

I’ve confirmed that:

  • The DB model (RegisteredNode), request model (NodeRegistrationModel), and response model (RegisteredNodeModel) all declare secrets: list[str] / List[str] consistently.
  • The addition of RegisteredNode.secrets: node_data.secrets in your update, creation, and response mappings aligns with inputs_schema/outputs_schema.

The only remaining item is the # type: ignore on lines 33–34 (and similarly at lines 46–47, 56–57) when you map RegisteredNode.secrets. That’s silencing a typing mismatch between SQLAlchemy’s column attribute and your data shape. You can:

  • Verify that secrets is declared as a SQLAlchemy column (e.g. Column(ARRAY(String))) in RegisteredNode—this often satisfies most type checkers.
  • If the warning persists, narrow the ignore (e.g. # type: ignore[assignment]) or add an explicit cast instead of a blanket # type: ignore.

No functional changes needed beyond cleaning up those mypy/flake8 warnings.

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: 2

♻️ Duplicate comments (1)
python-sdk/exospherehost/runtime.py (1)

277-284: Fix type comparison per pipeline failure.

The validation logic for secrets is correct, but line 283 still uses != instead of is not for type comparison, which causes pipeline failure as noted in the previous review.

             for field_name, field_info in node.Secrets.model_fields.items():
-                if field_info.annotation != str:
+                if field_info.annotation is not str:
                     errors.append(f"{node.__name__}.Secrets field '{field_name}' must be of type str, got {field_info.annotation}")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8de165c and be6662e.

📒 Files selected for processing (2)
  • python-sdk/exospherehost/node/BaseNode.py (2 hunks)
  • python-sdk/exospherehost/runtime.py (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: NiveditJain
PR: exospherehost/exospherehost#132
File: state-manager/app/controller/upsert_graph_template.py:11-27
Timestamp: 2025-08-03T16:46:04.030Z
Learning: In the exospherehost codebase, for upsert operations on graph templates, the team prioritizes API idempotency over avoiding race conditions in the database layer implementation. The approach of separate find and insert/update operations is acceptable when the API behavior remains consistent.
🔇 Additional comments (6)
python-sdk/exospherehost/node/BaseNode.py (2)

45-49: LGTM! Consistent with existing patterns.

The Secrets class follows the same design pattern as the existing Inputs and Outputs classes, maintaining consistency in the codebase architecture.


62-62: LGTM! Consistent assignment pattern.

The secrets assignment follows the same pattern as inputs assignment, making secrets accessible to node implementations via self.secrets.

python-sdk/exospherehost/runtime.py (4)

4-4: LGTM! Required import for new method.

The Dict import is needed for the return type annotation of the new _get_secrets method.


120-124: LGTM! Consistent endpoint construction pattern.

The method follows the same pattern as other endpoint construction methods and correctly includes the state_id in the URL path.


144-146: LGTM! Correct secrets registration.

The implementation correctly extracts secret field names from the node's Secrets model and includes them in the registration payload, aligning with the broader secrets functionality.


307-308: LGTM! Correct secrets integration in worker.

The implementation correctly fetches secrets for each state and passes them to the node's _execute method alongside inputs, completing the integration with the updated BaseNode interface.

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

♻️ Duplicate comments (6)
state-manager/app/utils/encrypter.py (1)

34-49: LGTM! Lazy initialization properly implemented.

The singleton pattern with lazy initialization has been correctly implemented as suggested in the previous review. This prevents application failures when the encryption key is not needed.

state-manager/app/models/db/graph_template_model.py (2)

44-63: LGTM! Base64 validation correctly implemented.

The URL-safe base64 validation has been properly implemented without the problematic divisibility check. The validation correctly relies on base64.urlsafe_b64decode to handle padding automatically.


74-79: LGTM! Error handling properly implemented.

The method now correctly returns None when the secret is not found, addressing the previous concern about KeyError exceptions.

python-sdk/exospherehost/node/BaseNode.py (1)

51-61: LGTM! Docstring properly updated.

The docstring has been correctly updated to document the secrets parameter, addressing the previous review comment.

python-sdk/exospherehost/runtime.py (2)

283-285: LGTM! Type comparison correctly implemented.

The type comparison now correctly uses is not instead of !=, addressing the pipeline failure from the previous review.


235-250: LGTM! Error handling properly implemented.

The method now correctly returns an empty dictionary when the request fails, preventing downstream issues when constructing the Secrets object.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be6662e and 370ebd3.

📒 Files selected for processing (4)
  • python-sdk/exospherehost/node/BaseNode.py (1 hunks)
  • python-sdk/exospherehost/runtime.py (6 hunks)
  • state-manager/app/models/db/graph_template_model.py (2 hunks)
  • state-manager/app/utils/encrypter.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: NiveditJain
PR: exospherehost/exospherehost#132
File: state-manager/app/controller/upsert_graph_template.py:11-27
Timestamp: 2025-08-03T16:46:04.030Z
Learning: In the exospherehost codebase, for upsert operations on graph templates, the team prioritizes API idempotency over avoiding race conditions in the database layer implementation. The approach of separate find and insert/update operations is acceptable when the API behavior remains consistent.
🔇 Additional comments (1)
python-sdk/exospherehost/runtime.py (1)

308-309: Consider handling missing required secrets.

When _get_secrets returns an empty dictionary due to an error, the node.Secrets(**secrets) instantiation might fail if the node's Secrets class has required fields.

Consider adding error handling to provide a more informative error message:

-                secrets = await self._get_secrets(state["state_id"])
-                outputs = await node()._execute(node.Inputs(**state["inputs"]), node.Secrets(**secrets))
+                secrets = await self._get_secrets(state["state_id"])
+                try:
+                    secrets_obj = node.Secrets(**secrets)
+                except ValidationError as e:
+                    if not secrets:  # Empty dict from error
+                        raise RuntimeError(f"Failed to fetch secrets for node {node.__name__}: {e}")
+                    raise
+                outputs = await node()._execute(node.Inputs(**state["inputs"]), secrets_obj)

- Introduced a new section in the README to explain how to work with secrets, including a code example for using secrets in nodes.
- Enhanced the BaseNode class to define a schema for secrets, ensuring secure handling and validation.
- Added a new route to retrieve secrets for a specific state, along with the necessary controller and response model.
- Updated state management models to include graph names and ensure compatibility with the new secrets functionality.
@NiveditJain NiveditJain merged commit 6ce8a9a into exospherehost:main Aug 5, 2025
2 checks passed
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: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 370ebd3 and 15d4f72.

📒 Files selected for processing (11)
  • .github/workflows/deploy-kubernetes.yml (1 hunks)
  • python-sdk/README.md (1 hunks)
  • python-sdk/exospherehost/_version.py (1 hunks)
  • python-sdk/exospherehost/node/BaseNode.py (1 hunks)
  • python-sdk/exospherehost/runtime.py (6 hunks)
  • state-manager/app/controller/create_states.py (2 hunks)
  • state-manager/app/controller/get_secrets.py (1 hunks)
  • state-manager/app/models/create_models.py (1 hunks)
  • state-manager/app/models/db/state.py (1 hunks)
  • state-manager/app/models/secrets_response.py (1 hunks)
  • state-manager/app/routes.py (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: NiveditJain
PR: exospherehost/exospherehost#132
File: state-manager/app/controller/upsert_graph_template.py:11-27
Timestamp: 2025-08-03T16:46:04.030Z
Learning: In the exospherehost codebase, for upsert operations on graph templates, the team prioritizes API idempotency over avoiding race conditions in the database layer implementation. The approach of separate find and insert/update operations is acceptable when the API behavior remains consistent.
📚 Learning: the exospherehost project is currently in beta phase, so breaking changes in apis are acceptable and...
Learnt from: NiveditJain
PR: exospherehost/exospherehost#131
File: state-manager/app/models/executed_models.py:0-0
Timestamp: 2025-08-03T04:26:00.148Z
Learning: The exospherehost project is currently in beta phase, so breaking changes in APIs are acceptable and don't require versioning or migration strategies.

Applied to files:

  • python-sdk/exospherehost/_version.py
📚 Learning: the exospherehost project requires python versions > 3.12 for the ci workflow, meaning python 3.13 o...
Learnt from: NiveditJain
PR: exospherehost/exospherehost#130
File: .github/workflows/ci.yml:22-22
Timestamp: 2025-08-02T12:43:35.075Z
Learning: The exospherehost project requires Python versions > 3.12 for the CI workflow, meaning Python 3.13 or higher should be used despite potential stability concerns with pre-release versions.

Applied to files:

  • python-sdk/exospherehost/_version.py
🪛 LanguageTool
python-sdk/README.md

[grammar] ~133-~133: Use correct spacing
Context: ...nd the state manager. ### Working with Secrets Secrets allow you to securely manage sen...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~135-~135: There might be a mistake here.
Context: ...kens. Here's how to use secrets in your nodes: python from exospherehost import Runtime, BaseNode from pydantic import BaseModel class APINode(BaseNode): class Inputs(BaseModel): user_id: str query: str class Outputs(BaseModel): response: dict status: str class Secrets(BaseModel): api_key: str api_endpoint: str database_url: str async def execute(self) -> Outputs: # Access secrets via self.secrets headers = {"Authorization": f"Bearer {self.secrets.api_key}"} # Use secrets for API calls import httpx async with httpx.AsyncClient() as client: response = await client.post( f"{self.secrets.api_endpoint}/process", headers=headers, json={"user_id": self.inputs.user_id, "query": self.inputs.query} ) return self.Outputs( response=response.json(), status="success" ) **Ke...

(QB_NEW_EN_OTHER)


[grammar] ~174-~174: There might be a mistake here.
Context: ...cess" ) ``` Key points about secrets: - Security: Secrets are stored securely...

(QB_NEW_EN_OTHER)


[grammar] ~176-~176: There might be a mistake here.
Context: ... and are never exposed in logs or error messages - Validation: The Secrets class uses P...

(QB_NEW_EN_OTHER)


[grammar] ~177-~177: There might be a mistake here.
Context: ...ntic for automatic validation of secret values - Access: Secrets are available via `sel...

(QB_NEW_EN_OTHER)


[grammar] ~178-~178: There might be a mistake here.
Context: ...vailable via self.secrets during node execution - Types: Common secret types include API...

(QB_NEW_EN_OTHER)


[grammar] ~179-~179: There might be a mistake here.
Context: ...ls, encryption keys, and authentication tokens - Injection: Secrets are injected by the...

(QB_NEW_EN_OTHER)


[grammar] ~180-~180: There might be a mistake here.
Context: ... time, so you don't need to handle them manually ## Integration with ExosphereHost Platform ...

(QB_NEW_EN_OTHER)

🪛 GitHub Actions: Ruff check on changed files only
state-manager/app/routes.py

[error] 30-30: Ruff F401: .models.db.state.State imported but unused. Remove unused import.


[error] 168-168: Ruff F541: f-string without any placeholders. Remove extraneous f prefix.


[error] 170-170: Ruff F541: f-string without any placeholders. Remove extraneous f prefix.

state-manager/app/controller/get_secrets.py

[error] 4-4: Ruff F401: app.models.db.registered_node.RegisteredNode imported but unused. Remove unused import.

🔇 Additional comments (19)
.github/workflows/deploy-kubernetes.yml (1)

34-34: LGTM! Proper secrets management setup.

The addition of SECRETS_ENCRYPTION_KEY to the Kubernetes secret follows the established pattern and correctly supports the new AES-GCM encryption functionality for the state manager.

python-sdk/exospherehost/_version.py (1)

1-1: Appropriate version bump for new functionality.

The version increment from "0.0.7b2" to "0.0.7b3" correctly reflects the addition of secrets management features in this beta release.

state-manager/app/models/db/state.py (1)

11-11: LGTM! Essential field for secrets functionality.

The addition of the graph_name field properly links states to their graph templates, enabling secrets retrieval as described in the PR objectives. The field follows the established pattern with proper typing and documentation.

state-manager/app/models/create_models.py (2)

9-9: Consistent model extension for graph template association.

The addition of graph_name to RequestStateModel properly enables clients to specify the graph template when creating states, maintaining consistency with the database model changes.


16-16: Proper response model alignment.

The addition of graph_name to ResponseStateModel ensures API responses include graph template information, maintaining consistency across request, response, and database models.

state-manager/app/models/secrets_response.py (1)

1-6: Well-designed secrets response model.

The SecretsResponseModel is properly implemented with:

  • Correct typing for secret name-to-value mapping
  • Appropriate Pydantic configuration
  • Clear documentation
  • Simple, focused design for the secrets API endpoint
state-manager/app/controller/create_states.py (1)

21-21: LGTM! Properly integrates graph_name field.

The addition of graph_name field is correctly implemented in both state creation and response model, maintaining consistency with the data flow.

Also applies to: 39-39

state-manager/app/routes.py (1)

157-174: Well-structured secrets retrieval endpoint.

The endpoint implementation follows the established patterns and properly handles authentication, request tracking, and delegation to the controller.

python-sdk/README.md (1)

133-181: Excellent documentation for the secrets feature!

The new section provides clear explanations, practical examples, and important security considerations. The code example effectively demonstrates how to define and use secrets within nodes.

python-sdk/exospherehost/runtime.py (3)

284-284: Type comparison correctly implemented.

Good to see the previous review comment has been addressed - using is not for type comparison is the correct approach.


235-250: Proper error handling for secrets retrieval.

The method correctly returns an empty dictionary on failure, preventing downstream issues. The error logging provides good visibility into failures.


120-125: Comprehensive secrets integration in the runtime.

The implementation properly handles all aspects of secret management:

  • Registration of secret schemas with the state manager
  • Validation that nodes define proper Secrets classes with string fields
  • Secure retrieval of secrets per state
  • Clean injection into node execution

This provides a secure and developer-friendly way to manage sensitive configuration.

Also applies to: 144-146, 278-285, 308-309

python-sdk/exospherehost/node/BaseNode.py (3)

72-76: Docstring properly updated for the secrets parameter.

The previous review comment has been addressed - the docstring now correctly documents both the inputs and secrets parameters.


45-68: Excellent documentation for the Secrets class!

The expanded docstring provides comprehensive information about:

  • Purpose and usage of secrets
  • Types of data that should be stored as secrets
  • Security considerations
  • Examples of common secret types

This addresses the previous review comment perfectly and will greatly help developers understand how to use this feature.


70-83: Clean integration of secrets into node execution.

The implementation elegantly extends the node execution model to support secrets while maintaining the existing API. Storing secrets in self.secrets follows the established pattern with self.inputs.

state-manager/app/controller/get_secrets.py (4)

11-25: Well-structured function signature and documentation.

The function signature is clear with proper type hints, and the docstring follows good documentation practices with comprehensive Args, Returns, and Raises sections.


28-36: Proper state validation with security check.

The implementation correctly validates state existence and performs an important security check to ensure the state belongs to the requested namespace, preventing unauthorized access to secrets from other namespaces.


39-46: Appropriate graph template lookup logic.

The graph template lookup correctly uses both the graph name from the state and the namespace for proper isolation. The error handling with logging provides good debugging information.


49-53: Clean secret retrieval and response construction.

The implementation delegates secret decryption to the GraphTemplate.get_secrets() method, which is a good separation of concerns. The logging provides useful information about the number of secrets retrieved.

Comment on lines +55 to +57
except Exception as e:
logger.error(f"Error getting secrets for state {state_id}: {str(e)}", x_exosphere_request_id=x_exosphere_request_id)
raise e No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider improving exception re-raising pattern.

While the exception handling logs errors properly, using bare raise e is less idiomatic than raise alone, as it can potentially modify the stack trace.

-        raise e 
+        raise
🤖 Prompt for AI Agents
In state-manager/app/controller/get_secrets.py around lines 55 to 57, the
exception is re-raised using 'raise e', which can alter the original stack
trace. Replace 'raise e' with a bare 'raise' to re-raise the caught exception
while preserving the original traceback.

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.

1 participant