lukasjarosch / skipper

Inventory based templated configuration library inspired by the kapitan project
https://lukasjarosch.github.io/skipper/
MIT License
11 stars 3 forks source link

Feat/gcp kms support #53

Closed andaryjo closed 5 months ago

andaryjo commented 1 year ago

Implementation of https://github.com/lukasjarosch/skipper/issues/46

Adds the GCP KMS Secrets Driver. To use it add following to your <target>.skipper.secrets.drivers target configuration:

gcpkms:
  key_name: "projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<keyname>"

The key name represents the full key URI. The naming scheme might be confusing but is consistent with the SDK. Both the URI and the key name are called name. I did not (yet) implement the option to provide project, location, key ring, etc. as dedicated arguments because as opposed to the Azure SDK, the GCP SDK wants to have the URI for the request. Let me know if you think the single arguments implementation should be included as well.

Open issues

Fixed: I'm still struggling with key versions. With Cloud KMS, rotating a key does not disable older versions and you can still decrypt secrets with the older version without actually needing to specify the version, even if you changed the primary (default) version. Somehow that just works until you disable the old version.

In theory you should be able to specify the key version by appending it to the URI: projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<keyname>/cryptoKeyVersions/<version>. This is the URI for key versions, and supported within the SDK (as you can see here), but it the API throws me an error and I wasn't successful fixing this yet:

failed to replace secret value: failed to decrypt input: rpc error: code = InvalidArgument desc = projects/tmp-joe-skipper-test/locations/europe-west3/keyRings/test/cryptoKeys/quickstart/cryptoKeyVersions/2 is not a valid resource type for this request.

Testing instructions

  1. Create a new key ring (equivalent to Azure Key Vault, but only for keys) and a new key:
gcloud kms keyrings create "myring" --location "europe-west3"
gcloud kms keys create "mykey" --location "europe-west3" --keyring "myring" --purpose "encryption" 
  1. Encrypt a secret:
printf "supersecret" | gcloud kms encrypt --key "mykey" --keyring "myring" --location "europe-west3" --plaintext-file=- --ciphertext-file=- | base64
  1. Place that output as secret in your skipper inventory secret path:
data: <encryption output>
type: gcpkms
  1. Configure the GCP KMS Secret Driver in your target as stated above.

  2. Make sure skipper can authenticate itself against Google Cloud by either pointing to service account credentials with theGOOGLE_APPLICATION_CREDENTIALS environment variable or running gcloud auth application-default login to let skipper authenticate itself as you. As this is a test environment, just be the owner of the project to not worry about permissions.

  3. Run skipper.

andaryjo commented 1 year ago

Unfortunately based on https://github.com/lukasjarosch/skipper/pull/51, something went wrong with the branches there.

andaryjo commented 1 year ago

This is the URI for key versions, and supported within the SDK, but it the API throws me an error

So I figured this one out. The decrypt method does actually not support specification of a key version, as you can see here.

The resource name of the CryptoKey to use for decryption. The server will choose the appropriate version.

This means we will need to omit the key version - if specified - for the decrypt request from the key name.