Skip to main content
info

This documentation is automatically synchronized from the claude-hub repository. Last updated: 2025-06-01

AWS Authentication Best Practices for Claude Repository

Current Implementation​

The Claude service currently uses static AWS credentials configured via environment variables:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION

These credentials are passed to Docker containers running Claude Code CLI to interact with AWS Bedrock.

1. Use IAM Instance Profiles (EC2)​

If running on AWS EC2, use IAM instance profiles instead of static credentials:

// Check for instance metadata availability first
const AWS = require('@aws-sdk/client-sts');

async function getCredentials() {
// Try instance metadata first
if (await isRunningOnEC2()) {
// AWS SDK will automatically use instance profile
return; // No explicit credentials needed
}

// Fall back to environment variables
return {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: process.env.AWS_REGION
};
}

2. Implement Temporary Credentials with STS​

Use AWS Security Token Service (STS) to generate temporary credentials:

const { STSClient, AssumeRoleCommand } = require('@aws-sdk/client-sts');

async function getTemporaryCredentials(roleArn) {
const stsClient = new STSClient({ region: process.env.AWS_REGION });

const command = new AssumeRoleCommand({
RoleArn: roleArn,
RoleSessionName: `claude-webhook-${Date.now()}`,
DurationSeconds: 3600 // 1 hour
});

const response = await stsClient.send(command);
return response.Credentials;
}

3. Use AWS IAM Roles for Service Accounts (IRSA) in Kubernetes​

If running in Kubernetes/EKS:

apiVersion: v1
kind: ServiceAccount
metadata:
name: claude-webhook
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/claude-webhook-role

4. Implement Credential Rotation​

Add automatic credential rotation:

class CredentialManager {
constructor() {
this.credentials = null;
this.expirationTime = null;
}

async getCredentials() {
if (!this.credentials || this.isExpired()) {
this.credentials = await this.refreshCredentials();
this.expirationTime = Date.now() + (50 * 60 * 1000); // 50 minutes
}
return this.credentials;
}

isExpired() {
return !this.expirationTime || Date.now() > this.expirationTime;
}

async refreshCredentials() {
// Implement credential refresh logic
return getTemporaryCredentials(process.env.AWS_ROLE_ARN);
}
}

5. Use AWS SDK v3 Best Practices​

Update to AWS SDK v3 and use credential providers:

const { fromInstanceMetadata, fromIni, fromProcess } = require('@aws-sdk/credential-providers');
const { defaultProvider } = require('@aws-sdk/credential-provider-node');

// Create a credential provider chain
const credentialProvider = defaultProvider({
region: process.env.AWS_REGION,
// Try these providers in order
providers: [
fromInstanceMetadata({ timeout: 1000 }),
fromIni({ profile: process.env.AWS_PROFILE }),
fromProcess(),
// Environment variables are checked by default
]
});

6. Secure Environment Variable Handling​

Update claudeService.js to use more secure credential passing:

// Instead of passing raw credentials, pass a credential provider
const credentialProvider = await getCredentialProvider();
const credentials = await credentialProvider();

// Pass temporary credentials if needed
const envVars = {
AWS_ACCESS_KEY_ID: credentials.accessKeyId,
AWS_SECRET_ACCESS_KEY: credentials.secretAccessKey,
AWS_SESSION_TOKEN: credentials.sessionToken, // Include for temporary creds
AWS_REGION: process.env.AWS_REGION,
// ... other env vars
};

7. Implement Least Privilege IAM Policies​

Create a specific IAM policy for Claude webhook:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:*:*:model/us.anthropic.claude-3-*"
]
}
]
}

8. Container-Specific Security​

For Docker containers, mount credentials securely:

// Use Docker secrets or volumes for credentials
const dockerCommand = `docker run --rm \\
--privileged \\
--mount type=secret,id=aws_creds,target=/run/secrets/aws-credentials \\
${dockerImageName}`;

9. Monitoring and Auditing​

Add CloudTrail monitoring for credential usage:

const { CloudTrailClient, PutEventsCommand } = require('@aws-sdk/client-cloudtrail');

async function logCredentialUsage(action, success) {
const event = {
eventTime: new Date(),
eventName: 'ClaudeWebhookCredentialUsage',
eventSource: 'claude-webhook',
sourceIPAddress: req.ip,
userAgent: req.headers['user-agent'],
resources: [{
type: 'AWS::IAM::Credentials',
name: action
}],
outcome: success ? 'Success' : 'Failure'
};

// Log to CloudTrail or your monitoring system
}

Implementation Priority​

  1. High Priority:

    • Implement temporary credentials with STS
    • Add credential rotation
    • Remove hardcoded credentials from update-aws-creds.sh
  2. Medium Priority:

    • Migrate to IAM instance profiles (if on EC2)
    • Update to AWS SDK v3
    • Implement least privilege IAM policies
  3. Low Priority:

    • Add CloudTrail monitoring
    • Implement container-specific secrets

Security Checklist​

  • Remove static credentials from code and scripts
  • Implement credential rotation
  • Use temporary credentials whenever possible
  • Apply least privilege IAM policies
  • Monitor credential usage
  • Secure credential passing to containers
  • Add credential expiration handling
  • Document credential requirements

Testing​

After implementing changes, test with:

# Test with instance profile
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
./test-claude-api.js owner/repo

# Test with assumed role
export AWS_ROLE_ARN="arn:aws:iam::123456789012:role/claude-webhook-role"
./test-claude-api.js owner/repo

# Test credential rotation
./test-credential-rotation.js

References​