Repository navigation
Conversation
… the relevant stack
…udtrail identities Imported roles may be shared with resources outside the stack, whose calls would then be attributed to it. Roles the stack creates are still matched through their physical IDs, and stack resources running on an imported role still correlate through their own identity.
Keeps this change focused on attribution; the heading also changed the shape of the diagnosis result for programmatic consumers.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Automated review A maintainer will still review this — treat the notes below as a starting point. 📌 Commit This PR fixes a correctness bug in toolkit-lib's post-deployment stack diagnoser, which correlates CloudTrail control-plane errors against a failed 🔴 0 blocking · 🟡 0 recommended · ⚪ 0 optional Generated automatically. React 👍 or 👎 to tell us whether this review helped, so we can improve these reviews. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2120 +/- ##
==========================================
- Coverage 92.05% 92.01% -0.04%
==========================================
Files 82 82
Lines 13195 13195
Branches 1894 1893 -1
==========================================
- Hits 12146 12142 -4
- Misses 1011 1015 +4
Partials 38 38
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@iankhou Why would roles be relevant to the stack failure other than the ones used by a custom resource provider? I see a few different flaws here:
Of course, the Achilles heel of this entire design is that it is not generally possible to correlate CloudTrail events with a particular stack deployment, which is why I do not understand why it is part of |
…events, not the template CloudTrail identities are now the roles and Lambda functions in the stack (DescribeStackResources) plus those seen in the operation's stack events, which covers resources that were created and then rolled back. Other resource types and the template are no longer used, so imported roles, shared ServiceToken providers and short physical IDs cannot claim unrelated events. The suggestion to re-run `cdk diagnose` is dropped once CloudTrail has delivered any event from after the sweep window.
Problem statement
Addresses an incorrect CloudTrail attribution reported in #2084.
After a stack deployment fails, the diagnoser fetches CloudTrail events from the failure window and attributes errored events to the stack by matching the calling principal's identity (role names, function names, physical IDs) against the stack's resources.
Sometimes this results in an unrelated event, since those identities can be shared with resources outside of the stack. An example is when we use
Role.fromRoleArn, which brings in a Role that could be created in a different stack (or not in a stack at all).Reproduction of the problem
A first stack creates a role,
ct-repro-shared-role, and a Lambda,ct-repro-unrelated-fn, that runs on it and is denieddynamodb:DescribeTable:A second stack imports that role as a Lambda's execution role, and fails on an unrelated resource. Nothing in this stack ever assumes the role during the deployment:
Deploy
CtReproUnrelated, invokect-repro-unrelated-fna few times, then deployCtReproFailingwithin the next few minutes.Before: the output attributes
ct-repro-unrelated-fn's calls toMyFn, as the session ARNassumed-role/ct-repro-shared-role/ct-repro-unrelated-fnshows:After:
cdk diagnose, run once CloudTrail had delivered six ofct-repro-unrelated-fn'sAccessDeniedevents inside the failure window, reports no CloudTrail errors for the stack:Changes
Stack identities are now the roles and Lambda functions the stack operation involved: the ones currently in the stack (
DescribeStackResources), plus the ones that appear in the operation's stack events. The events cover resources the operation created and then rolled back, which the stack no longer lists.cdk deployandcdk diagnosebuild this list the same way, and the CloudTrail investigation no longer reads the template.Roles the stack only references (imported roles) are therefore no longer stack identities. This means we ignore the CloudTrail lookups for them. Physical IDs of other resource types (buckets, stages, etc.) are no longer identities either, since only roles and functions make calls. Calls by a stack resource running on an imported role still correlate, through the resource's own identity (e.g. a Lambda's session name is its function name). A custom resource's backing function in the stack is matched as a regular Lambda function, so its errors are now labeled with the function rather than the custom resource.
CloudTrail events are matched by the resource that made the control-plane call. For example, when a Lambda function makes a call, CloudTrail records that resource in
userIdentity.inScopeOf.credentialsIssuedTo. If this field is present, the event belongs to the stack only if that resource does; the role it ran under is ignored. A function outside the stack therefore cannot have its calls attributed to the stack just because it shares a role with it, even a role the stack created. Events withoutinScopeOf(e.g. a service assuming a role with a generated session name) still match on the caller's role and session ARNs, but only against identities the stack owns (no imported roles).After a recent failure, we suggest re-running
cdk diagnosebecause CloudTrail may not have delivered the events yet. We now skip that suggestion if CloudTrail has already delivered any event from after the sweep window. CloudTrail does not guarantee delivery in order, so this is a good guess rather than a guarantee.Risks
Trade-offs
Errors from a service using an imported role for a stack resource (like Firehose or CodeBuild assuming a role the stack imported, with a service-generated session name) are no longer surfaced. They cannot be told apart from another stack's use of the same role, and the diagnoser prefers "no events found" over an incorrect attribution. The same applies to custom resources whose provider function lives outside the stack.
Known limitations
Events without
inScopeOfcan still be attributed to the stack when:CDKToolkit), whose deploy and exec roles are used by every other app deploying in the same window.Testing
cdk diagnoseattributed each root cause to the same resource as before (the handler function for the custom-resource stacks, the execution role for the VPC/ENI stack), found nothing for the negative case, and attributed no events across stacks. The re-run suggestion was dropped once later events had been delivered.Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license