Embed role policies in AssumeRole STS tokens (#8421)
* Embed role policies in AssumeRole STS tokens * Log STS policy lookup failures * Use IAMManager provider * Guard policy embedding role lookup
This commit is contained in:
@@ -5,6 +5,7 @@ package s3api
|
||||
// AWS SDKs to obtain temporary credentials using OIDC/JWT tokens.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/integration"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/ldap"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/sts"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/utils"
|
||||
@@ -339,7 +341,7 @@ func (h *STSHandlers) handleAssumeRole(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Generate common STS components
|
||||
stsCreds, assumedUser, err := h.prepareSTSCredentials(roleArn, roleSessionName, durationSeconds, sessionPolicyJSON, modifyClaims)
|
||||
stsCreds, assumedUser, err := h.prepareSTSCredentials(r.Context(), roleArn, roleSessionName, durationSeconds, sessionPolicyJSON, modifyClaims)
|
||||
if err != nil {
|
||||
h.writeSTSErrorResponse(w, r, STSErrInternalError, err)
|
||||
return
|
||||
@@ -480,7 +482,7 @@ func (h *STSHandlers) handleAssumeRoleWithLDAPIdentity(w http.ResponseWriter, r
|
||||
claims.WithIdentityProvider("ldap", identity.UserID, identity.Provider)
|
||||
}
|
||||
|
||||
stsCreds, assumedUser, err := h.prepareSTSCredentials(roleArn, roleSessionName, durationSeconds, sessionPolicyJSON, modifyClaims)
|
||||
stsCreds, assumedUser, err := h.prepareSTSCredentials(r.Context(), roleArn, roleSessionName, durationSeconds, sessionPolicyJSON, modifyClaims)
|
||||
if err != nil {
|
||||
h.writeSTSErrorResponse(w, r, STSErrInternalError, err)
|
||||
return
|
||||
@@ -499,7 +501,7 @@ func (h *STSHandlers) handleAssumeRoleWithLDAPIdentity(w http.ResponseWriter, r
|
||||
}
|
||||
|
||||
// prepareSTSCredentials extracts common shared logic for credential generation
|
||||
func (h *STSHandlers) prepareSTSCredentials(roleArn, roleSessionName string,
|
||||
func (h *STSHandlers) prepareSTSCredentials(ctx context.Context, roleArn, roleSessionName string,
|
||||
durationSeconds *int64, sessionPolicy string, modifyClaims func(*sts.STSSessionClaims)) (STSCredentials, *AssumedRoleUser, error) {
|
||||
|
||||
// Calculate duration
|
||||
@@ -546,6 +548,33 @@ func (h *STSHandlers) prepareSTSCredentials(roleArn, roleSessionName string,
|
||||
WithSessionName(roleSessionName).
|
||||
WithRoleInfo(effectiveRoleArn, fmt.Sprintf("%s:%s", roleName, roleSessionName), assumedRoleArn)
|
||||
|
||||
// If IAM integration is available, embed the role's attached policies into the session token.
|
||||
// This makes the token self-sufficient for authorization even when role lookup is unavailable.
|
||||
var policyManager *integration.IAMManager
|
||||
if h.iam != nil && h.iam.iamIntegration != nil {
|
||||
if provider, ok := h.iam.iamIntegration.(IAMManagerProvider); ok {
|
||||
policyManager = provider.GetIAMManager()
|
||||
}
|
||||
}
|
||||
|
||||
if policyManager != nil {
|
||||
roleNameForPolicies := utils.ExtractRoleNameFromArn(roleArn)
|
||||
if roleNameForPolicies == "" {
|
||||
roleNameForPolicies = utils.ExtractRoleNameFromPrincipal(roleArn)
|
||||
}
|
||||
|
||||
if roleNameForPolicies != "" && len(claims.Policies) == 0 {
|
||||
roleDef, err := policyManager.GetRole(ctx, roleNameForPolicies)
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Failed to load role %q for policy embedding: %v", roleNameForPolicies, err)
|
||||
} else if roleDef == nil {
|
||||
glog.V(2).Infof("Role definition %q was missing for policy embedding", roleNameForPolicies)
|
||||
} else if len(roleDef.AttachedPolicies) > 0 {
|
||||
claims.WithPolicies(roleDef.AttachedPolicies)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sessionPolicy != "" {
|
||||
claims.WithSessionPolicy(sessionPolicy)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user