Asherah Server is intended to be used by those who wish to utilize application-layer encryption but are unable to take advantage of the SDK directly, e.g., Asherah lacks an implementation in their preferred programming language.
Asherah Server is as a light-weight service layer built atop the Asherah SDK with encrypt/decrypt functionality exposed via a gRPC service. It uses a Unix domain socket for local inter-process communication and is designed to be deployed along side your application.
To integrate with the service you will need to generate client interfaces from the .proto service definition. Detailed instructions for generating client code in a number of languages can be found in the gRPC Quick Starts.
Full code for the client implementations used in the following samples, as well as the multi-container application configurations, can be found in the samples directory.
Use Docker Compose to launch a multi-container application comprised of a simple Python client and an Asherah Server sidecar.
Ensure Docker Compose is installed on your local system. For installation instructions, see Install Docker Compose.
From the samples directory run docker-compose -f docker-compose-python.yaml up
which will launch the
application defined in docker-compose-python.yaml.
[user@machine samples]$ docker-compose -f docker-compose-python.yaml up
Creating network "samples_default" with the default driver
Creating samples_sidecar_1 ... done
Creating samples_pythonapp_1 ... done
Attaching to samples_sidecar_1, samples_pythonapp_1
sidecar_1 | 2020/04/02 19:06:36 starting server
pythonapp_1 | INFO:root:starting test
pythonapp_1 | INFO:root:starting session for partitionid-1
sidecar_1 | 2020/04/02 19:06:37 handling get-session for partitionid-1
At this point the sample client begins sending encrypt and decrypt messages to the server sidecar in a loop and you will
see stream of log messages from both the client (pythonapp_1) and server (sidecar_1). Enter CTRL+c
to shutdown the
application.
Similarly, to launch the node sample application, run docker-compose -f docker-compose-node.yaml up
from the
samples directory. This will launch the application defined in
docker-compose-node.yaml.
NOTE: Docker Compose will need to build the images for both containers the first time docker-compose up
is run on
your machine. This process typically takes between 5 to 10 minutes, but build times can vary considerably from one
machine to another.
Launch the the same multi-container application we used above but this time we'll use kind
to spin up a local Kubernetes cluster and kubectl
to launch the deployment.
Ensure both kind
and kubectl
are installed locally.
From the samples directory run docker build
to build the docker image for the provided Python client:
[user@machine samples]$ docker build -t sample-client clients/python
Sending build context to Docker daemon 3.375MB
Step 1/15 : FROM python:3.7-alpine as base
... snipped
Step 14/15 : ENTRYPOINT ["python", "appencryption_client.py"]
---> Running in a0958391c52e
Removing intermediate container a0958391c52e
---> 838466cf27e6
Step 15/15 : CMD ["--help"]
---> Running in e94395d01e20
Removing intermediate container e94395d01e20
---> c0a177a10252
Successfully built c0a177a10252
Successfully tagged sample-client:latest
we'll also need the server image:
[user@machine samples]$ docker build -t asherah-server ../go
Sending build context to Docker daemon 87.04kB
Step 1/19 : ARG GOVERSION=1.13
... snipped
Step 18/19 : ENTRYPOINT ["/asherah-server"]
---> Using cache
---> 2fdfbe426e0e
Step 19/19 : CMD ["--help"]
---> Using cache
---> a3bc3c0483a8
Successfully built a3bc3c0483a8
Successfully tagged asherah-server:latest
Now that we have both of the images we can run kind
to create our local Kubernetes cluster and then load the new
images into the cluster:
[user@machine samples]$ kind create cluster
...
[user@machine samples]$ kind load docker-image sample-client
...
[user@machine samples]$ kind load docker-image asherah-server
...
And now we're ready to use kubectl
launch the deployment defined in deployment.yaml:
[user@machine samples]$ kubectl --context kind-kind apply -f deployment.yaml
deployment.apps/myapp created
We can view our pod and the application logs to verify everything is in working order:
[user@machine samples]$ kubectl --context kind-kind get po
NAME READY STATUS RESTARTS AGE
myapp-77bd786698-ls42l 2/2 Running 0 70s
[user@machine samples]$ kubectl --context kind-kind logs -c myapp myapp-77bd786698-ls42l | head -n2
INFO:root:starting test
INFO:root:starting session for partitionid-1
And when finished, kind delete cluster
can be used to delete the cluster.
Launch the sample application as a Fargate task on Amazon ECS.
NOTE: This example is based on the excellent ECS tutorial found here in the AWS Developer Guide.
Ensure you have access to an AWS account and both Amazon ECS CLI and AWS CLI (version 2) are installed.
In addition, the steps that follow also assume the ecsTaskExecutionRole
already exists within your AWS account. If you
know this task execution role already exists, you're ready to get started.
Otherwise, see
this section
of the ECS tutorial for more information.
Create a repository for each image
[user@machine samples]$ aws ecr create-repository \
--repository-name asherah-samples/client-python --region us-west-2
{
"repository": {
"repositoryArn": "arn:aws:ecr:us-west-2:123456789012:repository/asherah-samples/client-python",
"registryId": "123456789012",
"repositoryName": "asherah-samples/client-python",
"repositoryUri": "123456789012.dkr.ecr.us-west-2.amazonaws.com/asherah-samples/client-python",
"createdAt": 1586467301.0,
"imageTagMutability": "MUTABLE"
}
}
[user@machine samples]$ aws ecr create-repository \
--repository-name asherah-samples/server-go --region us-west-2
{
"repository": {
"repositoryArn": "arn:aws:ecr:us-west-2:123456789012:repository/asherah-samples/server-go",
"registryId": "123456789012",
"repositoryName": "asherah-samples/server-go",
"repositoryUri": "123456789012.dkr.ecr.us-west-2.amazonaws.com/asherah-samples/server-go",
"createdAt": 1586467577.0,
"imageTagMutability": "MUTABLE"
}
}
Export env
variables containing the new names of the new repositories
[user@machine samples]$ REPO_ROOT=123456789012.dkr.ecr.us-west-2.amazonaws.com
[user@machine samples]$ export ASHERAH_SAMPLE_CLIENT_IMAGE="${REPO_ROOT}/asherah-samples/client-python"
[user@machine samples]$ export ASHERAH_SAMPLE_SERVER_IMAGE="${REPO_ROOT}/asherah-samples/server-go"
Ensure your docker client is currently authenticated to your Amazon ECR registry
[user@machine samples]$ aws ecr get-login-password --region us-west-2 |
docker login --username AWS --password-stdin $REPO_ROOT
Login Succeeded
❗ If you encounter an error running the above command, ensure version 2 of the AWS CLI is installed.
Build and push the images to ECR
[user@machine samples]$ docker build -t $ASHERAH_SAMPLE_CLIENT_IMAGE clients/python
...
[user@machine samples]$ docker build -t $ASHERAH_SAMPLE_SERVER_IMAGE ../go
...
[user@machine samples]$ docker push $ASHERAH_SAMPLE_CLIENT_IMAGE
...
[user@machine samples]$ docker push $ASHERAH_SAMPLE_SERVER_IMAGE
...
Create a new cluster using ecs-cli up
[user@machine samples]$ ecs-cli up --cluster-config ecsdemo --ecs-profile my_account
INFO[0001] Created cluster cluster=ecsdemo region=us-west-2
INFO[0003] Waiting for your cluster resources to be created...
INFO[0004] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
INFO[0065] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
VPC created: vpc-0123456789abcdef0
Subnet created: subnet-0123456789abcdef0
Subnet created: subnet-0123456789abcdef1
Cluster creation succeeded.
Modify the provided ecs-params.yaml
file by replacing the placeholder subnet and security group IDs.
NOTE: The subnet IDs were provided by the previous step and the security group ID for your cluster's VPC can be retrieved with the following
[user@machine samples]$ aws ec2 describe-security-groups \
--filters Name=vpc-id,Values=vpc-0123456789abcdef0 \
--region us-west-2 | jq -r '.SecurityGroups[0].GroupId'
sg-0123456789abcdef0
Your modified ecs-params.yaml
file should now look something this:
version: 1
task_definition:
task_execution_role: ecsTaskExecutionRole
ecs_network_mode: awsvpc
task_size:
mem_limit: 0.5GB
cpu_limit: 256
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- "subnet-0123456789abcdef0"
- "subnet-0123456789abcdef1"
security_groups:
- "sg-0123456789abcdef0"
assign_public_ip: ENABLED
Now you're ready to deploy the service. Use ecs-cli compose service up
to deploy the task to your cluster.
[user@machine samples]$ ecs-cli compose \
--file docker-compose-ecs.yaml \
--ecs-params ecs-params.yaml \
--project-name asherah-sample-app \
service up --create-log-groups --cluster-config ecsdemo --ecs-profile my_account
...
Once the task has been launched ecs-cli compose service ps
can be used to view the running containers
[user@machine samples]$ ecs-cli compose \
--file docker-compose-ecs.yaml \
--ecs-params ecs-params.yaml \
--project-name asherah-sample-app \
service ps --cluster-config ecsdemo --ecs-profile my_account
Name State Ports TaskDefinition Health
1ee1565c-82e8-4c1a-899d-f104ee009b37/sidecar RUNNING asherah-sample-app:1 UNKNOWN
1ee1565c-82e8-4c1a-899d-f104ee009b37/myapp RUNNING asherah-sample-app:1 UNKNOWN
And ecs-cli logs
can be used to view the container logs
[user@machine samples]$ ecs-cli logs \
--task-id 1ee1565c-82e8-4c1a-899d-f104ee009b37 \
--container-name myapp \
--cluster-config ecsdemo \
--ecs-profile my_account
INFO:root:received DRR
INFO:root:decrypting DRR
...
That's it! When you're ready to wrap things up, be sure to clean up the resources by deleting the service and cluster
[user@machine samples]$ ecs-cli compose \
--file docker-compose-ecs.yaml \
--ecs-params ecs-params.yaml \
--project-name asherah-sample-app \
service down --cluster-config ecsdemo --ecs-profile my_account
...
[user@machine samples]$ ecs-cli down --force --cluster-config ecsdemo --ecs-profile my_account
First you'll need to ensure the protobuf compiler and relevent gRPC packages have been installed for language you're working with. See language sections below for more.
Use the following to regenerate the gRPC service code for the Go server implementation.
Ensure you have a working Go installation and gRPC is installed.
Navigate to the server
directory and run the following:
[user@machine server]$ protoc --go_out=plugins=grpc:./go protos/appencryption.proto
Use the following to regenerate the gRPC service code for the Java server implementation.
Ensure that you have a working JAVA installation, protobuf and protocol compiler.
Navigate to the server
directory and run the following:
[user@machine server]$ mkdir -p java/target/generated-sources/protobuf/grpc-java
[user@machine server]$ mkdir -p java/target/generated-sources/protobuf/java
[user@machine server]$ protoc --java_out=java/target/generated-sources/protobuf/java protos/appencryption.proto
[user@machine server]$ protoc \
--plugin=protoc-gen-grpc-java=<dowloaded_proto_plugin> \
--grpc-java_out=java/target/generated-sources/protobuf/grpc-java \
--proto_path=protos appencryption.proto