Skip to content

kbs/plugins: add provisioner plugin#1305

Draft
MatiasVara wants to merge 1 commit into
confidential-containers:mainfrom
MatiasVara:add-provision-plugin
Draft

kbs/plugins: add provisioner plugin#1305
MatiasVara wants to merge 1 commit into
confidential-containers:mainfrom
MatiasVara:add-provision-plugin

Conversation

@MatiasVara
Copy link
Copy Markdown

Add a provisioner plugin that automates LUKS key generation and resource creation for confidential VMs on behalf of a KubeVirt hook sidecar. When a POST request is received at kbs/v0/provisioner/provision, the plugin:

  1. Generates a random UUID and a LUKS encryption key.

  2. Builds an initdata.toml pointing the guest to the KBS resource path default/{UUID}/root where the key is stored.

  3. Stores the key in the KBS storage backend so the guest can retrieve it after attestation via the existing resource plugin.

  4. Returns a JSON response:

    struct ProvisionResponse { uuid: String, oemstring: String, mrconfigid: String, resource_path: String, }

The VMM must inject oemstring and mrconfigid into the VM domain:

  • oemstring: base64-encoded initdata.toml, passed via SMBIOS OEM string so the guest knows where to fetch its key.
  • mrconfigid: base64-encoded SHA-384 hash of initdata.toml, injected into the TDX mrConfigId register to bind the VM configuration to hardware attestation.

The plugin also supports DELETE requests at
kbs/v0/provisioner/provision/{uuid} to remove provisioned resources.

Authentication is routed through the KBS admin auth path (validate_auth returns true) instead of requiring a TEE attestation token, since the caller is infrastructure (hook sidecar), not a TEE guest.

Note that I already did a first review using Claude and I left a few TODOs with open questions.

Copy link
Copy Markdown
Member

@fitzthum fitzthum left a comment

Choose a reason for hiding this comment

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

Nice. A couple high-level comments, but this seems generally workable.

Comment thread kbs/src/plugins/implementations/provisioner.rs Outdated
// that the `resource` plugin reads from.
// TODO: Using overwrite: true could silently replace another VM's key
// on UUID collision. Use overwrite: false and handle the conflict error,
// or check existence before writing.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah probably should not do this. Instead, you can introduce another endpoint to this plugin for serving resources.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Can you elaborate?

Comment thread kbs/src/plugins/implementations/provisioner.rs
// and scoped roles, e.g.:
// [admin] type = "Simple"
// [[admin.personas]] id = "provisioner" public_key_path = "..."
// [[admin.roles]] id = "provisioner" allowed_endpoints = "^/kbs/v0/provisioner/.*$"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Note that this config is changing a bit, but I think your approach is generally sound. You will have an admin token just for this plugin that will be given to the hook sidecar thing, right?

Comment thread kbs/src/plugins/implementations/provisioner.rs Outdated
@MatiasVara MatiasVara force-pushed the add-provision-plugin branch 2 times, most recently from c4abca3 to cfde11f Compare May 4, 2026 12:47
Copy link
Copy Markdown
Member

@Xynnn007 Xynnn007 left a comment

Choose a reason for hiding this comment

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

Hi @MatiasVara welcome! I left some ideas although it's still draft. I have a question before codes:

KBS now has a mechanism named "external-plugin". See docs. To make it simple, it provides a way for KBS to connect to a gRPC server aside of KBS. In this way, we do not need to make any changes to KBS code. What we need is just changing the KBS config a little. In this way you can have a self-and-easy-maintained plugin server, do you consider to use the mechanism?

Comment thread kbs/Cargo.toml Outdated
Comment thread kbs/src/plugins/implementations/provisioner.rs
Comment thread kbs/src/plugins/implementations/provisioner.rs Outdated
Comment thread kbs/src/plugins/implementations/provisioner.rs Outdated
Comment thread kbs/src/plugins/implementations/provisioner.rs Outdated
@MatiasVara
Copy link
Copy Markdown
Author

MatiasVara commented May 6, 2026

Hi @MatiasVara welcome! I left some ideas although it's still draft. I have a question before codes:

KBS now has a mechanism named "external-plugin". See docs. To make it simple, it provides a way for KBS to connect to a gRPC server aside of KBS. In this way, we do not need to make any changes to KBS code. What we need is just changing the KBS config a little. In this way you can have a self-and-easy-maintained plugin server, do you consider to use the mechanism?

Oh cool, I did not know that there is that mechanism. I'll investigate it! Do you think it is better that way that having a plugin in-tree?

@MatiasVara MatiasVara force-pushed the add-provision-plugin branch from cfde11f to 5f9d4b3 Compare May 6, 2026 09:50
@Xynnn007
Copy link
Copy Markdown
Member

Xynnn007 commented May 6, 2026

Do you think it is better that way that having a plugin in-tree?

If it's not a concrete scenario for CoCo, I'd like to say yes. As it's defined by you and can be modified anytime. We will also be benefit of less maintainance effort ; )

@MatiasVara
Copy link
Copy Markdown
Author

MatiasVara commented May 6, 2026

Do you think it is better that way that having a plugin in-tree?

If it's not a concrete scenario for CoCo, I'd like to say yes. As it's defined by you and can be modified anytime. We will also be benefit of less maintainance effort ; )

I think the plan is to use it in together with kubevirt to provide resources to encrypt the disk for confidential VMs. I completely got you point. It's just that for me it would be easier if it is already in trustee and someone can just enable/disable it but I do not have an strong opinion about it.

@fitzthum
Copy link
Copy Markdown
Member

fitzthum commented May 6, 2026

Personally, I think it's fine to have this be an internal plugin. Not all users will use every plugin.

@MatiasVara MatiasVara force-pushed the add-provision-plugin branch from 5f9d4b3 to 9170397 Compare May 6, 2026 16:07
Comment thread kbs/src/plugins/implementations/provisioner.rs
Add a provisioner plugin that automates LUKS key generation and resource
creation for confidential VMs on behalf of a KubeVirt hook sidecar.
When a POST request is received at `kbs/v0/provisioner/provision`, the
plugin:

1. Generates a random UUID and a LUKS encryption key.
2. Builds an initdata.toml pointing the guest to the KBS resource path
   `default/{UUID}/root` where the key is stored.
3. Stores the key in the KBS storage backend so the guest can retrieve
   it after attestation via the existing `resource` plugin.
4. Returns a JSON response:

   struct ProvisionResponse {
       uuid: String,
       oemstring: String,
       mrconfigid: String,
       resource_path: String,
   }

The VMM must inject `oemstring` and `mrconfigid` into the VM domain:
- `oemstring`: base64-encoded initdata.toml, passed via SMBIOS OEM
  string so the guest knows where to fetch its key.
- `mrconfigid`: base64-encoded SHA-384 hash of initdata.toml, injected
  into the TDX mrConfigId register to bind the VM configuration to
  hardware attestation.

The plugin also supports DELETE requests at
`kbs/v0/provisioner/provision/{uuid}` to remove provisioned resources.

Authentication is routed through the KBS admin auth path
(validate_auth returns true) instead of requiring a TEE attestation
token, since the caller is infrastructure (hook sidecar), not a TEE
guest.

Assisted-by: Claude:claude-4.6-opus-high
Signed-off-by: Matias Ezequiel Vara Larsen <mvaralar@redhat.com>
@MatiasVara MatiasVara force-pushed the add-provision-plugin branch from 9170397 to fb51ec8 Compare May 7, 2026 14:58
Copy link
Copy Markdown
Member

@Xynnn007 Xynnn007 left a comment

Choose a reason for hiding this comment

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

Thanks for adopting previous comments!

If we want to get this into the repo, let me take a closer look at the design.

Based on the concrete logic and dataflow of the plugin, I’m wondering what was the reason for choosing a plugin approach instead of kbs-client+script inside KubeVirt hook sidecar to generate the UUID and set KBS resource?

This question came up when I noticed the storage member inside Provisioner struct. KBS resource plugin is a plugin, and if there is another KeyValueStorageInstance as introduced here with write access, it could potentially race with KBS resource writes.

But yes, if the original idea is that key generation can be triggered by an untrusted entity while keeping the key hidden, then this approach makes sense.

Comment thread kbs/src/plugins/implementations/provisioner.rs
Comment thread kbs/src/plugins/implementations/provisioner.rs
Comment thread kbs/src/plugins/implementations/provisioner.rs
@MatiasVara
Copy link
Copy Markdown
Author

Thanks for adopting previous comments!

If we want to get this into the repo, let me take a closer look at the design.

Based on the concrete logic and dataflow of the plugin, I’m wondering what was the reason for choosing a plugin approach instead of kbs-client+script inside KubeVirt hook sidecar to generate the UUID and set KBS resource?

My first PoC was something called Secret-Operator that would do exactly that but I had the problem that I can't trust k8s infrastructure so I decided to deploy it in a different infrastructure that I can trust. Then, I though that, to reduce the number of components, I would prefer to have it in trustee.

This question came up when I noticed the storage member inside Provisioner struct. KBS resource plugin is a plugin, and if there is another KeyValueStorageInstance as introduced here with write access, it could potentially race with KBS resource writes.

yes, It could. What would be the problem of that? I am trying to understand the implications of this design.

But yes, if the original idea is that key generation can be triggered by an untrusted entity while keeping the key hidden, then this approach makes sense.

The whole idea is:
image

@fitzthum
Copy link
Copy Markdown
Member

yes, It could. What would be the problem of that? I am trying to understand the implications of this design.

I don't think you should be accessing the resource storage from the plugin. The plugin should have its own storage namespace. This means adding an endpoint to get the resource via the plugin. This may run into issues with the lack of plugin support in the client, but it's still the way to go I think.

@MatiasVara
Copy link
Copy Markdown
Author

yes, It could. What would be the problem of that? I am trying to understand the implications of this design.

I don't think you should be accessing the resource storage from the plugin. The plugin should have its own storage namespace. This means adding an endpoint to get the resource via the plugin. This may run into issues with the lack of plugin support in the client, but it's still the way to go I think.

I can understand that would require changes on the client. Should it also require a PR to somehow give support for the plugin?

@fitzthum
Copy link
Copy Markdown
Member

I can understand that would require changes on the client. Should it also require a PR to somehow give support for the plugin?

See confidential-containers/guest-components#1468

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants