Skip to content

Conversation

zubairirfan96
Copy link
Collaborator

@zubairirfan96 zubairirfan96 commented Aug 11, 2025

📝 Description

Added Support for Vault Key Usage inside NodeJS Code Component. Key can be used by using this string template:
{{KEY(keyNameInVault)}} where keyNameInVault is the actual key name in SmythOS Vault.
For using own keys, users need to add "lambda:UpdateFunctionConfiguration" permission in policy document for specified user.

🔗 Related Issues

  • Fixes #
  • Relates to #

🔧 Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 📚 Documentation update
  • 🔧 Code refactoring (no functional changes)
  • 🧪 Test improvements
  • 🔨 Build/CI changes

✅ Checklist

  • [✅] Self-review performed
  • [✅] Tests added/updated
  • [✅] Documentation updated (if needed)

Summary by CodeRabbit

  • New Features
    • Environment-variable support for serverless deployments, including automatic injection into deployed functions.
    • Secure resolution of secret placeholders from Vault before deployment.
    • Deployment hash now includes environment values, triggering automatic redeploys when env vars change.
    • Code generation updated to embed environment handling for consistent runtime behavior.
    • Ability to update environment configuration on existing functions during deploys, ensuring config stays in sync.

@zubairirfan96 zubairirfan96 changed the base branch from main to dev August 11, 2025 13:10
Copy link

coderabbitai bot commented Aug 11, 2025

Walkthrough

Environment-variable awareness was added to AWS Lambda code generation, hashing, and deployment. Hashing now includes env values. Code generation embeds env handling. Deployment fetches and applies env vars, updating function configuration when needed. New helpers resolve vault-backed env vars and sanitize vault placeholders before validation and hashing.

Changes

Cohort / File(s) Summary of changes
Core helpers: env-aware hashing, codegen, deployment, and vault utilities
packages/core/src/helpers/AWSLambdaCode.helper.ts
Added env-variable support across code hash, code generation, and deployment. Introduced vault template replacement and env resolution helpers (extract, fetch, sort). Updated function signatures to accept env variables. Implemented UpdateFunctionConfigurationCommand path. Validation now sanitizes vault placeholders.
Compute connector: env-integrated deploy flow
packages/core/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts
Deployment now fetches current env vars, includes them in code hash, passes them to code generation and function creation/update. Imports new helpers for env resolution and sorting. Minor formatting change.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CM as ComputeManager (AWSLambdaCode.class)
  participant H as Helpers (AWSLambdaCode.helper)
  participant VAULT as Vault
  participant AWS as AWS Lambda

  CM->>H: getCurrentEnvironmentVariables(teamId, code)
  H->>VAULT: fetch secrets for {{KEY(NAME)}} placeholders
  VAULT-->>H: envVariables map
  H-->>CM: envVariables

  CM->>H: generateLambdaCode(code, parameters, envVariables)
  H-->>CM: env-aware code bundle

  CM->>H: generateCodeHash(code, inputs, sorted(env values))
  H-->>CM: codeHash

  CM->>H: createOrUpdateLambdaFunction(name, zipPath, awsConfigs, envVariables)
  alt function exists
    H->>AWS: UpdateFunctionConfiguration(envVariables)
    AWS-->>H: updated config
  else create new
    H->>AWS: CreateFunction(envVariables)
    AWS-->>H: function created
  end
  CM-->>CM: verify deployment by codeHash
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

In burrows of bytes, I tweak and I tend,
Secrets in soil, env vars I send.
Hashes now sniff the breeze of change,
Lambdas hop fresh across the range.
Vault whispers keys, I twitch an ear—
Deploy, update—carrots all clear. 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/core/nodejs-component-env-variable-support

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

❤️ Share
🪧 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.

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

🧹 Nitpick comments (2)
packages/core/src/helpers/AWSLambdaCode.helper.ts (2)

87-90: Unused parameter in replaceVaultKeysTemplateVars

The envVariables parameter is not used in the function. If it's not needed, consider removing it to avoid confusion.

-function replaceVaultKeysTemplateVars(code: string, envVariables: Record<string, string>) {
+function replaceVaultKeysTemplateVars(code: string) {
    const regex = /\{\{KEY\((.*?)\)\}\}/g;
    return code.replaceAll(regex, (match, p1) => `process.env.${p1}`);
}

Then update the call sites:

-    const code = replaceVaultKeysTemplateVars(rawCode, {});
+    const code = replaceVaultKeysTemplateVars(rawCode);

92-95: Consider simplifying the conditional logic

Since replaceVaultKeysTemplateVars doesn't use the envVariables parameter, the conditional check seems unnecessary.

If you remove the unused parameter as suggested earlier:

-    const codeWithEnvVariables = envVariables && Object.keys(envVariables).length ? replaceVaultKeysTemplateVars(code, envVariables) : code;
+    const codeWithEnvVariables = replaceVaultKeysTemplateVars(code);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 7c42656 and 625c03b.

📒 Files selected for processing (2)
  • packages/core/src/helpers/AWSLambdaCode.helper.ts (12 hunks)
  • packages/core/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts (5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/core/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts (1)
packages/core/src/helpers/AWSLambdaCode.helper.ts (7)
  • getDeployedFunction (314-337)
  • getDeployedCodeHash (74-78)
  • getCurrentEnvironmentVariables (575-583)
  • getSortedObjectValues (585-588)
  • generateCodeHash (23-28)
  • generateLambdaCode (92-114)
  • createOrUpdateLambdaFunction (129-213)
packages/core/src/helpers/AWSLambdaCode.helper.ts (1)
packages/core/src/subsystems/Security/Vault.service/Vault.helper.ts (1)
  • VaultHelper (7-30)
🔇 Additional comments (12)
packages/core/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts (3)

8-8: LGTM!

The new imports are properly added to support environment variable handling.


40-43: Good implementation of deterministic hashing!

The sorting of environment variable values ensures consistent hash generation, which is crucial for detecting changes in environment configuration.


62-62: Proper propagation of environment variables!

Environment variables are correctly passed to both code generation and Lambda function creation/update.

Also applies to: 73-73

packages/core/src/helpers/AWSLambdaCode.helper.ts (9)

5-5: LGTM!

The UpdateFunctionConfigurationCommand import is properly added for environment variable configuration updates.


23-28: Proper hash generation with environment variables!

The inclusion of environment variables in the hash ensures Lambda functions are redeployed when environment configuration changes.


30-32: Smart sanitization approach!

Replacing vault key templates before hashing ensures consistent hash generation regardless of the actual secret values.


155-158: Excellent environment variable handling!

The function properly manages environment variables for both Lambda function updates and creation, with appropriate deployment status verification.

Also applies to: 202-202


215-224: Clean implementation of configuration update!

The function properly updates Lambda environment variables using the AWS SDK.


382-385: Smart validation approach!

Sanitizing vault key templates before AST parsing prevents validation errors from the template syntax.


553-563: Robust key extraction implementation!

The function correctly extracts all vault key names from the template syntax.


575-583: Efficient parallel fetching of vault secrets!

The function properly fetches all required vault secrets in parallel and aggregates them into environment variables.


585-588: Good implementation for deterministic ordering!

The function ensures consistent ordering of object values, which is essential for reproducible hash generation.

Comment on lines +553 to +563
export function extractAllKeyNamesFromTemplateVars(input: string): string[] {
const regex = /\{\{KEY\((.*?)\)\}\}/g;
const matches = [];
let match;
while ((match = regex.exec(input)) !== null) {
if (match[1]) {
matches.push(match[1]);
}
}
return matches;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation for vault key names

Consider validating that extracted key names are valid environment variable names to prevent issues with special characters.

 export function extractAllKeyNamesFromTemplateVars(input: string): string[] {
     const regex = /\{\{KEY\((.*?)\)\}\}/g;
     const matches = [];
     let match;
     while ((match = regex.exec(input)) !== null) {
         if (match[1]) {
+            // Validate key name contains only alphanumeric and underscore
+            if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(match[1])) {
+                throw new Error(`Invalid vault key name: "${match[1]}". Key names must be valid environment variable names.`);
+            }
             matches.push(match[1]);
         }
     }
     return matches;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function extractAllKeyNamesFromTemplateVars(input: string): string[] {
const regex = /\{\{KEY\((.*?)\)\}\}/g;
const matches = [];
let match;
while ((match = regex.exec(input)) !== null) {
if (match[1]) {
matches.push(match[1]);
}
}
return matches;
}
export function extractAllKeyNamesFromTemplateVars(input: string): string[] {
const regex = /\{\{KEY\((.*?)\)\}\}/g;
const matches = [];
let match;
while ((match = regex.exec(input)) !== null) {
if (match[1]) {
// Validate key name contains only alphanumeric characters and underscores, and doesn’t start with a digit
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(match[1])) {
throw new Error(
`Invalid vault key name: "${match[1]}". Key names must be valid environment variable names.`
);
}
matches.push(match[1]);
}
}
return matches;
}
🤖 Prompt for AI Agents
In packages/core/src/helpers/AWSLambdaCode.helper.ts around lines 553 to 563,
the extracted vault key names from the template are not validated; update the
function to validate each extracted name against a standard environment-variable
pattern (/^[A-Za-z_][A-Za-z0-9_]*$/), collect any invalid names and either
filter them out or (preferably) throw an Error listing invalid keys so callers
know which entries are bad; ensure the function returns only the valid key names
when successful and include a clear error message naming the offending keys if
validation fails.

Comment on lines +566 to +573
async function fetchVaultSecret(keyName: string, agentTeamId: string): Promise<{ value: string, key: string }> {
const vaultSecret = await VaultHelper.getAgentKey(keyName, agentTeamId);
return {
value: vaultSecret,
key: keyName,
};

}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling for missing vault keys

The fetchVaultSecret function doesn't handle cases where a vault key might not exist. This could cause the entire deployment to fail if a referenced key is missing.

Consider adding error handling:

 async function fetchVaultSecret(keyName: string, agentTeamId: string): Promise<{ value: string, key: string }> {
-    const vaultSecret = await VaultHelper.getAgentKey(keyName, agentTeamId);
-    return {
-        value: vaultSecret,
-        key: keyName,
-    };
+    try {
+        const vaultSecret = await VaultHelper.getAgentKey(keyName, agentTeamId);
+        return {
+            value: vaultSecret,
+            key: keyName,
+        };
+    } catch (error) {
+        console.error(`Failed to fetch vault key "${keyName}":`, error);
+        throw new Error(`Vault key "${keyName}" not found or inaccessible`);
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function fetchVaultSecret(keyName: string, agentTeamId: string): Promise<{ value: string, key: string }> {
const vaultSecret = await VaultHelper.getAgentKey(keyName, agentTeamId);
return {
value: vaultSecret,
key: keyName,
};
}
async function fetchVaultSecret(keyName: string, agentTeamId: string): Promise<{ value: string, key: string }> {
try {
const vaultSecret = await VaultHelper.getAgentKey(keyName, agentTeamId);
return {
value: vaultSecret,
key: keyName,
};
} catch (error) {
console.error(`Failed to fetch vault key "${keyName}":`, error);
throw new Error(`Vault key "${keyName}" not found or inaccessible`);
}
}
🤖 Prompt for AI Agents
In packages/core/src/helpers/AWSLambdaCode.helper.ts around lines 566 to 573,
fetchVaultSecret currently assumes VaultHelper.getAgentKey always returns a
value; add handling for missing or empty secrets by checking the returned
vaultSecret (null/undefined/empty string) and, if absent, either throw a
descriptive Error (e.g. `throw new Error(\`Vault secret not found for key
${keyName} and team ${agentTeamId}\`)`) or return a clearly documented fallback
structure indicating the missing key; ensure the caller contract is preserved
(update callers if you choose to throw) and include a short
processLogger.warn/error entry before throwing/returning to aid debugging.

Comment on lines +34 to 38
const [isLambdaExists, exisitingCodeHash, currentEnvVariables] = await Promise.all([
getDeployedFunction(functionName, this.awsConfigs),
getDeployedCodeHash(agentId, codeUID),
getCurrentEnvironmentVariables(acRequest.candidate.id, input.code),
]);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect parameter passed to getCurrentEnvironmentVariables

The function getCurrentEnvironmentVariables expects agentTeamId as the first parameter, but you're passing acRequest.candidate.id which is the agentId. This could lead to incorrect vault secret retrieval.

Consider retrieving the team ID first:

-            getCurrentEnvironmentVariables(acRequest.candidate.id, input.code),
+            getCurrentEnvironmentVariables(/* need to get teamId from acRequest */, input.code),

You may need to fetch the team ID using the AccountConnector service similar to how it's done in the helper functions.

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

🤖 Prompt for AI Agents
In
packages/core/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts
around lines 34 to 38, getCurrentEnvironmentVariables is being called with
acRequest.candidate.id (agentId) but it expects agentTeamId; fetch the agent's
team ID first (use the AccountConnector or the same helper used elsewhere to
resolve team ID from the agent/account) and then call
getCurrentEnvironmentVariables(agentTeamId, input.code) so the correct vault
secrets are retrieved.

fs.rmSync(`${directory}`, { recursive: true, force: true });
fs.unlinkSync(`${directory}.zip`);
} catch (error) {}
} catch (error) { }
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error logging in catch block

The empty catch block silently swallows errors during cleanup. Consider logging the error for debugging purposes.

-            } catch (error) { }
+            } catch (error) {
+                console.debug('Cleanup error:', error);
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) { }
} catch (error) {
console.debug('Cleanup error:', error);
}
🤖 Prompt for AI Agents
In
packages/core/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts
around line 88, the catch block is empty and silently swallows errors during
cleanup; update the catch to log the error (including message and stack) with
the class/logger used in this file (e.g., this.logger?.error('Failed during
cleanup in AWSLambdaCode', error) or fall back to console.error if no logger),
ensure the caught value is handled as unknown and included in the log (e.g.,
String(error) and (error as Error).stack) to provide clear context for
debugging, and do not suppress the original error details.

@alaa-eddine-k alaa-eddine-k merged commit a2b8f68 into dev Aug 12, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants