# 🔐 IAM Role Authentication Setup Guide

## Overview

LogStack now supports **two authentication methods** for AWS S3:

1. **Access Keys (Default)** - Traditional method using AWS credentials
2. **IAM Role** - Automatic authentication for AWS environments (EC2, ECS, Lambda, EKS)

---

## 🎯 When to Use IAM Role?

**Use IAM Role when:**
- ✅ Running on AWS EC2 instances
- ✅ Running on AWS ECS (Fargate or EC2)
- ✅ Running on AWS Lambda functions
- ✅ Running on AWS EKS (Kubernetes)
- ✅ You want to avoid storing AWS credentials in code
- ✅ Better security compliance requirements

**Use Access Keys when:**
- ⚠️ Running on non-AWS servers (local, DigitalOcean, Heroku, etc.)
- ⚠️ Running locally for development/testing
- ⚠️ Using S3-compatible storage (MinIO, DigitalOcean Spaces)

---

## 🚀 Quick Start

### Method 1: Access Keys (Default)

```javascript
const { init } = require('log-archiver');

await init({
  dbUri: 'mongodb://localhost:27017/myapp',
  uploadProvider: 's3',
  
  s3: {
    bucket: 'my-logs-bucket',
    region: 'us-east-1',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  }
});
```

**.env file:**
```env
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=abcd1234...
```

---

### Method 2: IAM Role (AWS Environments)

```javascript
const { init } = require('log-archiver');

await init({
  dbUri: 'mongodb://localhost:27017/myapp',
  uploadProvider: 's3',
  
  s3: {
    bucket: 'my-logs-bucket',
    region: 'us-east-1',
    useIAMRole: true, // ✅ Enable IAM role
    // ⚠️ No accessKeyId or secretAccessKey needed
  }
});
```

**.env file:**
```env
# No AWS credentials needed!
# AWS SDK will automatically use IAM role
```

---

## 📋 IAM Role Setup Instructions

### 1. Create IAM Policy

Create a policy with S3 permissions:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "LogStackS3Access",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:DeleteObject",
        "s3:PutObjectAcl"
      ],
      "Resource": [
        "arn:aws:s3:::my-logs-bucket",
        "arn:aws:s3:::my-logs-bucket/*"
      ]
    }
  ]
}
```

**Steps:**
1. Go to AWS Console → IAM → Policies
2. Click "Create Policy"
3. Choose JSON tab
4. Paste the policy above (replace bucket name)
5. Name it: `LogStack-S3-Access`
6. Click "Create Policy"

---

### 2. Create IAM Role (for EC2)

**Steps:**
1. Go to AWS Console → IAM → Roles
2. Click "Create Role"
3. Select **AWS Service** → **EC2**
4. Click "Next: Permissions"
5. Search and select `LogStack-S3-Access` policy
6. Click "Next: Tags" (optional)
7. Click "Next: Review"
8. Name it: `LogStack-EC2-Role`
9. Click "Create Role"

---

### 3. Attach Role to EC2 Instance

**For New Instance:**
1. Launch EC2 instance
2. In "Configure Instance" step
3. IAM Role → Select `LogStack-EC2-Role`

**For Existing Instance:**
1. Select your EC2 instance
2. Actions → Security → Modify IAM Role
3. Select `LogStack-EC2-Role`
4. Click "Update IAM Role"

---

### 4. For ECS (Fargate/EC2)

**Task Role:**
1. Go to AWS Console → ECS → Task Definitions
2. Create/Edit task definition
3. In "Task Role" section
4. Select `LogStack-EC2-Role` (or create new role with same policy)
5. Save task definition

**Task Definition JSON:**
```json
{
  "taskRoleArn": "arn:aws:iam::123456789012:role/LogStack-EC2-Role",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "logstack-app",
      "image": "your-app-image",
      "environment": [
        {
          "name": "USE_IAM_ROLE",
          "value": "true"
        }
      ]
    }
  ]
}
```

---

### 5. For AWS Lambda

**Steps:**
1. Go to AWS Console → Lambda → Functions
2. Select your function
3. Configuration → Permissions
4. Execution Role → Edit
5. Attach `LogStack-S3-Access` policy
6. Save

**Or create new role:**
```javascript
// Lambda function configuration
{
  "Role": "arn:aws:iam::123456789012:role/LogStack-Lambda-Role",
  "Environment": {
    "Variables": {
      "USE_IAM_ROLE": "true"
    }
  }
}
```

---

## 🔍 Verification

### Test IAM Role Setup

```javascript
const { init, saveApiLog } = require('log-archiver');

async function testIAMRole() {
  try {
    console.log('🧪 Testing IAM Role authentication...');
    
    await init({
      dbUri: process.env.MONGODB_URI,
      uploadProvider: 's3',
      
      s3: {
        bucket: process.env.S3_BUCKET,
        region: process.env.AWS_REGION,
        useIAMRole: true, // ✅ Using IAM role
      },
      
      compression: {
        enabled: true,
      }
    });
    
    // Test log save
    await saveApiLog({
      method: 'GET',
      path: '/test',
      requestBody: { test: true },
      responseStatus: 200,
    });
    
    console.log('✅ IAM Role authentication working!');
    console.log('✅ Logs saved successfully');
    
  } catch (error) {
    console.error('❌ IAM Role test failed:', error.message);
    
    if (error.message.includes('credentials')) {
      console.log('\n⚠️ Possible issues:');
      console.log('1. IAM role not attached to EC2/ECS/Lambda');
      console.log('2. IAM role missing S3 permissions');
      console.log('3. Bucket name or region incorrect');
    }
  }
}

testIAMRole();
```

---

## 🛡️ Security Best Practices

### ✅ DO:
- Use IAM roles on AWS environments (more secure)
- Apply least privilege principle (only necessary S3 permissions)
- Use different buckets for different environments
- Enable S3 bucket encryption
- Use VPC endpoints for S3 (better performance)
- Rotate access keys regularly (if using access keys)

### ❌ DON'T:
- Don't hardcode AWS credentials in code
- Don't commit .env files to Git
- Don't use root account credentials
- Don't give full S3 access (use specific bucket ARN)
- Don't share IAM credentials

---

## 🐛 Troubleshooting

### Error: "Missing credentials in config"

**Solution:**
```javascript
// Make sure to set useIAMRole: true
s3: {
  bucket: 'my-bucket',
  region: 'us-east-1',
  useIAMRole: true, // ✅ Add this
}
```

### Error: "Access Denied"

**Solutions:**
1. Check IAM role has correct permissions
2. Verify bucket name is correct
3. Ensure bucket region matches config
4. Check bucket policy allows your IAM role

### Error: "Unable to locate credentials"

**Solutions:**
- **EC2**: Ensure IAM role is attached to instance
- **ECS**: Ensure task role is configured
- **Lambda**: Ensure execution role has S3 permissions
- **Local**: Use access keys instead of IAM role

---

## 📚 Complete Examples

### EC2 Production Setup

```javascript
const { init, createDailyJobs, runHourlyJob } = require('log-archiver');

async function startProductionApp() {
  // Initialize with IAM role (no credentials needed)
  await init({
    dbUri: process.env.MONGODB_URI,
    uploadProvider: 's3',
    
    s3: {
      bucket: 'production-logs-bucket',
      region: 'us-east-1',
      useIAMRole: true, // ✅ AWS SDK uses EC2 instance role
      keyPrefix: 'app_logs/',
    },
    
    compression: {
      enabled: true,
      format: 'gzip',
      level: 6,
    },
    
    retention: {
      database: {
        autoCleanup: true,
        apiLogs: 90, // 90 days
      },
      storage: {
        autoCleanup: true,
        files: 365, // 1 year
      },
    },
    
    cron: {
      dailyCron: '0 0 * * *',
      hourlyCron: '0 * * * *',
    },
  });
  
  console.log('✅ Production app started with IAM role authentication');
}

startProductionApp();
```

### Development Setup (Local)

```javascript
const { init } = require('log-archiver');

async function startDevApp() {
  // Initialize with access keys for local development
  await init({
    dbUri: 'mongodb://localhost:27017/dev',
    uploadProvider: 's3',
    
    s3: {
      bucket: 'dev-logs-bucket',
      region: 'us-east-1',
      // useIAMRole: false, // Default: uses access keys
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    },
  });
  
  console.log('✅ Development app started with access keys');
}

startDevApp();
```

---

## 🔄 Migration Guide

### From Access Keys to IAM Role

**Before (Access Keys):**
```javascript
s3: {
  bucket: 'my-bucket',
  region: 'us-east-1',
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
}
```

**After (IAM Role):**
```javascript
s3: {
  bucket: 'my-bucket',
  region: 'us-east-1',
  useIAMRole: true, // ✅ Add this line
  // Remove accessKeyId and secretAccessKey
}
```

**Steps:**
1. Create IAM role with S3 permissions (see above)
2. Attach role to EC2/ECS/Lambda
3. Update code to set `useIAMRole: true`
4. Remove AWS credentials from .env file
5. Deploy and test
6. Delete old access keys from AWS Console

---

## 📞 Support

If you encounter issues:
1. Check AWS CloudWatch logs for detailed errors
2. Verify IAM role permissions in AWS Console
3. Test S3 access using AWS CLI: `aws s3 ls s3://your-bucket`
4. Review package documentation
5. Open GitHub issue with error details

---

**Remember:** IAM roles provide better security by eliminating the need to manage and rotate access keys! 🔒
