Skip to content

Conversation

@lakshayman
Copy link
Contributor

@lakshayman lakshayman commented Jan 2, 2026

Date: 02 Jan 2026

Developer Name: @lakshayman


Description

This PR includes several improvements and fixes to the feature flag backend:

  1. JWT Authentication Improvements: Enhanced JWT token validation with better error logging and handling of public key whitespace issues. Added detailed logging to help debug SSM parameter retrieval and public key parsing failures.

  2. Infrastructure Setup: Added DynamoDB table setup script (setup-dynamodb-tables.sh) and comprehensive post-deployment setup documentation (POST_DEPLOYMENT_SETUP.md) to streamline deployment and testing processes.

  3. IAM Policy Fixes: Moved IAM policies from manual configuration to template.yaml for better infrastructure-as-code practices and easier management.

  4. Pipeline Fixes: Resolved CI/CD pipeline issues to ensure smooth deployments.

  5. Code Refactoring: Migrated shared code to AWS Lambda Layer architecture (from previous PR refactor: migrate shared code to AWS Lambda Layer #165), improving code reusability and maintainability.

Key Changes:

  • Enhanced JWT middleware with comprehensive error logging
  • Added public key whitespace trimming to handle SSM parameter formatting issues
  • Created setup scripts for local DynamoDB table creation
  • Improved error messages for better debugging experience
  • Updated test scripts with ngrok URL support for local development

Documentation Updated?

  • Yes
  • No

Added POST_DEPLOYMENT_SETUP.md with comprehensive deployment and testing instructions. Updated test scripts and documentation.

Under Feature Flag

  • Yes
  • No

These are infrastructure and authentication improvements, not feature changes.

Database Changes

  • Yes
  • No

Added setup script for DynamoDB tables (setup-dynamodb-tables.sh). No schema changes to existing tables.

Breaking Changes

  • Yes
  • No

No breaking changes. All changes are backward compatible.

Development Tested?

  • Yes
  • No

Tested locally and in production:

  • JWT authentication with new public key
  • Feature flag creation and retrieval
  • User feature flag mapping
  • All API endpoints verified working

Screenshots

JWT Authentication Success
✅ Testing GET all feature flags:
[
    {
        "id": "97b35949-edb0-4c79-afb9-7d6e56fe44b5",
        "name": "test-feature-flag",
        "description": "A test feature flag created via API",
        "status": "ENABLED",
        ...
    }
]

Test Coverage

API Testing Results

All endpoints tested and verified:

  • ✅ Health check endpoint
  • ✅ JWT authentication working
  • ✅ Create feature flag
  • ✅ Get all feature flags
  • ✅ Create user feature flag mapping
  • ✅ Get user feature flags

Additional Notes

  • JWT Authentication: Fixed issues with public key retrieval from SSM Parameter Store by adding whitespace trimming and comprehensive error logging. This helps identify issues during initialization.

  • Error Logging: Added detailed logging at each step of JWT initialization to help debug authentication failures:

    • SSM parameter name being accessed
    • Success/failure of parameter retrieval
    • PEM decoding status
    • Public key parsing errors
  • Setup Scripts: The setup-dynamodb-tables.sh script automates DynamoDB table creation for local development and testing.

  • Documentation: POST_DEPLOYMENT_SETUP.md provides step-by-step instructions for:

    • Setting up DynamoDB tables
    • Configuring SSM parameters
    • Testing API endpoints
    • Troubleshooting common issues
  • Testing: All changes have been tested in production environment with successful JWT authentication and feature flag operations.

@lakshayman lakshayman self-assigned this Jan 2, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Summary by CodeRabbit

  • Documentation

    • Added comprehensive post-deployment setup guide covering DynamoDB initialization, SSM parameter configuration, and API validation.
  • Chores

    • Updated CI/CD pipeline with latest GitHub Actions versions.
    • Enhanced IAM permissions configuration for improved security enforcement.
    • Added automated DynamoDB table initialization script.
    • Improved logging and error handling for better operational visibility.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

The pull request introduces comprehensive post-deployment setup documentation and infrastructure enhancements. Key changes include GitHub Actions workflow version upgrades, DynamoDB table initialization setup, IAM policy additions to Lambda functions, enhanced JWT logging with defensive null checks, and a post-deployment guide for configuration and verification.

Changes

Cohort / File(s) Summary
CI/CD Workflow
.github/workflows/pipeline.yaml
Upgrades GitHub Actions to newer versions (checkout v4→v5, slug v3→v5, setup-go v5→v6, aws-actions/configure-aws-credentials v1→v4, actions/upload-artifact & actions/download-artifact to v6). Replaces deprecated set-output with $GITHUB_OUTPUT environment file for branch name. Updates Python to v3.11 and SAM CLI setup to v2 with installer.
Documentation & Setup
POST_DEPLOYMENT_SETUP.md, setup-dynamodb-tables.sh
Introduces new post-deployment guide with DynamoDB table creation (featureFlag, featureFlagUserMapping, requestLimit), SSM parameter verification, API health checks, and troubleshooting. Adds Bash script for automated table setup with PAY_PER_REQUEST billing and initial seed data.
JWT Security Enhancements
layer/jwt/jwt.go
Adds extensive runtime logging for SSM key fetch, PEM decoding, PKIX parsing, and RSA assertion. Introduces defensive null checks for parameter retrieval. Adds key value trimming and min helper function for safe substring logging.
Infrastructure Permissions
template.yaml
Adds IAM policies across multiple Lambda functions (CorsLambda, HealthCheckFunction, RateLimiterFunction, ResetLimitFunction, GetFeatureFlagFunction, CreateFeatureFlagFunction, UpdateFeatureFlagFunction, GetAllFeatureFlagFunction, GetUserFeatureFlagFunction, GetUserFeatureFlagsFunction, CreateUserFeatureFlagFunction, UpdateUserFeatureFlagFunction). Policies grant DynamoDB CRUD access to three tables and SSM parameter read access to public keys. RateLimiterFunction receives additional lambda:PutFunctionConcurrency permission.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Lambda as Lambda Functions
    participant DynamoDB as DynamoDB<br/>(featureFlag,<br/>featureFlagUserMapping,<br/>requestLimit)
    participant SSM as Parameter Store<br/>(Public Keys)
    
    User->>Lambda: 1. Deploy application
    Lambda->>DynamoDB: 2. Create tables<br/>(setup-dynamodb-tables.sh)
    DynamoDB-->>Lambda: Tables created & initialized
    
    User->>SSM: 3. Verify/Create SSM<br/>parameters (PROD/STAGING<br/>public keys)
    SSM-->>User: Parameters ready
    
    Lambda->>SSM: 4. Fetch JWT public key<br/>(with logging & defensive checks)
    SSM-->>Lambda: Return key (trimmed)
    Lambda->>Lambda: 5. Parse & verify key<br/>(PEM → PKIX → RSA)
    Lambda-->>Lambda: JWT utils initialized
    
    User->>Lambda: 6. Test API endpoints<br/>(health check,<br/>feature-flag operations)
    Lambda->>DynamoDB: 7. Execute operations<br/>(read/write requests<br/>with IAM permissions)
    DynamoDB-->>Lambda: Return results
    Lambda-->>User: Success response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hoppity-hop, the infrastructure grows,
New tables spring up where the database flows,
With logging so bright and permissions so tight,
The feature flags dance in serverless delight!
🎉✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The PR title 'chore: before pushing to prod' is vague and does not clearly convey the specific changes in the PR, using generic language without describing the actual work. Provide a more descriptive title that highlights the main changes, such as 'chore: add JWT logging, DynamoDB setup, and IAM policies' or 'chore: improve infrastructure setup and authentication logging.'
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive, well-structured, and clearly relates to the changeset including JWT improvements, DynamoDB setup, IAM policies, pipeline fixes, and documentation.
✨ Finishing touches
  • 📝 Generate docstrings

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@lakshayman lakshayman marked this pull request as ready for review January 2, 2026 05:11
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
template.yaml (1)

190-410: Remove unused DynamoDB table permissions from functions.

Functions are over-provisioned with permissions to tables they don't access:

  • getFeatureFlagById and getAllFeatureFlags: Remove DynamoDBCrudPolicy for featureFlagUserMapping
  • getUserFeatureFlag and getUserFeatureFlags: Remove DynamoDBCrudPolicy for featureFlag
  • createFeatureFlag and updateFeatureFlag: Remove DynamoDBCrudPolicy for featureFlagUserMapping
  • createUserFeatureFlag and updateUserFeatureFlag: Remove DynamoDBCrudPolicy for featureFlag

All functions require write access to requestLimit (not read-only) because CheckRequestAllowed actively decrements the rate limit counter with PutItem operations.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9061a24 and a978723.

📒 Files selected for processing (5)
  • .github/workflows/pipeline.yaml
  • POST_DEPLOYMENT_SETUP.md
  • layer/jwt/jwt.go
  • setup-dynamodb-tables.sh
  • template.yaml
🧰 Additional context used
🪛 actionlint (1.7.9)
.github/workflows/pipeline.yaml

22-22: shellcheck reported issue in this script: SC2086:info:1:42: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 LanguageTool
POST_DEPLOYMENT_SETUP.md

[style] ~63-~63: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...t` Table After creating the table, you need to add an initial value: ```bash aws dyna...

(REP_NEED_TO_VB)

🪛 markdownlint-cli2 (0.18.1)
POST_DEPLOYMENT_SETUP.md

184-184: Trailing spaces
Expected: 0 or 2; Actual: 1

(MD009, no-trailing-spaces)

🪛 Shellcheck (0.11.0)
setup-dynamodb-tables.sh

[info] 22-22: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 39-39: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 54-54: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 64-64: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 68-68: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 72-72: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 85-85: Double quote to prevent globbing and word splitting.

(SC2086)

🔇 Additional comments (8)
.github/workflows/pipeline.yaml (3)

17-25: LGTM! Modern GitHub Actions syntax.

The upgrade to use $GITHUB_OUTPUT instead of the deprecated set-output command is correct and aligns with current GitHub Actions best practices. The action version upgrades are also appropriate.


55-129: LGTM! Comprehensive GitHub Actions upgrades.

The workflow upgrades are well-coordinated:

  • AWS credentials action upgraded to v4 for improved security
  • Artifact upload/download actions upgraded to v6 (consistent versions)
  • Python setup upgraded to v6 with Python 3.11
  • SAM CLI setup upgraded to v2 with installer approach

These changes modernize the CI/CD pipeline appropriately.


34-36: No issues found. Go version 1.25.1 is a valid, released version as of January 2026 (the latest patch in the 1.25 series is 1.25.5). The specified version in the workflow is acceptable.

Likely an incorrect or invalid review comment.

layer/jwt/jwt.go (3)

88-117: Excellent defensive coding and observability improvements!

The enhancements significantly improve debuggability:

  • Comprehensive logging at each initialization step aids troubleshooting
  • TrimSpace on line 94 addresses SSM parameter formatting issues (trailing whitespace)
  • Safe substring using min() on line 98 prevents panics when logging truncated keys
  • Defensive nil checks ensure robust error handling
  • Security is maintained by only logging sanitized/truncated information

These changes directly address the production JWT authentication issues mentioned in the PR objectives.


119-148: Strong defensive programming with SSM parameter handling.

The nil checks on lines 141-144 are essential defensive measures:

  • Handles edge case where Parameter or Value might be nil
  • Provides clear error message for debugging
  • TrimSpace on line 146 ensures consistency with public key trimming

The enhanced logging throughout this function will significantly aid in diagnosing SSM-related issues in production.


150-155: LGTM! Simple and effective helper.

The min() helper prevents potential panics when taking substrings for logging. The implementation is straightforward and appropriate for integer comparison.

POST_DEPLOYMENT_SETUP.md (1)

1-91: Comprehensive and well-structured documentation!

The post-deployment guide provides excellent coverage:

  • Dual approach (script-based and manual) accommodates different user preferences
  • Clear explanations of required DynamoDB tables and their schemas
  • Verification commands help users confirm successful setup
  • Aligns perfectly with the setup-dynamodb-tables.sh script
template.yaml (1)

1-416: Strong infrastructure-as-code migration!

Moving IAM policies from manual configuration into template.yaml significantly improves:

  • Infrastructure reproducibility and version control
  • Consistency across environments (PROD/DEV)
  • Alignment with AWS best practices

The policy structure is well-organized and parameter names correctly match those referenced in layer/jwt/jwt.go and POST_DEPLOYMENT_SETUP.md.

Comment on lines +138 to +150
## 🧪 Test After Setup

After creating the tables, test your API:

```bash
# 1. Health check (should work)
curl https://j31g91e2fa.execute-api.us-east-1.amazonaws.com/Prod/health-check

# 2. Get feature flags (should work now)
curl -X GET "https://j31g91e2fa.execute-api.us-east-1.amazonaws.com/Prod/feature-flags/" \
-H "Cookie: rds-session-staging=YOUR_JWT_TOKEN" \
-H "Origin: https://test.realdevsquad.com"
```
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Replace hardcoded API endpoints with placeholders.

Lines 144, 147, and 218 contain hardcoded API Gateway endpoints (j31g91e2fa.execute-api.us-east-1.amazonaws.com). Users will need to replace these with their actual deployed endpoints.

🔎 Proposed fix
 ```bash
 # 1. Health check (should work)
-curl https://j31g91e2fa.execute-api.us-east-1.amazonaws.com/Prod/health-check
+curl https://<YOUR_API_ID>.execute-api.<YOUR_REGION>.amazonaws.com/Prod/health-check
 
 # 2. Get feature flags (should work now)
-curl -X GET "https://j31g91e2fa.execute-api.us-east-1.amazonaws.com/Prod/feature-flags/" \
+curl -X GET "https://<YOUR_API_ID>.execute-api.<YOUR_REGION>.amazonaws.com/Prod/feature-flags/" \
   -H "Cookie: rds-session-staging=YOUR_JWT_TOKEN" \
   -H "Origin: https://test.realdevsquad.com"

Add a note explaining how to find the API Gateway endpoint:

```markdown
**Note:** Replace `<YOUR_API_ID>` and `<YOUR_REGION>` with your actual API Gateway ID and region. You can find this in:
- AWS Console: API Gateway → Your API → Stages → Prod
- Or run: `aws cloudformation describe-stacks --stack-name <YOUR_STACK_NAME> --query 'Stacks[0].Outputs'`
🤖 Prompt for AI Agents
In POST_DEPLOYMENT_SETUP.md around lines 138 to 150 (and also update the other
occurrence at line 218), replace the hardcoded API Gateway URLs
(j31g91e2fa.execute-api.us-east-1.amazonaws.com) with placeholders like
<YOUR_API_ID>.execute-api.<YOUR_REGION>.amazonaws.com and update the two curl
examples accordingly; add a short note telling users how to find their API ID
and region (AWS Console path and an aws cloudformation describe-stacks command)
so they can substitute the placeholders with their actual values.

Comment on lines +152 to +228
---

## 📋 Complete Checklist

- [ ] **DynamoDB Tables Created:**
- [ ] `featureFlag` table exists
- [ ] `featureFlagUserMapping` table exists
- [ ] `requestLimit` table exists
- [ ] `requestLimit` table has initial item with `limitType: "pendingLimit"` and `limitValue: 1000`

- [ ] **SSM Parameter:**
- [ ] `PROD_RDS_BACKEND_PUBLIC_KEY` exists (for PRODUCTION)
- [ ] OR `STAGING_RDS_BACKEND_PUBLIC_KEY` exists (for DEVELOPMENT)

- [ ] **Testing:**
- [ ] Health check endpoint works
- [ ] Feature flags endpoints work with JWT token

---

## 🔍 Troubleshooting

### Error: "ResourceNotFoundException: Requested resource not found"

**Cause:** DynamoDB table doesn't exist

**Solution:** Create the missing table using the commands above

### Error: "invalid memory address or nil pointer dereference"

**Cause:** Code is trying to unmarshal a nil response from DynamoDB (table doesn't exist or item doesn't exist)

**Solution:**
1. Create the `requestLimit` table
2. Initialize it with the default value (see step 4 above)

### Error: "ParameterNotFound" when calling API

**Cause:** SSM Parameter for JWT public key doesn't exist

**Solution:** Create the SSM parameter with the public key (see SSM Parameter section above)

### Error: "AccessDeniedException" when creating tables

**Cause:** Your AWS credentials don't have DynamoDB permissions

**Solution:** Ensure your AWS user/role has:
- `dynamodb:CreateTable`
- `dynamodb:PutItem`
- `dynamodb:DescribeTable`
- `dynamodb:ListTables`

---

## 🚀 Quick Setup Command

Run this to set up everything:

```bash
# 1. Create all tables
./setup-dynamodb-tables.sh us-east-1

# 2. Verify tables
aws dynamodb list-tables --region us-east-1

# 3. Test API
curl https://j31g91e2fa.execute-api.us-east-1.amazonaws.com/Prod/health-check
```

---

## 📝 Notes

- Tables are created with **PAY_PER_REQUEST** billing mode (no capacity planning needed)
- The `requestLimit` table is initialized with a default value of 1000
- You can adjust the initial `limitValue` based on your needs
- All tables are created in the same region as your Lambda functions
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Excellent troubleshooting and reference sections!

The documentation concludes with valuable resources:

  • Actionable checklist for post-deployment verification
  • Comprehensive troubleshooting guide covering common error scenarios
  • Quick setup workflow for rapid deployment
  • Important notes about billing mode and configuration

Minor formatting: Line 184 has a trailing space (detected by markdownlint).

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

184-184: Trailing spaces
Expected: 0 or 2; Actual: 1

(MD009, no-trailing-spaces)

🤖 Prompt for AI Agents
In POST_DEPLOYMENT_SETUP.md around lines 152 to 228, there is a minor formatting
issue: line 184 contains a trailing space flagged by markdownlint; remove the
trailing whitespace on line 184 (and re-save the file) so the line ends cleanly
with no extra spaces, then run your linter/markdownlint to confirm the fix.

Comment on lines +6 to +26
set -e

REGION=${1:-us-east-1}

echo "🚀 Setting up DynamoDB tables in region: $REGION"
echo ""

# Table 1: featureFlag
echo "Creating table: featureFlag"
aws dynamodb create-table \
--table-name featureFlag \
--attribute-definitions \
AttributeName=id,AttributeType=S \
--key-schema \
AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region $REGION \
--no-cli-pager

echo "✅ Created featureFlag table"
echo ""
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Quote the $REGION variable and consider idempotency.

The script uses set -e which will exit if any command fails. If the tables already exist, the script will fail. Additionally, the $REGION variable should be quoted to prevent word splitting and globbing issues.

🔎 Proposed improvements

Option 1: Add error handling to make the script idempotent

 # Table 1: featureFlag
 echo "Creating table: featureFlag"
 aws dynamodb create-table \
   --table-name featureFlag \
   --attribute-definitions \
     AttributeName=id,AttributeType=S \
   --key-schema \
     AttributeName=id,KeyType=HASH \
   --billing-mode PAY_PER_REQUEST \
-  --region $REGION \
-  --no-cli-pager
+  --region "$REGION" \
+  --no-cli-pager 2>/dev/null || echo "⚠️  featureFlag table already exists, skipping..."

Option 2: Check table existence before creation

Add this function at the beginning of the script:

table_exists() {
  aws dynamodb describe-table --table-name "$1" --region "$REGION" &>/dev/null
}

Then use it before each create-table command:

if ! table_exists "featureFlag"; then
  echo "Creating table: featureFlag"
  aws dynamodb create-table \
    # ... rest of command
else
  echo "⚠️  featureFlag table already exists, skipping..."
fi

Apply similar quoting to all $REGION references throughout the script (lines 22, 39, 54, 64, 68, 72, 85).

📝 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
set -e
REGION=${1:-us-east-1}
echo "🚀 Setting up DynamoDB tables in region: $REGION"
echo ""
# Table 1: featureFlag
echo "Creating table: featureFlag"
aws dynamodb create-table \
--table-name featureFlag \
--attribute-definitions \
AttributeName=id,AttributeType=S \
--key-schema \
AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region $REGION \
--no-cli-pager
echo "✅ Created featureFlag table"
echo ""
set -e
REGION=${1:-us-east-1}
echo "🚀 Setting up DynamoDB tables in region: $REGION"
echo ""
# Table 1: featureFlag
echo "Creating table: featureFlag"
aws dynamodb create-table \
--table-name featureFlag \
--attribute-definitions \
AttributeName=id,AttributeType=S \
--key-schema \
AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region "$REGION" \
--no-cli-pager 2>/dev/null || echo "⚠️ featureFlag table already exists, skipping..."
echo "✅ Created featureFlag table"
echo ""
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 22-22: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
In setup-dynamodb-tables.sh around lines 6 to 26, the script uses unquoted
$REGION (risking word-splitting/globbing) and will fail if the table already
exists due to set -e; make it idempotent by adding a helper function
(table_exists) that calls aws dynamodb describe-table --table-name "$1" --region
"$REGION" and returns success if the table exists, then wrap each aws dynamodb
create-table invocation in an if ! table_exists "featureFlag"; then ... else ...
fi block to skip creation when present, and ensure every $REGION reference is
quoted as "$REGION" throughout the script.

Comment on lines +90 to +92
Policies:
- DynamoDBCrudPolicy:
TableName: requestLimit
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify if CorsLambda actually performs write operations on requestLimit table

echo "=== Searching for DynamoDB write operations in corsLambda ==="
rg -nP --type=go -C3 '\b(PutItem|UpdateItem|DeleteItem|TransactWriteItems|BatchWriteItem)\b' corsLambda/

echo -e "\n=== Searching for requestLimit table references in corsLambda ==="
rg -nP --type=go -C3 'requestLimit' corsLambda/

echo -e "\n=== General DynamoDB operations in corsLambda ==="
rg -nP --type=go -C3 '\b(GetItem|Query|Scan)\b' corsLambda/

Repository: RealDevSquad/feature-flag-backend

Length of output: 256


🏁 Script executed:

#!/bin/bash
# Find corsLambda related files
echo "=== Finding corsLambda references ==="
find . -type f -name "*cors*" -o -name "*template*" | head -20

echo -e "\n=== Checking template.yaml around lines 85-95 ==="
cat -n template.yaml | sed -n '85,95p'

echo -e "\n=== Finding Go files with cors or CORS ==="
rg -l --type=go -i cors | head -10

echo -e "\n=== Listing directory structure to find Lambda code ==="
ls -la | grep -E "^d"
git ls-files | grep -E "\.go$" | head -20

Repository: RealDevSquad/feature-flag-backend

Length of output: 2560


🏁 Script executed:

#!/bin/bash
echo "=== corsLambda/main.go ==="
cat -n corsLambda/main.go

echo -e "\n=== rateLimiterLambda/main.go ==="
cat -n rateLimiterLambda/main.go | head -50

echo -e "\n=== template.yaml - CorsLambda definition ==="
cat -n template.yaml | sed -n '75,100p'

Repository: RealDevSquad/feature-flag-backend

Length of output: 3519


🏁 Script executed:

#!/bin/bash
echo "=== layer/utils/CheckRequestAllowed.go ==="
cat -n layer/utils/CheckRequestAllowed.go

echo -e "\n=== layer/utils/Constants.go ==="
cat -n layer/utils/Constants.go

Repository: RealDevSquad/feature-flag-backend

Length of output: 5246


Restrict DynamoDBCrudPolicy to only required operations.

The CorsLambda performs rate limiting checks on the requestLimit table via CheckRequestAllowed, which only performs GetItem (read) and PutItem (write) operations. The current DynamoDBCrudPolicy grants unnecessary permissions including DeleteItem and UpdateItem. Use a more restrictive policy such as DynamoDBWritePolicy or a custom inline policy limited to GetItem and PutItem only.

🤖 Prompt for AI Agents
In template.yaml around lines 90 to 92, the IAM role uses DynamoDBCrudPolicy for
the requestLimit table which grants unnecessary CRUD permissions; replace it
with a more restrictive policy that grants only the exact actions used by
CheckRequestAllowed (DynamoDB:GetItem and DynamoDB:PutItem) on the requestLimit
table ARN (optionally include arn:aws:dynamodb:*:*:table/requestLimit/index/* if
index access is needed), implemented either by switching to a minimal managed
policy (if available) or by adding a custom inline policy that explicitly lists
only GetItem and PutItem for that table.

Comment on lines +112 to +122
Policies:
- DynamoDBCrudPolicy:
TableName: featureFlag
- DynamoDBCrudPolicy:
TableName: featureFlagUserMapping
- DynamoDBCrudPolicy:
TableName: requestLimit
- SSMParameterReadPolicy:
ParameterName: PROD_RDS_BACKEND_PUBLIC_KEY
- SSMParameterReadPolicy:
ParameterName: STAGING_RDS_BACKEND_PUBLIC_KEY
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's explore the directory structure to find health-check related files
echo "=== Finding health-check related files ==="
find . -type f -name "*health*" -o -name "*check*" | grep -E "\.(go|py|js|ts)$" | head -20

echo -e "\n=== Listing repository structure ==="
ls -la | head -20

echo -e "\n=== Finding template.yaml ==="
find . -name "template.yaml" -type f

Repository: RealDevSquad/feature-flag-backend

Length of output: 1445


🏁 Script executed:

#!/bin/bash
# Search for health check function implementation
echo "=== Searching for health check handler or function ==="
rg -i "health.*check|check.*health" --type=go -l

echo -e "\n=== Searching for DynamoDB operations in codebase ==="
rg "DynamoDB|PutItem|UpdateItem|DeleteItem|GetItem|Query|Scan" --type=go -l | head -10

Repository: RealDevSquad/feature-flag-backend

Length of output: 460


🏁 Script executed:

#!/bin/bash
# Check the size and content of template.yaml
wc -l template.yaml

echo -e "\n=== Searching for HealthCheckFunction in template.yaml ==="
rg -nP "HealthCheckFunction|health" template.yaml -i

echo -e "\n=== Viewing lines 100-130 of template.yaml ==="
sed -n '100,130p' template.yaml

Repository: RealDevSquad/feature-flag-backend

Length of output: 1135


🏁 Script executed:

#!/bin/bash
# Search more broadly for what this function actually does
echo "=== Searching for code/handler referenced by HealthCheckFunction ==="
rg "CodeUri|Handler" template.yaml | head -20

echo -e "\n=== List all Lambda functions in template ==="
rg "^\s+\w+Function:" template.yaml

Repository: RealDevSquad/feature-flag-backend

Length of output: 1435


🏁 Script executed:

#!/bin/bash
# Find and list health-check directory contents
echo "=== Contents of health-check directory ==="
find health-check/ -type f 2>/dev/null | head -20

echo -e "\n=== Files in health-check with line counts ==="
find health-check/ -type f -name "*.go" 2>/dev/null | xargs wc -l

echo -e "\n=== Main health-check file content ==="
find health-check/ -name "*.go" -type f | head -1 | xargs cat -n

Repository: RealDevSquad/feature-flag-backend

Length of output: 780


🏁 Script executed:

#!/bin/bash
# Search for actual database operations in health-check
echo "=== DynamoDB operations in health-check ==="
rg "PutItem|UpdateItem|DeleteItem|GetItem|Query|Scan|BatchGetItem|BatchWriteItem|TransactWrite" health-check/ --type=go -C 2

echo -e "\n=== SSM operations in health-check ==="
rg "ssm|GetParameter|ParameterName" health-check/ --type=go -C 2

Repository: RealDevSquad/feature-flag-backend

Length of output: 160


Remove unused IAM policies from HealthCheckFunction.

HealthCheckFunction currently has DynamoDBCrudPolicy for all three tables and SSMParameterReadPolicy for both keys, but the implementation performs no database or SSM operations. It simply returns a hardcoded response without accessing any AWS resources. Remove all DynamoDB and SSM policies to follow the principle of least privilege.

🤖 Prompt for AI Agents
In template.yaml around lines 112 to 122, the HealthCheckFunction has
unnecessary DynamoDBCrudPolicy entries for tables featureFlag,
featureFlagUserMapping, requestLimit and SSMParameterReadPolicy entries for
PROD_RDS_BACKEND_PUBLIC_KEY and STAGING_RDS_BACKEND_PUBLIC_KEY; remove those
five policy entries from the Policies list for HealthCheckFunction so the
function's IAM role only contains the minimal required permissions (e.g., Lambda
basic execution) since the handler does not access DynamoDB or SSM.

Comment on lines +142 to +148
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- lambda:PutFunctionConcurrency
Resource: '*'
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider scoping Lambda concurrency policy to specific functions.

The RateLimiterFunction has permission to set concurrency on all Lambda functions (Resource: '*'). If the rate limiter only manages a known set of functions, consider scoping the policy to specific function ARNs for better security.

🔎 Proposed refinement if applicable
       Policies:
         - Version: '2012-10-17'
           Statement:
             - Effect: Allow
               Action:
                 - lambda:PutFunctionConcurrency
-              Resource: '*'
+              Resource: 
+                - !GetAtt CreateFeatureFlagFunction.Arn
+                - !GetAtt UpdateFeatureFlagFunction.Arn
+                # Add other functions that need rate limiting

This is only applicable if you know the specific set of functions that require rate limiting.

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

🤖 Prompt for AI Agents
In template.yaml around lines 142-148 the IAM policy for RateLimiterFunction
allows lambda:PutFunctionConcurrency on all functions (Resource: '*'); limit
this to only the functions the rate limiter actually manages by replacing '*'
with the specific Lambda function ARNs (or ARNs built with CloudFormation
intrinsics like !GetAtt or !Sub for each target function), or alternatively
restrict to per-account/region ARNs if full names are known
(arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:YourFunctionName).
Update the template to accept the target function names/ARNS as parameters or
reference the existing function resources so the policy lists only those ARNs
instead of '*'.

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