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 SDK helpers and Core stubs for plugins to communicate with Enterprise Rotation Manager #29273

Merged
merged 13 commits into from
Jan 7, 2025

Conversation

vinay-gopalan
Copy link
Contributor

Description

Adds helpers for all plugins to communicate with the upcoming Rotation Manager (Enterprise-only) feature. This PR adds the helper methods and RPC interfaces that will allow all built-in and external plugins to talk to the Rotation Manager once it exists.

This PR also adds helpers to create Rotation Job structures easily with the help of methods in sdk/logical/rotation_job.go and parse Rotation Schedules with a common helper library in sdk/logical/schedule.go.

Note: This PR will not implement the Rotation Manager. Attempting to use the feature will result in a not implemented in CE error (from CE Stubs)

An example of how these helpers can be used by plugins is provided with the builtin AWS Secrets plugin. A test with AWS secrets also confirms that the feature is not implemented on CE.

@vinay-gopalan vinay-gopalan requested review from a team as code owners January 2, 2025 18:12
@vinay-gopalan vinay-gopalan requested review from hashneo and removed request for hashneo January 2, 2025 18:12
@github-actions github-actions bot added the hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed label Jan 2, 2025
@vinay-gopalan vinay-gopalan added this to the 1.19.0-rc milestone Jan 2, 2025
sdk/logical/schedule.go Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Jan 2, 2025

CI Results:
All Go tests succeeded! ✅

Copy link

github-actions bot commented Jan 2, 2025

Build Results:
All builds succeeded! ✅

vault/dynamic_system_view.go Outdated Show resolved Hide resolved
builtin/logical/aws/path_config_root.go Outdated Show resolved Hide resolved
return logical.ErrorResponse("error registering rotation job: %s", err), nil
}

rc.RotationID = rotationID
Copy link
Contributor

Choose a reason for hiding this comment

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

When the backend is reloaded, will this value be overwritten with a new value? Should we check if the mount's root rotation job has already been registered before registering?

Copy link
Member

Choose a reason for hiding this comment

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

Good catch, don't think we accounted for this yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a good question. Like Robert said, we haven't worked this out yet, but one thought I had was the following:

We can have the RM keep track of each Rotation ID in the form of a list. The structure of Rotation IDs encodes the Request Path as well. Before registering a root credential, we can check the incoming Rotation Job's ReqPath, and if that Path has already been stored in our Rotation IDs list, we can avoid registering and log a warning — stating the user needs to delete a rotation job before re-registering another for the same mount.

Can sketch out some ideas to enable tracking IDs in the case where the plugin crashes/reloads, and will put that up as part of the Enterprise PR 👍🏼

Copy link
Contributor

Choose a reason for hiding this comment

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

The structure of Rotation IDs encodes the Request Path as well

Sorry to keep coming back to this, but if we are already doing this in Vault Core, why are we requiring plugins to store this mapping as well?

sdk/helper/automatedrotationutil/fields.go Outdated Show resolved Hide resolved
RotationTTL int `json:"rotation_ttl"`

// RotationID is the unique ID of the registered rotation job.
// Used by the plugin to track the rotation.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should add more guidance on the care plugin authors must take with this value.

"For static roles, plugin authors must maintain and store a mapping of role path to rotation ID. This should then be used to..."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good callout! We can note this down as an item to address as part of our Plugin Developer Facing Docs

sdk/logical/rotation_job.go Outdated Show resolved Hide resolved
sdk/logical/schedule.go Outdated Show resolved Hide resolved
sdk/logical/rotation_job.go Outdated Show resolved Hide resolved
sdk/logical/rotation_job.go Outdated Show resolved Hide resolved
sdk/logical/schedule.go Outdated Show resolved Hide resolved
}

b.Logger().Debug("Registering rotation job", "mount", req.MountPoint+req.Path)
rotationID, err := b.System().RegisterRotationJob(ctx, rotationJob)
Copy link
Contributor

Choose a reason for hiding this comment

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

How and when does a rotation job get deregistered?

Copy link
Member

Choose a reason for hiding this comment

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

Good call out, not sure if we have yet discussed the idea of deregistering rotation. Is it something we should allow? I wonder if there's any differences between allowing automated rotation to be disabled versus a pause mechanism meant only for emergencies?

Copy link
Contributor Author

@vinay-gopalan vinay-gopalan Jan 6, 2025

Choose a reason for hiding this comment

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

De-registration / off-boarding should be allowed IMO, if only as a disabling escape hatch. Added a method on the SystemView to Deregister a rotation job. This will be triggered if a boolean disable_automated_rotation (subject to change) is set to true on the config. Example of this in AWS is linked here

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking about the disable and delete actions. Without deregistration, how do we stop rotations when a mount is disabled or a static role is deleted that have been registered with the Rotation Manager?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I see, that's a good question! So this won't be visible in this PR, but the Enterprise Rotation Manager implementation does store the request path that a credential comes from. The RM also has access to core.Router, and I believe we should be able to use MatchingMountEntry to determine if a given mount exists.

This will be performed on the Enterprise Rotation Manager code (before it routes the request to the plugin backend, it can confirm that a matching mount entry exists for handling the request). I can make sure to test that flow, and call it out in the Enterprise PR once it is opened (after this PR is merged in so that CI in Enterprise is happy)

Copy link
Contributor

Choose a reason for hiding this comment

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

it can confirm that a matching mount entry exists for handling the request

I think we will want to deregister a job when the backend/role is disabled or deleted, right?

fairclothjm
fairclothjm previously approved these changes Jan 7, 2025
sdk/logical/system_view.go Outdated Show resolved Hide resolved
@vinay-gopalan vinay-gopalan merged commit 27bd3e9 into main Jan 7, 2025
90 of 92 checks passed
@vinay-gopalan vinay-gopalan deleted the VAULT-33156/rotation-manager-ce-stubs branch January 7, 2025 22:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants