fix(iam): normalize service policies and preserve imported state

Keep omitted edit policies unchanged, reset valid empty policies to inheritance, and normalize nonempty policies without a version before storage. Preserve caller policy objects and exclude derived authorization claims from snapshots and new JWTs.

Restore imported service-account and group status, report the actual group error, and cover creation, editing, replication, import/export and raw JWT claims with focused server tests.

Refs #339, #345.

Signed-off-by: Feng Ruohang <rh@vonng.com>
(cherry picked from commit 86e4c09d47f48cb2f44fb2f63f02f222ac6ae102)
This commit is contained in:
Feng Ruohang
2026-11-11 11:01:50 +08:00
parent 14ecb222e7
commit 1d714834c5
7 changed files with 444 additions and 45 deletions
+7 -20
View File
@@ -20,7 +20,6 @@ package cmd
import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"maps"
@@ -2934,27 +2933,15 @@ func updatedServiceAccountCredentials(ctx context.Context, accessKey string, cr
// the embedded one stays. Only a policy that was given, and is empty,
// removes it: the account then has all its parent is allowed, which is
// usually more.
reset := opts.sessionPolicy != nil && opts.sessionPolicy.Version == "" && len(opts.sessionPolicy.Statements) == 0
if _, ok := m.Lookup(policy.SessionPolicyName); ok && reset {
m.Delete(policy.SessionPolicyName)
m.Set(iamPolicyClaimNameSA(), inheritedPolicyType)
}
if opts.sessionPolicy != nil { // session policies is being updated
if err := opts.sessionPolicy.Validate(); err != nil {
if opts.sessionPolicy != nil {
policyBuf, err := marshalServiceAccountPolicy(opts.sessionPolicy)
if err != nil {
return cr, err
}
if opts.sessionPolicy.Version != "" && len(opts.sessionPolicy.Statements) > 0 {
policyBuf, err := json.Marshal(opts.sessionPolicy)
if err != nil {
return cr, err
}
if len(policyBuf) > maxSVCSessionPolicySize {
return cr, errSessionPolicyTooLarge
}
if len(policyBuf) == 0 {
m.Delete(policy.SessionPolicyName)
m.Set(iamPolicyClaimNameSA(), inheritedPolicyType)
} else {
// Overwrite session policy claims.
m.Set(policy.SessionPolicyName, base64.StdEncoding.EncodeToString(policyBuf))
m.Set(iamPolicyClaimNameSA(), embeddedPolicyType)