kbs/plugins: add provisioner plugin#1305
Conversation
fitzthum
left a comment
There was a problem hiding this comment.
Nice. A couple high-level comments, but this seems generally workable.
| // and scoped roles, e.g.: | ||
| // [admin] type = "Simple" | ||
| // [[admin.personas]] id = "provisioner" public_key_path = "..." | ||
| // [[admin.roles]] id = "provisioner" allowed_endpoints = "^/kbs/v0/provisioner/.*$" |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Rethinking about this, if the hook side car is not trusted then the private key would be compromised too and in that case using insecureAll would have the same effect.
c4abca3 to
cfde11f
Compare
Xynnn007
left a comment
There was a problem hiding this comment.
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? |
cfde11f to
5f9d4b3
Compare
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. |
|
Personally, I think it's fine to have this be an internal plugin. Not all users will use every plugin. |
5f9d4b3 to
9170397
Compare
9170397 to
fb51ec8
Compare
Xynnn007
left a comment
There was a problem hiding this comment.
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.
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.
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? |
|
0bc946f to
c0002f9
Compare
I addressed this comment in last version. |
|
|
||
| // Config (deserialized from kbs-config.toml) | ||
| #[derive(Deserialize, Clone, Debug, PartialEq)] | ||
| pub struct ProvisionerConfig { |
There was a problem hiding this comment.
Would it make sense to use the Pkcs11Config here in case it is available?
c0002f9 to
d098db2
Compare
Add a provisioner plugin that automates resource creation for
confidential VMs. When a POST request is received at
`kbs/v0/provisioner/provision`, the plugin:
1. Generates a UUID and an encryption key. The UUID is deterministic and
relies on the VM's namespace and name.
2. Builds an initdata.toml pointing the guest to the KBS resource path
`provisioner/{UUID}/root` where the key is stored.
3. Stores the key in the plugin storage backend so the guest can retrieve
it after attestation via the existing `provisioner` plugin.
4. Returns a JSON response:
struct ProvisionResponse {
uuid: String,
oemstring: String,
mrconfigid: String,
hostdata: String,
resource_path: String,
}
The VMM must inject `oemstring` and `mrconfigid`/`hostdata` 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.
- `hostdata`: base64-encoded SHA-384 hash of initdata.toml, injected
into the SEV hostData 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, not a TEE guest. Only the GET operation
requires attestation.
Assisted-by: Claude:claude-4.6-opus-high
Signed-off-by: Matias Ezequiel Vara Larsen <mvaralar@redhat.com>
d098db2 to
30a7083
Compare

Add a provisioner plugin that automates LUKS key generation and resource creation for confidential VMs. When a POST request is received at
kbs/v0/provisioner/provision, the plugin:Generates a UUID and a random LUKS encryption key. The UUID is generated from the VM's namespace and name.
Builds an initdata.toml pointing the guest to the KBS resource path
default/{UUID}/rootwhere the key is stored.Stores the key in the KBS storage backend so the guest can retrieve it after attestation via the existing
resourceplugin.Returns a JSON response:
struct ProvisionResponse { uuid: String, oemstring: String, mrconfigid: String, resource_path: String, }
The VMM must inject
oemstringandmrconfigidinto 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.