Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add user warrants #3156

Merged
merged 4 commits into from
Jan 26, 2025
Merged

✨ Add user warrants #3156

merged 4 commits into from
Jan 26, 2025

Conversation

sttts
Copy link
Member

@sttts sttts commented Aug 22, 2024

TODO:

Summary

Needs kcp-dev/kubernetes#145.

From Slack:

🧵 long ago @sur presented a problem (if I remember right) in our current auth model of serviceaccounts only being valid locally, and with that the inability to create workspaces through an APIExport virtual workspace. The steps are these:

  1. a user U creates a workspace W2 in logicalcluster L1 through an APIExport virtual workspace (that has a permission claim on Workspaces).
  2. the VW forwards the requests by impersonating its system:masters user with a fake system:kcp:admin serviceaccount (S1) for L1 named system:serviceaccount:default:rest.
  3. the forwarded requests hits kcp and kcp authorizes the workspace creation with that S1 serviceaccount. It uses that identity to authorize the use of workspace types. By giving use permission to everybody, this goes through.
  4. workspace admission sticks S1 as owner on the workspace object, to be used by initialization later.
  5. the workspace scheduler creates a logicalclusters L2 for W2 and gives S1 admin permissions through a clusterrole+binding.
  6. the initializers kick in and access the initializer VW for L2 where W2 has been scheduled to. Their requests are impersonated as S1 by the VW.
  7. these requests hit kcp and the authorizer denies access because S1 is a foreign service account 💥

Now assume a modified system that

  • understands serviceaccounts from other workspaces, but does not give them permissions by default.
  • does not use a fake serviceaccount S1 identity to pass through the APIExport VW requests, but preserves the actual controller user and only attaches a warrant that gives the requires access of the claim.

The steps from above would turn into:

  1. a user U creates a workspace W2 in logicalcluster L1 through an APIExport virtual workspace (that has a permission claim on Workspaces).
  2. the VW forwards the requests by impersonating its system:masters user as U with a warrant for a fake system:kcp:admin serviceaccount (S1) for L1 named system:serviceaccount:default:rest.
  3. the forwarded requests hits kcp and kcp authorizes the workspace creation with that warrant S1 serviceaccount because U is not enough. It uses the U identity to authorize the use of workspace types. By giving use permission to everybody, tThis goes through.
  4. workspace admission sticks U with warrant S1 as owner on the workspace object, to be used by initialization later.
  5. the workspace scheduler creates a logicalclusters L2 for W2 and gives U with warrant S1 admin permissions through a clusterrole+binding.
  6. the initializers kick in and access the initializer VW for L2 where W2 has been scheduled to. Their requests are impersonated as U with warrant S1 by the VW.
  7. these requests hit kcp and the authorizer denies access because S1 is a foreign service account grants access because U with warrant S1 is admin in L2.

Now assume in addition that U is actually a controller serviceaccount S0 in workspace root. Step (7) would 💥 because S0 is foreign for L2. We further modify the system to authenticate serviceaccount as system:kcp:serviceaccount:<logicalcluster>:<ns>:<name> with a warrant for system:serviceaccount:<ns>:<name> restricted to their defining logicalcluster.

Now, U becomes system:kcp:serviceaccount:root:default:controller with warrant system:serviceaccount:default:controller restricted to root. With that (4) becomes

  1. workspace admission sticks system:kcp:serviceaccount:root:default:controller with warrant system:serviceaccount:default:controller restricted to root with warrant S1 as owner on the workspace object, to be used by initialization later.

I.e. the user has two warrants. With that (7) becomes:

  1. these requests hit kcp and the authorizer grants access because system:kcp:serviceaccount:root:default:controller with the TWO warrants including S1 is admin in L2.

Related issue(s)

Fixes #

Release Notes

Pass through original identity of controllers accessing a logical cluster through the APIExport virtual workspace. To get the required permissions, a warrant mechanism is added through user extra fields that attaches secondary user identities purely used for authorization.

@kcp-ci-bot kcp-ci-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. dco-signoff: yes Indicates the PR's author has signed the DCO. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 22, 2024
@sttts sttts changed the title ✨ PoC: Implement user warrents ✨ PoC: Implement user warrants Aug 22, 2024
@kcp-ci-bot kcp-ci-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 22, 2024
@sttts sttts force-pushed the sttts-warrants branch 2 times, most recently from 00dd36e to ebb5114 Compare August 22, 2024 13:00
docs/content/concepts/authorization.md Outdated Show resolved Hide resolved
docs/content/concepts/authorization.md Outdated Show resolved Hide resolved
docs/content/concepts/authorization.md Outdated Show resolved Hide resolved
@kcp-ci-bot kcp-ci-bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 23, 2024
@sttts sttts force-pushed the sttts-warrants branch 4 times, most recently from 4b188ca to 2ca96c3 Compare August 26, 2024 09:29
@kcp-ci-bot kcp-ci-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 13, 2024
@mjudeikis
Copy link
Contributor

In general just a questions. looks good,

@kcp-ci-bot kcp-ci-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Dec 2, 2024
@sttts sttts force-pushed the sttts-warrants branch 3 times, most recently from 49ead38 to a4296e0 Compare January 25, 2025 15:31
@sttts sttts changed the title ✨ Implement user warrants ✨ Add user warrants Jan 25, 2025
@sttts sttts force-pushed the sttts-warrants branch 5 times, most recently from d2cc358 to 4c6b0ed Compare January 25, 2025 20:32
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@gmail.com>
sttts added 3 commits January 26, 2025 10:10
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@gmail.com>
…for the target workspace

Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@gmail.com>
…nts and scoping

Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@gmail.com>
@sttts sttts force-pushed the sttts-warrants branch 4 times, most recently from b0e31b3 to 30834fe Compare January 26, 2025 12:55
@embik
Copy link
Member

embik commented Jan 26, 2025

/retest

looks like a flake to me.

@@ -173,6 +173,7 @@ func (s *Authorization) ApplyTo(ctx context.Context, config *genericapiserver.Co
if err != nil {
return err
}
authorizer = authz.WithWarrantsAndScopes(authorizer)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my understanding here: We are only wrapping the (optional) webhook authorizer because the RBAC-based ones (the whole chain thing) got warrant support by amending the rule resolver in the kube fork, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. And we don't want that external, third party authorizers have to understand scopes and warrants.

@mjudeikis
Copy link
Contributor

/retest
/lgtm
/approve
/hold
until @embik gets his question sorted :)

@kcp-ci-bot kcp-ci-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. lgtm Indicates that a PR is ready to be merged. labels Jan 26, 2025
@kcp-ci-bot
Copy link
Contributor

LGTM label has been added.

Git tree hash: ec0e8108e30e6e12d6320ecebdfc209511d4b631

@kcp-ci-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mjudeikis

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

The pull request process is described here

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

@kcp-ci-bot kcp-ci-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 26, 2025
@embik
Copy link
Member

embik commented Jan 26, 2025

/hold cancel

@kcp-ci-bot kcp-ci-bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 26, 2025
@kcp-ci-bot kcp-ci-bot merged commit a1b3400 into kcp-dev:main Jan 26, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. dco-signoff: yes Indicates the PR's author has signed the DCO. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants