Add session policy support to IAM (#8338)

* Add session policy support to IAM

- Implement policy evaluation for session tokens in policy_engine.go
- Add session_policy field to session claims for tracking applied policies
- Update STS service to include session policies in token generation
- Add IAM integration tests for session policy validation
- Update IAM manager to support policy attachment to sessions
- Extend S3 API STS endpoint to handle session policy restrictions

* fix: optimize session policy evaluation and add documentation

* sts: add NormalizeSessionPolicy helper for inline session policies

* sts: support inline session policies for AssumeRoleWithWebIdentity and credential-based flows

* s3api: parse and normalize Policy parameter for STS HTTP handlers

* tests: add session policy unit tests and integration tests for inline policy downscoping

* tests: add s3tables STS inline policy integration

* iam: handle user principals and validate tokens

* sts: enforce inline session policy size limit

* tests: harden s3tables STS integration config

* iam: clarify principal policy resolution errors

* tests: improve STS integration endpoint selection
This commit is contained in:
Chris Lu
2026-02-13 13:58:22 -08:00
committed by GitHub
parent beeb375a88
commit 49a64f50f1
12 changed files with 682 additions and 275 deletions

View File

@@ -16,6 +16,9 @@ const (
// iamRoleMarker is the marker that identifies IAM role ARNs
iamRoleMarker = "role/"
// iamUserMarker is the marker that identifies IAM user ARNs
iamUserMarker = "user/"
)
// ARNInfo contains structured information about a parsed AWS ARN.
@@ -88,6 +91,36 @@ func ExtractRoleNameFromPrincipal(principal string) string {
return ExtractRoleNameFromArn(principal)
}
// ExtractUserNameFromPrincipal extracts the user name from an AWS IAM principal ARN.
//
// It handles both legacy and standard AWS IAM user ARN formats:
// - arn:aws:iam::user/UserName (legacy format without account ID)
// - arn:aws:iam::ACCOUNT:user/UserName (standard AWS format with account ID)
//
// Returns an empty string if the principal does not represent an IAM user.
func ExtractUserNameFromPrincipal(principal string) string {
if !strings.HasPrefix(principal, iamPrefix) {
return ""
}
remainder := principal[len(iamPrefix):]
resourcePart := remainder
if colonIdx := strings.Index(remainder, ":"); colonIdx != -1 {
resourcePart = remainder[colonIdx+1:]
}
if !strings.HasPrefix(resourcePart, iamUserMarker) {
return ""
}
userName := resourcePart[len(iamUserMarker):]
if userName == "" {
return ""
}
return userName
}
// ExtractRoleNameFromArn extracts the role name from an AWS IAM role ARN.
//
// It handles both legacy and standard AWS IAM role ARN formats: