{"record":{"id":"c074d42559e431e7","repo":"getsops/sops","slug":"failed-to-assume-role-s-w","errorCode":null,"errorMessage":"failed to assume role '%s': %w","messagePattern":"failed to assume role '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kms/keysource.go","lineNumber":450,"sourceCode":"}\n\n// createSTSConfig uses AWS STS to assume a role and returns a config\n// configured with that role's credentials. It returns an error if\n// it fails to construct a session name, or assume the role.\nfunc (key MasterKey) createSTSConfig(ctx context.Context, config *aws.Config) (*aws.Config, error) {\n\tname, err := stsSessionName()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinput := &sts.AssumeRoleInput{\n\t\tRoleArn:         &key.Role,\n\t\tRoleSessionName: &name,\n\t}\n\n\tclient := sts.NewFromConfig(*config)\n\tout, err := client.AssumeRole(ctx, input)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to assume role '%s': %w\", key.Role, err)\n\t}\n\n\tconfig.Credentials = credentials.NewStaticCredentialsProvider(*out.Credentials.AccessKeyId,\n\t\t*out.Credentials.SecretAccessKey, *out.Credentials.SessionToken,\n\t)\n\treturn config, nil\n}\n\n// stsSessionName returns the name for the STS session in the format of\n// `sops@<hostname>`. It sanitizes the hostname with stsSessionRegex, and\n// truncates to roleSessionNameLengthLimit when it exceeds the limit.\nfunc stsSessionName() (string, error) {\n\thostname, err := osHostname()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to construct STS session name: %w\", err)\n\t}\n\n\tre := regexp.MustCompile(stsSessionRegex)","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/kms/keysource.go#L432-L468","documentation":"createSTSConfig performs sts.AssumeRole so the KMS key is accessed with the temporary credentials of key.Role. When the AssumeRole API call fails, sops wraps the SDK error with the role name. Typical inner causes are: role does not exist, caller is not authorized to assume it (sts:AssumeRole denied), trust policy mismatch, or expired/insufficient credentials.","triggerScenarios":"EncryptContext/DecryptContext on a KMS MasterKey with a non-empty Role field where client.AssumeRole returns an AccessDenied, NoSuchEntity/NotFound, or credentials error.","commonSituations":"Typo in the role ARN; the calling identity lacks sts:AssumeRole permission; the role's trust policy does not trust the caller; SCP or permission boundary denies STS; using the role from an account without proper external-id conditions; MFA-required trust policy without MFA parameters.","solutions":["Inspect the wrapped SDK error: AccessDenied means fix IAM (attach sts:AssumeRole to the caller and matching trust policy); NotFound means fix the role ARN.","Verify the role exists: `aws sts get-caller-identity` then `aws iam get-role --role-name <name>` in the right account/region.","Test manually with `aws sts assume-role --role-arn <arn> --role-session-name test` to confirm credentials allow it.","Correct the `role` field on the KMS key in .sops.yaml or remove it if not needed (then no AssumeRole is attempted)."],"exampleFix":"// before (.sops.yaml)\n- arn: arn:aws:kms:us-east-1:123456789012:key/abcd\n  role: \"arn:aws:iam::123456789012:role/sops-role\"  # typo: 'iam' vs 'sts' context / wrong path\n// after\n- arn: arn:aws:kms:us-east-1:123456789012:key/abcd\n  role: \"arn:aws:iam::123456789012:role/SOPSKeyRole\"  # verified via aws iam get-role","handlingStrategy":"retry","validationCode":"// Go: dry-run AssumeRole before encrypting\n_, err := sts.NewFromConfig(cfg).AssumeRole(ctx, &sts.AssumeRoleInput{\n  RoleArn: aws.String(roleArn), RoleSessionName: aws.String(\"sops-preflight\")})\n// surface the error early instead of mid-encryption","typeGuard":null,"tryCatchPattern":"// Go\n_, err := key.Encrypt()\nvar opErr *types.UnrecognizedClientException // and AccessDenied flows\nif err != nil && strings.Contains(err.Error(), \"failed to assume role\") {\n  if strings.Contains(err.Error(), \"AccessDenied\") { /* fix IAM, do not retry */ }\n  // transient errors only: backoff and retry\n}","preventionTips":["Test `aws sts assume-role --role-arn <arn> --role-session-name test` before wiring the role into sops","Ensure the role's trust policy trusts the calling principal and sts:AssumeRole is allowed by SCPs/boundaries","Copy role ARNs from `aws iam get-role` output, never type them by hand","Remove the `role` field when it is not needed - it skips AssumeRole entirely"],"tags":["aws","kms","sts","iam","network"],"backgroundTag":"sts-assume-role-denied","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}