Skip to content

Add support for mapping AWS root account principals#995

Open
AndreKurait wants to merge 1 commit intokubernetes-sigs:masterfrom
AndreKurait:root-account-mapping
Open

Add support for mapping AWS root account principals#995
AndreKurait wants to merge 1 commit intokubernetes-sigs:masterfrom
AndreKurait:root-account-mapping

Conversation

@AndreKurait
Copy link

What

Add a dedicated RootMapping type and rootMap to the file mapper, enabling explicit mapping of AWS root account principals (arn:aws:iam::ACCOUNT:root) to Kubernetes usernames and groups.

Why

Root account principals are already parsed correctly by arn.Canonicalize() — it returns the ROOT principal type and the canonical ARN. The token verification code in token.go also handles root correctly (line 755: if principalType == arn.FEDERATED_USER || principalType == arn.USER || principalType == arn.ROOT).

However, when the identity reaches the mapper, it falls through with ErrNotMapped because:

  • roleMap only contains role ARNs
  • userMap only contains user ARNs
  • There is no rootMap

The only way a root principal can currently authenticate is via AutoMappedAWSAccounts, which grants blanket access to the entire account without explicit mapping control. There is no way to map root to specific Kubernetes groups while excluding other principals from the same account.

Example

mapRoots:
- rootarn: "arn:aws:iam::012345678912:root"
  username: "root-admin"
  groups:
  - system:masters

Changes

  • pkg/config/types.go: New RootMapping struct with rootarn, username, groups fields. New RootMappings []RootMapping field on Config.
  • pkg/config/mapper.go: Validate(), Matches(), Key(), IdentityMapping() methods on RootMapping, mirroring UserMapping.
  • pkg/mapper/file/mapper.go: rootMap field on FileMapper, populated from Config.RootMappings with arn.Canonicalize() validation. Lookup in Map() after role and user lookups.
  • Tests: Unit tests for RootMapping methods and end-to-end FileMapper.Map() test covering match, cross-account rejection, and cross-resource-type rejection.

Design

Mirrors the existing UserMapping/userMap pattern exactly:

  • Separate struct type (not shoehorned into UserMapping or RoleMapping)
  • Separate map in the mapper (exact key lookup, same as userMap)
  • arn.Canonicalize() validation at load time
  • Checked after roles and users in Map() (root auth is rare, so checked last)

Backward Compatibility

  • No changes to existing role or user mapping behavior
  • RootMappings defaults to empty — no root mappings unless explicitly configured
  • Root principals that previously fell through to AutoMappedAWSAccounts will continue to work via that path (the root map is checked before IsAccountAllowed in doMapping)

Testing

All existing tests pass. New tests:

  • TestRootARNMappingValidate(), Matches(), Key() methods
  • TestRootMap — end-to-end through FileMapper.Map() with match, cross-account rejection, cross-resource-type rejection

Add a dedicated RootMapping type and rootMap to the file mapper,
mirroring the existing RoleMapping/roleMap and UserMapping/userMap
pattern.

Previously, root account principals (arn:aws:iam::ACCOUNT:root) were
parsed correctly by arn.Canonicalize() (returning the ROOT principal
type), but then fell through all mappers with ErrNotMapped because no
mapper had a code path for root ARNs. The only way a root principal
could authenticate was via AutoMappedAWSAccounts, which grants access
to the entire account without explicit mapping control.

This adds:
- RootMapping struct in config/types.go with rootarn, username, groups
- Validate(), Matches(), Key(), IdentityMapping() methods mirroring
  UserMapping
- rootMap in FileMapper with population from Config.RootMappings
- Root lookup in FileMapper.Map() after role and user lookups

Example configuration:

  mapRoots:
  - rootarn: arn:aws:iam::012345678912:root
    username: root-admin
    groups:
    - system:masters

Signed-off-by: Andre Kurait <akurait@amazon.com>
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Mar 4, 2026
@k8s-ci-robot k8s-ci-robot requested a review from haoranleo March 4, 2026 23:20
@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Mar 4, 2026
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: AndreKurait
Once this PR has been reviewed and has the lgtm label, please assign kmala for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot
Copy link
Contributor

Hi @AndreKurait. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 4, 2026
@bryantbiggs
Copy link
Member

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Mar 16, 2026
@AndreKurait
Copy link
Author

@bryantbiggs Any feedback based on the successful tests?

@bryantbiggs
Copy link
Member

bryantbiggs commented Mar 16, 2026

Curious about the motivation here — if you have root credentials, you can create any IAM role or user you need, so every case that might seem to require root auth has an alternative (assume a role and use mapRoles, create a user and use mapUsers, etc.). It's hard to think of a scenario where a role or user ARN genuinely won't work.

EKS Access Entries (AWS's own replacement for aws-auth) deliberately excluded root support — root credentials can't be restricted by IAM policies, SCPs, or permission boundaries, so a root principal reaching Kubernetes with system:masters is completely unconstrained at both layers. That seems like an intentional decision to not normalize root as a valid auth path rather than an oversight. What's the use case that motivated this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants