Fix DeleteAccessEntry denial in the agentless enrollment policy - #6
BenEdgar17 wants to merge 2 commits into
Conversation
…lment policy DeleteAccessEntry/DescribeAccessEntry are authorized against the access-entry resource ARN and the eks:principalArn condition key is not populated for them, so the shared statement's StringEquals silently denied deletion (hit live: datasource-deletion cleanup got AccessDeniedException while creation succeeded). Create keeps the principalArn condition (proven live) and is now scoped to cluster ARNs; Delete/Describe are scoped by the agentless role's access-entry ARN — the same pattern the Associate statement already uses, also proven live. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CloudTrail analysis showed the eks:principalArn condition DOES match DeleteAccessEntry when the entry exists; every observed denial was on a nonexistent entry (AccessDenied masking what should be ResourceNotFound). The fix is unchanged — resource-scoping makes authorization independent of entry existence — but the comment now records the true mechanism. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Correction to the original description: the first version of this PR claimed
All four role generations carried byte-identical policy documents (verified via The diff is unchanged and still the right fix — resource-scoping decouples delete authorization from entry existence. Commit 6f2a16c updates the in-template comment to record the true mechanism. |
Summary
Splits the agentless enrollment policy's combined Create/Delete/Describe access-entry statement in all three aws-generic CloudFormation templates:
eks:CreateAccessEntrykeeps theeks:principalArnStringEquals condition (documented and proven to work for Create) and is now scoped to the cluster ARN it actually authorizes against.eks:DeleteAccessEntry/eks:DescribeAccessEntrydrop the condition and are instead resource-scoped to the agentless role's access-entry ARN pattern (…:access-entry/*/role/<acct>/Dalton-EKS-Agentless-<acct>/*) — the same pattern the Associate/Disassociate statement already uses in production.Root cause (corrected after CloudTrail analysis)
The
eks:principalArncondition onDeleteAccessEntryonly matches when the access entry actually exists. CloudTrail from the dev account shows the same policy, same role generation, same request:AccessDeniedExceptioninstead ofResourceNotFoundException(10:56Z, 13:49Z, 14:27Z — and at 14:27:06Z the same second'sCreateAccessEntrysucceeded, proving the policy itself was live and healthy).Dalton's cleanup and recreate-on-enroll paths deliberately rely on a tolerable not-found (delete-then-create rebind per ENG-4311; best-effort cleanup per ENG-4310). Under the conditioned statement, every no-entry delete surfaces as a scary AccessDenied "failed" outcome in the deletion report and defeats the ENG-4311 stale-entry rebind. Resource-scoping makes delete authorization independent of entry existence: existing entries delete cleanly, absent entries return ResourceNotFound, which the backend already tolerates.
Rollout
s3://cf-templates-w9lau7h9v2y20-eu-north-1/aws-generic/.dalton-aws-integrationin eu-north-1).Linear
Part of ENG-4257
🤖 Generated with Claude Code