Repository navigation
fix(#6019): sagemaker-core 2.15.0: role validation raises false-positive RoleValidationError under condition-based SCPs (IAM simulator can't evaluate conditional SCPs) - #9
Draft
sagemaker-bot wants to merge 1 commit into
Conversation
…with a pipeline session in V3 but does in V2
sagemaker-bot
force-pushed
the
agent/issue-5828
branch
from
September 29, 2026 23:16
33b944f to
681d6b8
Compare
RoleValidationError under condition-based SCPs (IAM simulator can't evaluate conditional SCPs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves aws#6019.
Agent Run Report — issue aws#6019
sagemaker-core 2.15.0: role validation raises false-positive
RoleValidationErrorunder condition-based SCPs (IAM simulator can't evaluate conditional SCPs)Outcome:
ready_for_pr1. Triage
2. Reproduction
sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.pyRepro test
Failing output (before fix)
3. Fix
Fixed a false-positive RoleValidationError under condition-based SCPs (issue aws#6019). The client-side permission pre-check in sagemaker-core's iam_role_resolver.py relies on iam:SimulatePrincipalPolicy, which per AWS docs cannot evaluate SCPs that carry any conditions. In organizations using condition-based SCPs the simulator returns EvalDecision=implicitDeny with empty MatchedStatements and OrganizationsDecisionDetail.AllowedByOrganizations=false even for actions the role is actually allowed to perform at run time, and the resolver treated this as a definitive denial and raised. The root-cause fix is in _simulate_denied_actions: a new helper _is_org_layer_only_denial detects verdicts denied solely at the Organizations/SCP layer (AllowedByOrganizations false, no matched identity statement) and excludes them from the denied set, so they are treated as unverifiable (warn + proceed) — the same as the existing "caller can't simulate" path — letting the real API call be the source of truth. Explicit identity Deny statements still surface as matched statements and continue to block. Changed file: sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py.
Changed files:
sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.pysagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.pyDiff
4. Validation
Post-fix test output
5. Review
5b. Adversarial verification
6. Routing
?Timeline
Agent actions (26 tool calls)
Tool-by-tool transcript
read_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py'} → """IAM role resolution, validation, and (opt-in) creation for the SageMaker Python SDK. The default path is read-only: :func:resolve_and_validate_roleresearch{'pattern': 'simulate_principal_policy|_simulate_denied_actions|_evaluate_permissions', 'path': 'sagemaker-core/tests'} → sagemaker-core/tests/unit/helper/test_iam_role_resolver.py:20: _simulate_denied_actions, sagemaker-core/tests/unit/helper/test_iam_role_resolver.py:881:read_file{'path': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver.py'} → """Unit tests for the read-only IAM role resolver (validate, never create).""" import json import logging from unittest.mock import MagicMock, patch import pytwrite_file{'path': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py', 'bytes': 3480} → wrote 3480 bytes to sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.pyrun_pytest{'selection': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py'} → exit=1 F [100%] =================================== FAILURES ============================read_file{'path': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py'} → """Reproduction for issue sagemaker-core 2.15.0: role validation raises false-positiveRoleValidationErrorunder condition-based SCPs (IAM simulator can't evaluate conditional SCPs) aws/sagemaker-python-sdk#6019. Under an AWS Organization that uses condition-based SCPs, the IAM policy simulator cannot faithfully evaluate the SCP layer, sread_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py'} → """IAM role resolution, validation, and (opt-in) creation for the SageMaker Python SDK. The default path is read-only: :func:resolve_and_validate_rolereedit_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py', 'old_bytes': 1044, 'new_bytes': 2801} → edited sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py (replaced 1044→2801 bytes)run_pytest{'selection': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py'} → exit=0 . [100%] 1 passed in 1.99srun_pytest{'selection': 'sagemaker-core/tests/unit/helper/'} → exit=0 ........................................................................ [ 36%] ........................................................................read_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py'} → """IAM role resolution, validation, and (opt-in) creation for the SageMaker Python SDK. The default path is read-only: :func:resolve_and_validate_roleresearch{'pattern': '_simulate_denied_actions|_is_org_layer_only_denial|EvaluationResults|OrganizationsDecisionDetail', 'path': 'sagemaker-core/tests'} → sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py:6: emptyMatchedStatementslist and ``OrganizationsDecisionDetail. sagemaker-csearch{'pattern': 'simulate_principal_policy|EvaluationResults', 'path': 'sagemaker-core/tests'} → sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py:70: "EvaluationResults": [ sagemaker-core/tests/unit/helper/test_iread_file{'path': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py'} → """Reproduction for issue sagemaker-core 2.15.0: role validation raises false-positiveRoleValidationErrorunder condition-based SCPs (IAM simulator can't evaluate conditional SCPs) aws/sagemaker-python-sdk#6019. Under an AWS Organization that uses condition-based SCPs, the IAM policy simulator cannot faithfully evaluate the SCP layer, sread_file{'path': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver.py'} → """Unit tests for the read-only IAM role resolver (validate, never create).""" import json import logging from unittest.mock import MagicMock, patch import pytwrite_file{'path': 'sagemaker-core/tests/unit/helper/test_probe_scp_6019.py', 'bytes': 8698} → wrote 8698 bytes to sagemaker-core/tests/unit/helper/test_probe_scp_6019.pyrun_pytest{'selection': 'sagemaker-core/tests/unit/helper/test_probe_scp_6019.py'} → exit=0 .......... [100%] 10 passed in 1.97sedit_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py', 'old_bytes': 88, 'new_bytes': 63} → edited sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py (replaced 88→63 bytes)run_pytest{'selection': 'sagemaker-core/tests/unit/helper/test_probe_scp_6019.py'} → exit=1 F........F [100%] =================================== FAILURES ============================edit_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py', 'old_bytes': 63, 'new_bytes': 88} → edited sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py (replaced 63→88 bytes)run_pytest{'selection': 'sagemaker-core/tests/unit/helper/test_iam_role_resolver.py sagemaker-core/tests/unit/helper/test_iam_role_resolver_scp_false_positive.py sagemaker-core/tests/unit/helper/test_probe_scp_6019.py'} → exit=0 ........................................................................ [ 85%] ............search{'pattern': 'EvalDecision.*allowed.*not _is_org_layer_only_denial', 'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py'} → (no matches)read_file{'path': 'sagemaker-core/src/sagemaker/core/helper/iam_role_resolver.py'} → """IAM role resolution, validation, and (opt-in) creation for the SageMaker Python SDK. The default path is read-only: :func:resolve_and_validate_rolererun_pytest{'selection': 'sagemaker-core/tests/unit/helper/'} → exit=0 ........................................................................ [ 34%] ........................................................................write_file{'path': 'sagemaker-core/tests/unit/helper/test_probe_scp_6019.py', 'bytes': 0} → wrote 0 bytes to sagemaker-core/tests/unit/helper/test_probe_scp_6019.pyread_file{'path': 'sagemaker-core/tests/unit/helper/test_probe_scp_6019.py'} →