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.
Recommended Improvements
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
-
High Priority:
- Implement temporary credentials with STS
- Add credential rotation
- Remove hardcoded credentials from
update-aws-creds.sh
-
Medium Priority:
- Migrate to IAM instance profiles (if on EC2)
- Update to AWS SDK v3
- Implement least privilege IAM policies
-
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