fix(logs): emit account root ARN in resource policies to avoid drift false positive - #38195
fix(logs): emit account root ARN in resource policies to avoid drift false positive#38195UTKARSH698 wants to merge 7 commits into
Conversation
…false positive
`LogGroup.addToResourcePolicy` (used by `grantRead`/`grantWrite`) reduced
cross-account ARN principals to a bare account id (e.g. `{"AWS":"123456789012"}`).
CloudFormation canonicalizes that to the account root ARN
(`{"AWS":"arn:aws:iam::123456789012:root"}`) on the deployed resource, so drift
detection performs a literal string comparison and reports the stack as DRIFTED
on every evaluation cycle.
Emit the canonical account root ARN at synth time instead, so the synthesized
template matches the deployed value. The partition is preserved for concrete
ARNs and falls back to the stack partition pseudo parameter for account-only
principals. Service and `*` principals are unaffected.
Closes aws#37797
…ource policy Extends the loggroup-grantread integ test with a cross-account ArnPrincipal grant and regenerates the snapshot, asserting the resource policy emits the canonical account root ARN (arn:aws:iam::<account>:root) rather than a bare account id. This satisfies the PR linter requirement that fixes touch an integration test and its snapshot, and locks in the aws#37797 drift fix.
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
|
Heads-up for reviewers: the red
That is a security guard applied to all external fork PRs, so it can only be cleared maintainer-side. Nothing in this change touches the CLI — the diff is confined to |
|
Friendly follow-up 👋 It’s been a couple of weeks, so flagging that this is still open and ready for review. The branch is a bit behind |
|
Cross-linking for whoever triages this: #38330 targets the same issue (#37797) by changing the same One substantive difference worth a look when picking between them: this PR derives the account-root ARN through Happy to rebase onto |
…icy principals Principals that already expose an account now map onto iam.AccountPrincipal, CDK's canonical representation of an account root, instead of a locally built ARN string. Raw ARN principals continue to be reduced through Stack.formatArn so that aws-cn and aws-us-gov principals keep their own partition. The private helper is renamed to convertArnPrincipalToAccountRootArn to describe what it now returns. Adds unit coverage for account principals, non-default partitions, and ARN principals that carry no account.
|
Heads-up for reviewers: I pushed one new commit ( What changed The if (principal.principalAccount) {
return new iam.ArnPrincipal(this.accountRootArn(principal.principalAccount));
}It now uses the type the library already has for this: if (principal.principalAccount) {
return new iam.AccountPrincipal(principal.principalAccount);
}
The raw With the local helper no longer needed it is gone, and the private method is renamed Test coverage Added three unit cases that the original commit did not cover: an account-bearing principal, a non-default partition, and an Still happy to drop this commit if you would rather review the minimal diff — the original two commits stand on their own, and this one is purely presentational. |
|
@gjurova — thanks for pulling
Could you hit Approve and run when you get a moment? Since CI can't run the new commit yet, I verified the change locally so the ask isn't a blind one:
The last row is the assertion that was already in the suite before this PR, and it is byte-identical — which is the main thing I wanted to confirm, since the refactor is meant to be output-neutral. Happy to squash the two commits if you'd prefer a single one in the history. |
Issue
Closes #37797
Reason for this change
LogGroup.addToResourcePolicy(reached viagrantRead/grantWriteand direct calls) routed every principal throughconvertArnPrincipalToAccountId, which reduced cross-account ARN principals to a bare account id:{ "AWS": "211125612616" }CloudFormation accepts that, but on the deployed resource it stores the canonical account root ARN:
{ "AWS": "arn:aws:iam::211125612616:root" }Drift detection does a literal string comparison between the two, so every stack that grants a cross-account principal access to a log group is reported as
DRIFTEDon every evaluation cycle. There is no consumer-side workaround. The maintainer reproduced and confirmed the root cause in #37797.Description of changes
convertArnPrincipalToAccountIdnow emits the canonical account root ARN (arn:<partition>:iam::<account>:root) instead of a bare account id, via a small privateaccountRootArn(account, partition?)helper built onStack.formatArn:ArnPrincipals preserve their parsed partition (gov/china safe) and produce a literalarn:aws:iam::<account>:root.principalAccount, often a token) fall back to the stack partition pseudo parameter ({Ref: AWS::Partition}).*(AnyPrincipal) are unchanged.This makes the synthesized resource policy match the form CloudFormation stores, eliminating the persistent drift false positive while remaining semantically identical.
Describe any new or updated permissions being added
None.
Description of how you validated changes
Updated the two existing
aws-logsresource-policy unit tests (concrete IAM user principal, and imported-role principal via CFN pseudo parameters) to expect the account root ARN, and added a dedicated regression test for the concrete cross-account case from the issue.Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license.