CIEM-718: skip the never-read denied_permissions report section (opt-in) - #40
Merged
Merged
Conversation
create_json_report gains include_denied_permissions: bool = True. Default is
unchanged, so every existing caller (CLI, golden test) keeps current behavior;
callers that don't read the section opt out.
Why the section is skippable: evaluate() unions the SCP's expanded Deny
statements into denied_permissions and then never reads them back. An SCP's
actual effect lands elsewhere - dropped actions go to ineffective_permissions
with denied_by set to the SCP ARN, and conditionally-denied actions stay in
allowed_permissions with the negated deny condition merged in. Measured on a
conditional-SCP account, adding SCPs changed 479 allowed_permissions conditions
and added/removed 0 entries, while denied_permissions grew 91 -> 271,119 chars
of account-constant echo repeated for every principal.
No consumer reads it: the graph parser
(move_to_graph_utils/orca/effective_permissions/effective_permissions_parser.py)
and the UI/GraphQL path (base_api/gql/gql_query.py) both read only
allowed_permissions + ineffective_permissions.
Measured on real accounts, full (uncapped), one shared evaluator:
tempus (2,774 principals) report 43.5s -> 1.8s, total 72.2s -> 30.6s (-58%),
peak RSS 253MB -> 204MB
a2 (179) / a3 (297) unchanged (no SCPs, report is not the bottleneck)
Output-neutral: allowed_permissions, ineffective_permissions and the shrunk
policy are hash-identical to main across a2, a3 and tempus, both with the flag
defaulted and with the section skipped.
There was a problem hiding this comment.
Orca Security Scan Summary
| Status | Check | Issues by priority | |
|---|---|---|---|
| Secrets | View in Orca | ||
| Vulnerabilities | View in Orca |
|
Tohar-orca
approved these changes
Aug 9, 2026
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.



Summary
create_json_reportgainsinclude_denied_permissions: bool = True. The default is unchanged, so the CLI and the golden test keep current behavior; only callers that don't read the section opt out.This is the low-risk half of #39, carved out so it can land on its own. It touches 16 lines, does not go near
evaluate(), and adds no caches, no shared state and no object aliasing.Why this section is safe to skip
evaluate()unions the SCP's expandedDenystatements intodenied_permissionsand then never reads them back — the only consumer is this report section:An SCP's actual effect lands in the two sections we keep:
allowed_permissions, recorded inineffective_permissionswithdenied_by= the SCP ARNallowed_permissionswith the negated SCP condition merged into itsConditionMeasured on a conditional-SCP account, comparing the same principal with and without SCPs:
Because
self.scp_policyis built once in__init__, that blob is identical for every principal. It is also the section that scales with the SCP set, which is why enabling the SCP-hierarchy flag made report-building dominate the handler.Incidentally, the accumulation is subtly wrong and has been for as long as it has existed:
deep_updateonly mergesdictandlistvalues, butdenied_permissionsisDict[str, Set[Action]], so when an action key appears in both the principal's own denies and the SCP's, the SCP's set is silently dropped. Nobody has noticed, because nobody reads it.No consumer reads it
move_to_graph_utils/orca/effective_permissions/effective_permissions_parser.py:119,125reads onlyallowed_permissions+ineffective_permissionsbase_api/gql/gql_query.py:1249,1256likewiseorcaandui.v2: every otherdenied_permissionsoccurrence is a test fixture or an Azure-path commentMeasured — real accounts, full (uncapped), one shared evaluator
Report phase on tempus: 43.5 s → 1.8 s. a2/a3 have no SCPs, so the denied section is small and there is nothing to win — as expected.
Correctness
allowed_permissions,ineffective_permissionsand the shrunk policy are hash-identical tomainacross a2, a3 and tempus — both with the flag defaulted and with the section skipped. Default-path timings are identical tomain, i.e. no overhead for callers that don't opt in.New test
test_include_denied_permissions_preserves_read_sectionslocks the invariant. 39 unit tests pass.Rollout
Safe by default — the denied section is still built unless a caller opts out. The matching
orcaPR flips the AWS handler toinclude_denied_permissions=Falseand bumps the pin; it is blocked on publishing 1.1.9.#39 remains open with the caches, hash memo and
_finalizerewrite; it will need a rebase and a version bump past 1.1.9.