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

Azure KMS (Key Vault) Server KeyManager plugin #3955

Closed
wants to merge 26 commits into from

Conversation

moe-omar
Copy link
Contributor

@moe-omar moe-omar commented Mar 9, 2023

This PR adds a server KMS plugin that uses Azure's Key Vault.

Pull Request check list

  • Commit conforms to CONTRIBUTING.md?
  • Proper tests/regressions included?
  • Documentation updated?

Affected functionality
No existing functionality affected. New server plugin added

Description of change
A new server keymanager plugin that uses Azure's Key Vault.

What/How was this new change tested?

  • Tested using all the supported key types (rsa-2048, rsa-4096, ec-p256, and ec-p384) for both JWT keys and CA keys.
  • Tested key rotation, refresh and keys cleanup for stale/unused keys belonging to the trust domain the server belongs to.
  • Tested authentication using Azure client/application credentials as well as using MSI in an Azure VM.
  • This involved running the server, registering agents and workloads and making sure SVID's are issued (signed by Key Vault keys) and can be validated using the bundle.
  • Added unit tests.

Copy link
Collaborator

@MarcosDY MarcosDY left a comment

Choose a reason for hiding this comment

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

Looks great!!!

doc/plugin_server_keymanager_azure_kms.md Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
// assert
if tt.updateKeyErr != "" {
require.NotNil(t, err)
require.Equal(t, tt.err, err.Error())
Copy link
Collaborator

Choose a reason for hiding this comment

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

you can use require.EqualError() that validate error is not nil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are strings we're comparing here though not errors

pkg/server/plugin/keymanager/azurekms/azurekms_test.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms_test.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms_test.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/client_fake.go Outdated Show resolved Hide resolved
@amartinezfayo amartinezfayo added this to the 1.6.2 milestone Mar 15, 2023
Copy link
Member

@amartinezfayo amartinezfayo left a comment

Choose a reason for hiding this comment

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

Thank you very much @moe-omar for this contribution! We really appreciate the effort put in this.

I have a couple of concerns:

  1. With the current logic, it seems that key versions will be kept in the Key Vault forever, unless the server starts with a different server ID (e.g. the metadata file is lost).
    This may not be super critical from the costing perspective, since the pricing model of the service is based on the number of transactions performed rather than the number of objects maintained. Still, it's concerning to me to keep keys that have been rotated and shouldn't be usable anymore.

  2. It doesn't seem that is possible to customize the access control of the keys created by SPIRE. This has been proved to be problematic in the past with other providers (see Make the KMS Key manager to create keys using a role-based policy when possible #2424 for details). Could we support influencing the access control of keys managed by the plugin?

pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
pkg/server/plugin/keymanager/azurekms/azurekms.go Outdated Show resolved Hide resolved
Comment on lines +38 to +39
Note that Azure does not support deleting individual key versions, instead, the key itself is deleted by the plugin
when it's no longer being used by a server in the trust domain the server belongs to.
Copy link
Member

Choose a reason for hiding this comment

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

I think that it may be problematic to keep key versions even if we know that they have been rotated.
Keys will only be deleted if the metadata file is lost, otherwise the server will continue to keep current keys active and never delete any of the old versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that's correct, when a key is rotated, the older versions are still active but they won't be used by the SPIRE server (the plugin will only use the current version). So even though the older versions are active, they are not usable in the SPIRE context.

@moe-omar
Copy link
Contributor Author

moe-omar commented Apr 2, 2023

Thank you very much @moe-omar for this contribution! We really appreciate the effort put in this.

I have a couple of concerns:

  1. With the current logic, it seems that key versions will be kept in the Key Vault forever, unless the server starts with a different server ID (e.g. the metadata file is lost).
    This may not be super critical from the costing perspective, since the pricing model of the service is based on the number of transactions performed rather than the number of objects maintained. Still, it's concerning to me to keep keys that have been rotated and shouldn't be usable anymore.
  2. It doesn't seem that is possible to customize the access control of the keys created by SPIRE. This has been proved to be problematic in the past with other providers (see Make the KMS Key manager to create keys using a role-based policy when possible #2424 for details). Could we support influencing the access control of keys managed by the plugin?

Thanks @amartinezfayo !

For 1, Key Vault doesn't support deleting specific key versions unfortunately, but I think it's possible to "disable" a key version (it can be reenabled though). You think that would be good enough?

Regarding 2, I looked at the original issue that motivated adding policies to AWS KMS keys, I think it's a little different with Key Vault. Policies are set at the Key Vault level not individual keys like in AWS KMS and I also don't think that you get a default policy when you create the Key Vault itself (I had to create a policy to give SPIRE access to keys in the Key Vault). So the way I think this would work is that a Key Vault + access policies to give SPIRE the appropriate access are provisioned separately (via Terraform for example) and the plugin is then configured to use the Key Vault.

Let me know if you think I'm missing something.

@amartinezfayo amartinezfayo modified the milestones: 1.6.2, 1.6.3, 1.6.4 Apr 4, 2023
@amartinezfayo
Copy link
Member

Key Vault doesn't support deleting specific key versions unfortunately, but I think it's possible to "disable" a key version (it can be reenabled though). You think that would be good enough?

I think that we should try to avoid having the plugin creating key versions indefinitely. Key Vault does not restrict the number of versions on a key, but storing a large number of versions may have impact in the performance of operations, and may be confusing to still have them showing in the console.
I would rather prefer that we delete the rotated keys. They will still be recoverable for a retention period but will not be showed by default in the console (you will only see them if you choose to manage the deleted keys).
We would create a new key when we need to generate a new one, and once it's created, we can delete the old one. What do you think?

Policies are set at the Key Vault level not individual keys like in AWS KMS and I also don't think that you get a default policy when you create the Key Vault itself (I had to create a policy to give SPIRE access to keys in the Key Vault). So the way I think this would work is that a Key Vault + access policies to give SPIRE the appropriate access are provisioned separately (via Terraform for example) and the plugin is then configured to use the Key Vault.

While I believe that the access control in Key Vault can also be defined at the key level (that's the resource scope in the case of Key Vault - https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal#step-1-identify-the-needed-scope) I agree that since there is no default policy applied, the situation is different than the other KMS plugins so it seems that we should be good here.

@evan2645 evan2645 modified the milestones: 1.6.4, 1.7.0 May 9, 2023
@MarcosDY MarcosDY modified the milestones: 1.7.0, 1.7.1 Jun 6, 2023
@evan2645 evan2645 modified the milestones: 1.7.1, 1.7.2 Jul 11, 2023
@amartinezfayo
Copy link
Member

@moe-omar are you still willing to finalize this implementation?
The SPIRE project has now access to Azure resources, which leaves us in a better position to pick up this work if needed.

Something that I haven't realized before is that the commits are not signed off, which we will need in order to be able to merge this. Please refer to https://github.com/apps/dco for more information about signing-off your commits.

Could you please have the commits signed-off and let us know how would you like to proceed with this work? Thanks!

moe-omar and others added 8 commits July 20, 2023 18:16
Signed-off-by: mo omar <momar@confluent.io>
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 2.8.1 to 3.0.1.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](sigstore/cosign-installer@9becc61...c3667d9)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: mo omar <momar@confluent.io>
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/golang/sys/releases)
- [Commits](golang/sys@v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: mo omar <momar@confluent.io>
Bumps [cloud.google.com/go/kms](https://github.com/googleapis/google-cloud-go) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](googleapis/google-cloud-go@dlp/v1.8.0...dlp/v1.9.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/kms
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: mo omar <momar@confluent.io>
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](golang/crypto@v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: mo omar <momar@confluent.io>
Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.14.4 to 0.14.5.
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](kubernetes-sigs/controller-runtime@v0.14.4...v0.14.5)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: mo omar <momar@confluent.io>
Signed-off-by: mo omar <momar@confluent.io>
- Add "CanReAttest" boolean filter in list agents method
- Update spire-server agent and entry commands to add new response fields: registration entry hint and agent canReAttest.

---------

Signed-off-by: Guilherme Carvalho <guilhermbrsp@gmail.com>
Signed-off-by: mo omar <momar@confluent.io>
moe-omar and others added 18 commits July 20, 2023 18:16
Signed-off-by: mo omar <momar@confluent.io>
…piffe#3958)

Bumps [github.com/aws/aws-sdk-go-v2/service/ec2](https://github.com/aws/aws-sdk-go-v2) from 1.86.0 to 1.89.0.
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/CHANGELOG.md)
- [Commits](aws/aws-sdk-go-v2@service/ec2/v1.86.0...service/ec2/v1.89.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2/service/ec2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: mo omar <momar@confluent.io>
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.111.0 to 0.112.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](googleapis/google-api-go-client@v0.111.0...v0.112.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: mo omar <momar@confluent.io>
Bumps [github.com/googleapis/gax-go/v2](https://github.com/googleapis/gax-go) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/googleapis/gax-go/releases)
- [Commits](googleapis/gax-go@v2.7.0...v2.7.1)

---
updated-dependencies:
- dependency-name: github.com/googleapis/gax-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Marcos Yacob <marcos.yacob@hpe.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Marcos Yacob <marcos.yacob@hpe.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Marcos Yacob <marcos.yacob@hpe.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Marcos Yacob <marcos.yacob@hpe.com>
Signed-off-by: mo omar <momar@confluent.io>
Signed-off-by: mo omar <momar@confluent.io>
Signed-off-by: mo omar <momar@confluent.io>
Signed-off-by: mo omar <momar@confluent.io>
Signed-off-by: mo omar <momar@confluent.io>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
Signed-off-by: mo omar <momar@confluent.io>
Co-authored-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
Signed-off-by: mo omar <momar@confluent.io>
@moe-omar moe-omar force-pushed the azure-keymanager-server-plugin branch from 98374cc to a7ff3fb Compare July 20, 2023 22:17
@rturner3 rturner3 modified the milestones: 1.7.2, 1.8.0 Aug 8, 2023
@amartinezfayo amartinezfayo removed this from the 1.8.0 milestone Aug 23, 2023
@amartinezfayo
Copy link
Member

amartinezfayo commented Aug 23, 2023

Closing in favor of #4458. Thank you @moe-omar for this contribution!

amartinezfayo added a commit to amartinezfayo/spire that referenced this pull request Aug 23, 2023
…owing changes:

- Change the implementation to create a new key when we need to generate a new one instead of adding a new version to an existing key. Once the key is created, the old one is deleted. Since key versions can't be deleted in Key Vault, this allows us to delete rotated keys.
- Avoid disposing keys that belong to the current server.
- Rename the plugin to azure_key_vault.
- Fix tests.

Signed-off-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
amartinezfayo added a commit to amartinezfayo/spire that referenced this pull request Aug 23, 2023
- Change the implementation to create a new key when we need to generate a new one instead of adding a new version to an existing key. Once the key is created, the old one is deleted. Since key versions can't be deleted in Key Vault, this allows us to delete rotated keys.
- Avoid disposing keys that belong to the current server.
- Rename the plugin to azure_key_vault.
- Fix tests.

Signed-off-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
amartinezfayo added a commit to amartinezfayo/spire that referenced this pull request Aug 24, 2023
- Change the implementation to create a new key when we need to generate a new one instead of adding a new version to an existing key. Once the key is created, the old one is deleted. Since key versions can't be deleted in Key Vault, this allows us to delete rotated keys.
- Avoid disposing keys that belong to the current server.
- Rename the plugin to azure_key_vault.
- Fix tests.

Signed-off-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
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.

6 participants