Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/srinandan/cloudkms-encryption
A sidecar service for Apigee hybrid runtime to interact with Cloud KMS and Secret Manager
https://github.com/srinandan/cloudkms-encryption
apigee apigee-hybrid cloudkms encryption google-cloud secretsmanager sidecar
Last synced: 17 days ago
JSON representation
A sidecar service for Apigee hybrid runtime to interact with Cloud KMS and Secret Manager
- Host: GitHub
- URL: https://github.com/srinandan/cloudkms-encryption
- Owner: srinandan
- License: apache-2.0
- Created: 2019-12-18T07:16:26.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2020-06-12T22:26:30.000Z (over 4 years ago)
- Last Synced: 2024-11-09T17:15:53.613Z (2 months ago)
- Topics: apigee, apigee-hybrid, cloudkms, encryption, google-cloud, secretsmanager, sidecar
- Language: Go
- Homepage:
- Size: 51.8 KB
- Stars: 0
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: change-project.sh
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# cloudkms-encryption
[![Go Report Card](https://goreportcard.com/badge/github.com/srinandan/cloudkms-encryption)](https://goreportcard.com/report/github.com/srinandan/cloudkms-encryption)
This service is meant to run as a sidecar to the Apigee hybrid API gateway (also known as Message Processor). The service takes a Google Cloud Service Account as a parameter and is used to encrypt or decrypt text using [Cloud KMS](https://cloud.google.com/kms/). The service can also store and retrieve data from GCP [Secret Manager](https://cloud.google.com/secret-manager/docs/).
## Use Case
This service is meant to be used with the Apigee hybrid [API Runtime](https://docs.apigee.com/hybrid). When developing API Proxies on Apigee, a developer may want to encrypt or decrypt parts of the payload. Google Cloud provides [Cloud KMS](https://cloud.google.com/kms/). The services uses Cloud KMS libraries to encrypt or decrpyt data.
Sensitive information often needs to be stored in a secure location. GCP Secret Manager provides a service (like a vault) to store sensitive information.
## Prerequisites
* Apigee hybrid runtime installed on GKE or GKE on-premises (v1.13.x)
* A GCP Project with Cloud KMS and Secret Manager APIs enabled
* A Service Account with the following roles:
a. Cloud KMS CryptoKey Encrypter/Decrypter
b. Secret Manager Admin
c. Secret Manager Secret Accessor
d. Cloud KMS CryptoKey Public Key Viewer## Prerequisites to build
* kubectl 1.13 or higher
* docker 19.x or higher (if not using skaffold)
* skaffold 1.1.0 or higher (optional)## Installation
### Installation via kubectl
1. Build the [docker image](./Dockerfile) `docker build -t gcr.io/{project-id}/cloudkms-encryption`
2. Push to a container registry `docker push gcr.io/{project-id}/cloudkms-encryption`
3. Modify the kubernetes [manifest](./cloudkms-encryption.yaml)```bash
kubectl create secret -n {namespace} generic cloudkms-encryption-svc-account --from-file client_secret.json
kubectl apply -n {namespace} -f cloudkms-encryption.yaml
```### Installation via Skaffold
This application can also be installed via [skaffold](https://skaffold.dev/). Modify the [skaffold.yaml](./skaffold.yaml) to set the appropriate project name.
```bash
skaffold run
```#### Errors in Skaffold
When rerunning/installing the application, you may observe errors like this:
```bash
- Error from server (Invalid): error when applying patch:
...
...
`selector` does not match template `labels`
```There is an open [issue](https://github.com/GoogleContainerTools/skaffold/issues/3133) for this in the skaffold project.
Workaound: first run `skaffold delete` and then `skaffold run`
## Supported Operations
### Environment Variables
The following environment variables are mandatory:
* `GOOGLE_APPLICATION_CREDENTIALS` - Path to service account json
* `PROJECT_ID` - GCP project id
* `REGION` - Crypto key region
* `KEY_RING` - Crypto key ring
* `SYM_CRYPTO_KEY` - Symmaetric key name
* `ASYM_CRYPTO_KEY` - Assymetric key name### Encrypt data (Symmetric Encryption)
Path: `/encrypt`
Method: `POST`
Accept: text/plain
Content-Type: application/jsonThe response is base64 encoded
```bash
curl 0.0.0.0:8080/encrypt -d 'sample clear text data'
```Output:
```bash
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=UTF-8
<
{"payload":"CiQATxZWh3Ky1nUed8+Uzfy1rrZ0hUrvt8J0OZUyauXbrvv2TwwSLwCPcW8BdQBpa9PXMWdOUk1c8SLNPG7J4NCyVXNfF8FLBnhgXYMGNCeY4B0673bf"}
```### Decrypt data (Symmetric Decryption)
Path: `/decrypt`
Method: `POST`
Accept: text/plain
Content-Type: application/json```bash
curl 0.0.0.0:8080/decrypt -d 'CiQATxZWh3Ky1nUed8+Uzfy1rrZ0hUrvt8J0OZUyauXbrvv2TwwSLwCPcW8BdQBpa9PXMWdOUk1c8SLNPG7J4NCyVXNfF8FLBnhgXYMGNCeY4B0673bf'
```Output:
```bash
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=UTF-8
<
{"payload":"sample clear text data"}
```### Encrypt data (Asymmetric Encryption)
Path: `/asmencrypt`
Method: `POST`
Accept: text/plain
Content-Type: application/jsonThe response is base64 encoded
```bash
curl localhost:8080/asmencrypt -H "Content-Type: text/plain" -d 'this is a test'
```Output:
```json
{"payload":"27dWLYAtq3tI7E3ukT5++9vEoevbb+r3uDB/CqeWxt7JrFtcoy4EMurcnhyVbsDjd7AwYB3icxs/ETEGmrxFESOR8xOI7vE2kCG+8xlFbMitIQDRsmuCwRNMyYfQMyUPtvN+eQ9YJmpxo7YqprOCk3OQ4PDew9R4VAVJxUurGbjNW5gvzLSfutqyR5y7/Ey54HRlNZCWD7GkHHi1YTIp/oc0VL9yr4K8D6P16aH4lF2H0qBF1dOGJCK19ArAZeRwPCauETdGgWepsB9BJIAvsH2CCgOGkACQHgYFIWoBCGW8CEONrlsWh455KctcZ7s4DfMI0YhTsPhu6OLpDbsTsQ=="}
```### Decrypt data (Asymmetric Decryption)
Path: `/asmdecrypt`
Method: `POST`
Accept: text/plain
Content-Type: application/json```bash
curl localhost:8080/asmdecrypt -H "Content-Type: text/plain" -d '27dWLYAtq3tI7E3ukT5++9vEoevbb+r3uDB/CqeWxt7JrFtcoy4EMurcnhyVbsDjd7AwYB3icxs/ETEGmrxFESOR8xOI7vE2kCG+8xlFbMitIQDRsmuCwRNMyYfQMyUPtvN+eQ9YJmpxo7YqprOCk3OQ4PDew9R4VAVJxUurGbjNW5gvzLSfutqyR5y7/Ey54HRlNZCWD7GkHHi1YTIp/oc0VL9yr4K8D6P16aH4lF2H0qBF1dOGJCK19ArAZeRwPCauETdGgWepsB9BJIAvsH2CCgOGkACQHgYFIWoBCGW8CEONrlsWh455KctcZ7s4DfMI0YhTsPhu6OLpDbsTsQ=='
```Output:
```json
{"payload":"this is a test"}
```### Create Secret
Creates a new secret in Secret Manager.
Path: `/secrets`
Method: `POST`
Accept: application/json
Content-Type: application/json```bash
curl localhost:8080/secrets -H "Content-Type: application/json" -d '{"secretId":"test"}'
```### Store Secret
Stores a secret in Secret Manager, optionally encrypts and stores a section in Secret Manager
Path: `/storesecrets`
Method: `POST`
Accept: application/json
Content-Type: application/json```bash
curl localhost:8080/storesecrets -H "Content-Type: application/json" -d '{"secretId":"test","payload":"test data"}'
```The same method can be used to encrypt first with Cloud KMS and then store in Secret Manager.
```json
{
"secretId":"test",
"payload":"test data",
"encrypted": true
}
```### Access a secret
Access a secret in Secret Manager, optionally decrypts the secret first and retrieves in clear text
Path: `/secrets/{secretName}/{version}`
Method: `GET`
Accept: application/json
Content-Type: application/json```bash
curl localhost:8080/secrets/test/1
```The same method can be used to access the data from Secret Manager and them decrypt with Cloud KMS
```bash
curl localhost:8080/secrets/test/1?ecrypted=true
```## Access patterns from Apigee hyrid
A typical pattern/example would be to use a [Service Callout policy](https://docs.apigee.com/api-platform/reference/policies/service-callout-policy) to access operations supported by the service.