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