aws-samples / aws-samples/resource-autotagger

Fix for Email-Based IAM Users: SSM Parameter Validation Error

Open
#11 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
11
Forks
1
PR merge metrics
No merged PRs in 30d

Description

## Fix for Email-Based IAM Users: SSM Parameter Validation Error

### Issue
When using email addresses as IAM usernames (common in organizations), the auto-tagging Lambda function fails with SSM parameter validation errors, preventing all resource tagging from working.

### Error Encountered
```
ValidationException: The parameter doesn't meet the parameter name requirements. The parameter name must begin with a forward slash "/". It can't be prefixed with "aws" or "ssm" (case-insensitive). It must use only letters, numbers, or the following symbols: . (period), - (hyphen), _ (underscore). Special characters are not allowed.
```

### Environment
- **Region**: ap-northeast-1 (Tokyo)
- **Runtime**: nodejs18.x
- **CDK Version**: 2.1020.2
- **Repository Version**: Latest (commit: 9bc80e8)
- **Use Case**: Organization using email addresses for IAM usernames (e.g., `john.doe@company.com`)

### Root Cause
The `get_ssm_parameter_tags` function creates SSM parameter paths using usernames directly, but email addresses contain `@` symbols which are invalid for SSM parameter names:

```javascript
// This fails when iam_user_name = "john.doe@company.com"
path_string = `/auto-tag/${iam_user_name}/tag`; // → /auto-tag/john.doe@company.com/tag (invalid)
```

### ✅ Working Solution

I successfully fixed this issue by modifying the `get_ssm_parameter_tags` function in `handlers/resource-auto-tag/index.mjs`. Here's what worked:

```javascript
async function get_ssm_parameter_tags(iam_user_name, role_name, user_id) {
// Sanitize function to handle email addresses and other special characters
function sanitizeParameterName(name) {
return name ? name.replace(/[^a-zA-Z0-9._-]/g, '') : '';
}

var path_string = '';
if (iam_user_name != null) {
const sanitized_user = sanitizeParameterName(iam_user_name);
path_string = `/auto-tag/${sanitized_user}/tag`;
}
else {
if (role_name != null && user_id !=null) {
const sanitized_role = sanitizeParameterName(role_name);
const sanitized_user_id = sanitizeParameterName(user_id);
path_string = `/auto-tag/${sanitized_role}/${sanitized_user_id}/tag`;
} else {
path_string = '';
}
}

if (path_string != '') {
try {
var params = { Path: path_string, Recursive: true, WithDecryption: true };
var command = new GetParametersByPathCommand(params);
var get_parameter_response = await ssmClient.send(command);
if (get_parameter_response.Parameters != undefined && get_parameter_response.Parameters != null && get_parameter_response.Parameters.length > 0) {
var tag_list = [];
for (var i=0; i< get_parameter_response.Parameters.length;i++) {
var path_components = get_parameter_response.Parameters[i]["Name"].split("/");
var tag_key = path_components[path_components.length-1];
tag_list.push({"Key": tag_key, "Value": get_parameter_response.Parameters[i]["Value"]});
}
return tag_list;
} else {
return null;
}
} catch (error) {
console.warn('SSM parameter access failed, continuing without SSM tags:', error.message);
return null;
}
} else {
return null;
}
}
```

### How to Apply the Fix

1. Open AWS Lambda console
2. Find the main auto-tagging function (usually named `ResourceAutoTagCdkStack-resourceautotag...`)
3. Go to the Code tab
4. Find the `get_ssm_parameter_tags` function (around line 186)
5. Replace the entire function with the code above
6. Click "Deploy"

### Test Results

**Before Fix:**
- ❌ Lambda function crashed with ValidationException
- ❌ No resources got tagged
- ❌ Error: `The parameter doesn't meet the parameter name requirements`

**After Fix:**
- ✅ Auto-tagging works successfully
- ✅ Resources get tagged with: `IAM User Name`, `Date created`, etc.
- ✅ Graceful handling when SSM parameters don't exist
- ✅ Email addresses like `john.doe@company.com` now work

### Example Transformation
```
Email: john.doe@company.com
SSM Path Before: /auto-tag/john.doe@company.com/tag (INVALID ❌)
SSM Path After: /auto-tag/johndoecompanycom/tag (VALID ✅)
```

### Benefits of This Approach

1. **Works for all organizations** using email-based IAM usernames
2. **Non-breaking**: Existing functionality preserved
3. **Error resilient**: Continues tagging even if SSM access fails
4. **Easy to implement**: Just replace one function
5. **Handles edge cases**: Null values, special characters, etc.

### Alternative Quick Fix
If you only want to handle email addresses specifically, you can use this simpler approach:
```javascript
// Quick fix for email addresses only
const sanitized_user = iam_user_name.split('@')[0];
path_string = `/auto-tag/${sanitized_user}/tag`;
```

But the comprehensive solution above is recommended as it handles all special characters, not just email addresses.

### Impact
This fix resolves the issue for organizations using email addresses as IAM usernames, which is a common pattern in enterprise environments. The auto-tagging functionality now works reliably without requiring changes to existing IAM user naming conventions.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.