Skip to content

smadhav/box-lambda-function

Repository files navigation

Box API Access Token Lambda Function

This AWS Lambda function generates and temporarily stores Box API access tokens using OAuth2 client credentials flow. The access tokens are stored in DynamoDB with the folder ID as the key and have a TTL (Time To Live) for automatic cleanup.

Features

  • ✅ Generates Box API access tokens using OAuth2 client credentials flow
  • ✅ Temporarily stores access tokens in DynamoDB with folder ID as key
  • ✅ Automatic token expiration and cleanup via TTL
  • ✅ Secure credential management using AWS Secrets Manager
  • ✅ Comprehensive error handling and logging
  • ✅ API Gateway integration for HTTP endpoints
  • ✅ CORS support for web applications

Architecture

API Gateway → Lambda Function → Box API (OAuth2)
                    ↓
              DynamoDB (Token Storage)
                    ↓
            Secrets Manager (Credentials)

Prerequisites

  1. AWS Account with appropriate permissions
  2. Box Developer Account with API access
  3. AWS CLI configured with credentials
  4. Node.js 18.x or higher
  5. Terraform (optional, for infrastructure deployment)

Box API Setup

  1. Go to Box Developer Console
  2. Create a new app or use an existing one
  3. Configure the app with OAuth2 settings
  4. Note down the Client ID, Client Secret, and Enterprise ID
  5. For enterprise authentication, you'll need:
    • client_id: Your Box app's client ID
    • client_secret: Your Box app's client secret
    • box_subject_type: Usually "enterprise"
    • box_subject_id: Your Box enterprise ID (e.g., "281779040")

Deployment Options

Option 1: Using Terraform (Recommended)

  1. Configure variables:

    cd terraform
    cp terraform.tfvars.example terraform.tfvars
    # Edit terraform.tfvars with your values
  2. Deploy infrastructure:

    terraform init
    terraform plan
    terraform apply
  3. Deploy Lambda function:

    cd ..
    chmod +x deploy.sh
    ./deploy.sh

Option 2: Using Serverless Framework

  1. Install Serverless:

    npm install -g serverless
  2. Deploy:

    serverless deploy

Option 3: Manual AWS Console Deployment

  1. Create DynamoDB Table:

    • Table name: box-lambda-function-dev-tokens
    • Partition key: folderId (String)
    • Enable TTL with attribute name: ttl
  2. Create Secrets Manager Secret:

    • Secret name: box-lambda-function-dev-box-credentials
    • Secret value:
      {
        "clientId": "your-box-client-id",
        "clientSecret": "your-box-client-secret",
        "boxSubjectType": "enterprise",
        "boxSubjectId": "your-enterprise-id"
      }
  3. Create Lambda Function:

    • Runtime: Node.js 18.x
    • Handler: index.handler
    • Environment variables:
      • TOKEN_TABLE_NAME: box-lambda-function-dev-tokens
      • BOX_SECRET_NAME: box-lambda-function-dev-box-credentials

Configuration

Environment Variables

Variable Description Default
TOKEN_TABLE_NAME DynamoDB table name for token storage box-lambda-function-dev-tokens
BOX_SECRET_NAME Secrets Manager secret name box-lambda-function-dev-box-credentials

IAM Permissions Required

The Lambda execution role needs the following permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:*:*:secret:box-lambda-function-*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem",
        "dynamodb:Query",
        "dynamodb:Scan"
      ],
      "Resource": "arn:aws:dynamodb:*:*:table/box-lambda-function-*"
    }
  ]
}

Usage

API Endpoints

POST /box/token

Creates a new access token for the provided folder ID.

Request Body:

{
  "folder-id": "your-folder-id"
}

Response:

{
  "success": true,
  "folderId": "your-folder-id",
  "message": "Access token generated and stored successfully",
  "expiresAt": "2024-01-15T10:30:00.000Z"
}

GET /box/token/{folderId}

Retrieves an existing access token for the folder ID.

Response:

{
  "success": true,
  "folderId": "your-folder-id",
  "accessToken": "your-access-token",
  "expiresAt": "2024-01-15T10:30:00.000Z"
}

Direct Lambda Invocation

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda({ region: 'us-east-1' });

const params = {
  FunctionName: 'box-access-token-handler-dev',
  Payload: JSON.stringify({
    'folder-id': 'your-folder-id'
  })
};

lambda.invoke(params, (err, data) => {
  if (err) console.error(err);
  else console.log(JSON.parse(data.Payload));
});

Testing

Run the test script to verify the function works correctly:

node test-function.js

Error Handling

The function handles various error scenarios:

  • 400 Bad Request: Missing or invalid folder ID
  • 500 Internal Server Error: Box API errors, credential issues, or DynamoDB errors

Example error response:

{
  "error": "folder-id is required",
  "message": "Please provide a valid folder-id in the request"
}

Token Management

  • TTL: Access tokens expire after 1 hour (3600 seconds)
  • Storage: Tokens are stored in DynamoDB with automatic cleanup
  • Security: Credentials are stored securely in AWS Secrets Manager
  • Uniqueness: Each folder ID can have only one active token

Monitoring and Logging

  • CloudWatch Logs: All function executions are logged
  • Error Tracking: Detailed error messages for debugging
  • Performance: Function timeout set to 30 seconds
  • Memory: 256 MB allocated by default

Security Considerations

  1. Credentials: Never hardcode Box API credentials in the code
  2. IAM: Use least privilege principle for IAM roles
  3. Encryption: DynamoDB and Secrets Manager provide encryption at rest
  4. Network: Use VPC endpoints if needed for additional security
  5. Monitoring: Enable CloudTrail for API call auditing

Troubleshooting

Common Issues

  1. "Failed to retrieve Box API credentials"

    • Check if the secret exists in Secrets Manager
    • Verify the secret contains valid JSON with clientId and clientSecret
    • Ensure Lambda has permission to access the secret
  2. "Box API error"

    • Verify Box API credentials are correct
    • Check if the Box app is properly configured
    • Ensure the Box API endpoint is accessible
    • Verify enterprise ID is correct for your Box organization
    • Check if the app has enterprise-level permissions
  3. "Failed to store access token"

    • Check if the DynamoDB table exists
    • Verify Lambda has DynamoDB permissions
    • Ensure the table has the correct schema

Debug Mode

Enable debug logging by adding this environment variable:

DEBUG=true

Cost Optimization

  • DynamoDB: Uses on-demand billing, pay only for what you use
  • Lambda: Pay per invocation, with free tier available
  • Secrets Manager: $0.40 per secret per month
  • API Gateway: Pay per API call

Support

For issues or questions:

  1. Check CloudWatch logs for detailed error messages
  2. Verify all prerequisites are met
  3. Test with the provided test script
  4. Review the troubleshooting section

License

MIT License - see LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published