MWI: Minimal bound-keypair joining implementation#54371
Conversation
|
Outstanding TODOs:
|
c2cab06 to
042ce31
Compare
| // TODO: Is this wise? End users _shouldn't_ modify this, but this could | ||
| // interfere with cluster backup/restore. Options seem to be: | ||
| // - Let users create/update with status fields. They can break things, but | ||
| // maybe that's okay. No backup/restore implications. | ||
| // - Ignore status fields during creation and update. Any set value will be | ||
| // discarded here, and during update. This would still have consequences | ||
| // during cluster restores, but wouldn't raise errors, and the status | ||
| // field would otherwise be protected from easy tampering. Users might be | ||
| // confused as no user-visible errors would be raised if they used | ||
| // `tctl edit`. | ||
| // - Raise an error if status fields are changed. Worst restore | ||
| // implications, but tampering won't be easy, and will have some UX. | ||
| if tokenV2.Status.BoundKeypair != nil { | ||
| return trace.BadParameter("cannot create a bound_keypair token with set status") | ||
| } |
There was a problem hiding this comment.
Curious for thoughts on this. I think the simplest option is probably to just let users modify the resource freely, even if that has consequences.
There was a problem hiding this comment.
Curious for thoughts on this. I think the simplest option is probably to just let users modify the resource freely, even if that has consequences.
I definitely see this as being necessary for a backup/restore story - although part of me wishes we more generally had a lower-level mechanism for that (e.g enforce that only an admin can perform a backup/restore that overrides validation rules).
There was a problem hiding this comment.
I think this is one of the reason a resource's "status" is actually a sub-resource (with different RBAC permissions) in Kubernetes.
There was a problem hiding this comment.
Hmm, that makes sense. I'll just leave a note and keep it simple - we'll tell users not to modify the status field, but there won't be any actual guardrails in place so we don't get in the way of restore attempts.
|
@timothyb89 - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes. |
| // TODO: Is this wise? End users _shouldn't_ modify this, but this could | ||
| // interfere with cluster backup/restore. Options seem to be: | ||
| // - Let users create/update with status fields. They can break things, but | ||
| // maybe that's okay. No backup/restore implications. | ||
| // - Ignore status fields during creation and update. Any set value will be | ||
| // discarded here, and during update. This would still have consequences | ||
| // during cluster restores, but wouldn't raise errors, and the status | ||
| // field would otherwise be protected from easy tampering. Users might be | ||
| // confused as no user-visible errors would be raised if they used | ||
| // `tctl edit`. | ||
| // - Raise an error if status fields are changed. Worst restore | ||
| // implications, but tampering won't be easy, and will have some UX. | ||
| if tokenV2.Status.BoundKeypair != nil { | ||
| return trace.BadParameter("cannot create a bound_keypair token with set status") | ||
| } |
There was a problem hiding this comment.
Curious for thoughts on this. I think the simplest option is probably to just let users modify the resource freely, even if that has consequences.
I definitely see this as being necessary for a backup/restore story - although part of me wishes we more generally had a lower-level mechanism for that (e.g enforce that only an admin can perform a backup/restore that overrides validation rules).
boxofrad
left a comment
There was a problem hiding this comment.
This looks great! Nice work 👏🏻
| // TODO: Is this wise? End users _shouldn't_ modify this, but this could | ||
| // interfere with cluster backup/restore. Options seem to be: | ||
| // - Let users create/update with status fields. They can break things, but | ||
| // maybe that's okay. No backup/restore implications. | ||
| // - Ignore status fields during creation and update. Any set value will be | ||
| // discarded here, and during update. This would still have consequences | ||
| // during cluster restores, but wouldn't raise errors, and the status | ||
| // field would otherwise be protected from easy tampering. Users might be | ||
| // confused as no user-visible errors would be raised if they used | ||
| // `tctl edit`. | ||
| // - Raise an error if status fields are changed. Worst restore | ||
| // implications, but tampering won't be easy, and will have some UX. | ||
| if tokenV2.Status.BoundKeypair != nil { | ||
| return trace.BadParameter("cannot create a bound_keypair token with set status") | ||
| } |
There was a problem hiding this comment.
I think this is one of the reason a resource's "status" is actually a sub-resource (with different RBAC permissions) in Kubernetes.
| if !spec.Joining.Unlimited && !hasJoinsRemaining { | ||
| return nil, "", trace.AccessDenied("no rejoins remaining") | ||
| } |
There was a problem hiding this comment.
Should this check actually be inside the function passed to PatchToken in case the join counter has been modified concurrently?
There was a problem hiding this comment.
The decision is made here, but the mutator function (mutateStatusConsumeJoin) checks that:
- the join (now recovery) counter has not changed since the decision was made
- the join (now recovery) limit is at least the value it was when the decision was made
The mutator functions are run inside PatchToken, so those checks will always need to pass for the patch to succeed.
This includes a number of changes: - Rebases on the latest protos branch. This includes removal of the new keypair field on initial join, and adds messages for interactive keypair rotation. - Per the rebase, remaining_joins is removed in favor of using join_count for all calculations. The registration method and validatity checks have been updated to reference that instead. - Refactors challenge response function to allow for keypair rotation. We still don't implement rotation but the handler now receives the full proto message and produces a full proto response, so that we can easily handle the rotation case in the future. - Challenge validation checks time fields explicitly to ensure the client didn't tamper with them. - Added some missing docstrings
This is passed back to clients as part of the proto certs message as confirmation that rotation succeeded, so the value needed to be plumbed through.
We renamed and tweaked a number of proto fields, so this updates field references.
bde272b to
a2ca7e1
Compare
Co-authored-by: Dan Upton <daniel.upton@goteleport.com>
…-impl' into timothyb89/bound-keypair-minimal-impl
This splits the backend implementation of lib/boundkeypair out from the main bound keypair joining PR in #54371. It makes no changes beyond those already reviewed in that PR.
…54766) * MWI: Add lib/boundkeypair for bound keypair backend implementation This splits the backend implementation of lib/boundkeypair out from the main bound keypair joining PR in #54371. It makes no changes beyond those already reviewed in that PR. * Apply code review suggestions - Renames the experiment package - Fixes missing test helper flags - Renames the experiment env var - Uses strconv.ParseBool() * Simplify experiment flag
…ypair-minimal-impl
|
Small update note: I've split out |
* MWI: Minimal bound-keypair joining implementation This includes a minimal implementation of bound-keypair joining. This first iteration requires preregistered public keys, and requires `unlimited` and `insecure` flags to be set on bound keypair tokens. Minimal client-side implementation will be in a follow up PR. RFD: #52546 Closes #53373 * Refactor challenge response function, rebase on updated protos branch This includes a number of changes: - Rebases on the latest protos branch. This includes removal of the new keypair field on initial join, and adds messages for interactive keypair rotation. - Per the rebase, remaining_joins is removed in favor of using join_count for all calculations. The registration method and validatity checks have been updated to reference that instead. - Refactors challenge response function to allow for keypair rotation. We still don't implement rotation but the handler now receives the full proto message and produces a full proto response, so that we can easily handle the rotation case in the future. - Challenge validation checks time fields explicitly to ensure the client didn't tamper with them. - Added some missing docstrings * Add joinserver test * Fix lint error and add docstring * Add tests for bound keypair challenge validation * Remove client side package intended for other PR * Fix various lints * Add tests for RegisterUsingBoundKeypairMethod() * Fix lints * Add basic provisioning token CheckAndSetDefaults() tests * Include bound public key in RegisterUsingBoundKeypairMethod return This is passed back to clients as part of the proto certs message as confirmation that rotation succeeded, so the value needed to be plumbed through. * Fixes after upstream proto change We renamed and tweaked a number of proto fields, so this updates field references. * Apply suggestions from code review Co-authored-by: Dan Upton <daniel.upton@goteleport.com> * Remove TODO * Fix missed field rename * Fix broken test * Fix lurking nil pointer deref after field rename --------- Co-authored-by: Dan Upton <daniel.upton@goteleport.com>
* MWI: Minimal bound-keypair joining implementation This includes a minimal implementation of bound-keypair joining. This first iteration requires preregistered public keys, and requires `unlimited` and `insecure` flags to be set on bound keypair tokens. Minimal client-side implementation will be in a follow up PR. RFD: #52546 Closes #53373 * Refactor challenge response function, rebase on updated protos branch This includes a number of changes: - Rebases on the latest protos branch. This includes removal of the new keypair field on initial join, and adds messages for interactive keypair rotation. - Per the rebase, remaining_joins is removed in favor of using join_count for all calculations. The registration method and validatity checks have been updated to reference that instead. - Refactors challenge response function to allow for keypair rotation. We still don't implement rotation but the handler now receives the full proto message and produces a full proto response, so that we can easily handle the rotation case in the future. - Challenge validation checks time fields explicitly to ensure the client didn't tamper with them. - Added some missing docstrings * Add joinserver test * Fix lint error and add docstring * Add tests for bound keypair challenge validation * Remove client side package intended for other PR * Fix various lints * Add tests for RegisterUsingBoundKeypairMethod() * Fix lints * Add basic provisioning token CheckAndSetDefaults() tests * Include bound public key in RegisterUsingBoundKeypairMethod return This is passed back to clients as part of the proto certs message as confirmation that rotation succeeded, so the value needed to be plumbed through. * Fixes after upstream proto change We renamed and tweaked a number of proto fields, so this updates field references. * Apply suggestions from code review Co-authored-by: Dan Upton <daniel.upton@goteleport.com> * Remove TODO * Fix missed field rename * Fix broken test * Fix lurking nil pointer deref after field rename --------- Co-authored-by: Dan Upton <daniel.upton@goteleport.com>
…54766) * MWI: Add lib/boundkeypair for bound keypair backend implementation This splits the backend implementation of lib/boundkeypair out from the main bound keypair joining PR in #54371. It makes no changes beyond those already reviewed in that PR. * Apply code review suggestions - Renames the experiment package - Fixes missing test helper flags - Renames the experiment env var - Uses strconv.ParseBool() * Simplify experiment flag
…ion (#54766) (#55079) * MWI: Add lib/boundkeypair for bound keypair backend implementation (#54766) * MWI: Add lib/boundkeypair for bound keypair backend implementation This splits the backend implementation of lib/boundkeypair out from the main bound keypair joining PR in #54371. It makes no changes beyond those already reviewed in that PR. * Apply code review suggestions - Renames the experiment package - Fixes missing test helper flags - Renames the experiment env var - Uses strconv.ParseBool() * Simplify experiment flag * Fix broken test
) * MWI: Minimal bound-keypair joining implementation (#54371) * MWI: Minimal bound-keypair joining implementation This includes a minimal implementation of bound-keypair joining. This first iteration requires preregistered public keys, and requires `unlimited` and `insecure` flags to be set on bound keypair tokens. Minimal client-side implementation will be in a follow up PR. RFD: #52546 Closes #53373 * Refactor challenge response function, rebase on updated protos branch This includes a number of changes: - Rebases on the latest protos branch. This includes removal of the new keypair field on initial join, and adds messages for interactive keypair rotation. - Per the rebase, remaining_joins is removed in favor of using join_count for all calculations. The registration method and validatity checks have been updated to reference that instead. - Refactors challenge response function to allow for keypair rotation. We still don't implement rotation but the handler now receives the full proto message and produces a full proto response, so that we can easily handle the rotation case in the future. - Challenge validation checks time fields explicitly to ensure the client didn't tamper with them. - Added some missing docstrings * Add joinserver test * Fix lint error and add docstring * Add tests for bound keypair challenge validation * Remove client side package intended for other PR * Fix various lints * Add tests for RegisterUsingBoundKeypairMethod() * Fix lints * Add basic provisioning token CheckAndSetDefaults() tests * Include bound public key in RegisterUsingBoundKeypairMethod return This is passed back to clients as part of the proto certs message as confirmation that rotation succeeded, so the value needed to be plumbed through. * Fixes after upstream proto change We renamed and tweaked a number of proto fields, so this updates field references. * Apply suggestions from code review Co-authored-by: Dan Upton <daniel.upton@goteleport.com> * Remove TODO * Fix missed field rename * Fix broken test * Fix lurking nil pointer deref after field rename --------- Co-authored-by: Dan Upton <daniel.upton@goteleport.com> * Fix build due to backport changes * Backport additional test changes --------- Co-authored-by: Dan Upton <daniel.upton@goteleport.com>
This includes a minimal implementation of bound-keypair joining. This first iteration requires preregistered public keys, and requires
unlimitedandinsecureflags to be set on bound keypair tokens.Minimal client-side implementation will be in a follow up PR.
RFD: #52546
Protos PR: #53566
Client PR: #54372
Closes #53373