gRPC and Envoy Application LayerTransport Security (ALTS) HelloWorld
Simple helloworld demonstrating GCP support for Application Layer Transport Security. You can read more about ALTS in that article (no sense in repeating it).
ALTS
can be thought of intrinsic platform-based security which helps ensure service->service communication uses the machine's bound identity itself.
That is, the gRPC communication will utilize and transmit an encrypted message at the application layer using keys intrinsic to the peer systems involved. This is in contrast to user-space based security (eg, auth header, mTLS with user-space certs, etc) because the system that provides the assertion of machine identity and security is provided by the platform itself.
This repo also shows a sample envoy client server using ALTS but for HTTP traffic (you could, ofcourse use gRPC just the same w/ envoy but i’ll stick with HTTP here).
For more information on ALTS configuration for Envoy, see envoy.extensions.transport_sockets.alts.v3.Alts
This article is nothing new…its just a rehash of gRPC’s ALTS helloworld
The difference in this repo is that I specifically show how to setup the VMs and actually emit the service account information from the peers (which is important to see).
Setup
You can find the source here in this repo
Build Client/Server
go build -o bin/client client/client.go
go build -o bin/server server/server.go
Create Service accounts/VM
gcloud iam service-accounts create alts-server --display-name "ALTS Server Service Account"gcloud iam service-accounts create alts-client --display-name "ALTS Client Service Account"export PROJECT_ID=`gcloud config get-value core/project`export CLIENT_SERVICE_ACCOUNT=alts-client@$PROJECT_ID.iam.gserviceaccount.comexport SERVER_SERVICE_ACCOUNT=alts-server@$PROJECT_ID.iam.gserviceaccount.com$ gcloud compute instances create alts-server \
--service-account=$SERVER_SERVICE_ACCOUNT \
--scopes=https://www.googleapis.com/auth/userinfo.email \
--image=debian-10-buster-v20200521 --zone us-central1-a --image-project=debian-cloud $ gcloud compute instances create alts-client \
--service-account=$CLIENT_SERVICE_ACCOUNT \
--scopes=https://www.googleapis.com/auth/userinfo.email \
--image=debian-10-buster-v20200521 --zone us-central1-a --image-project=debian-cloud
Copy binaries
$ gcloud compute scp bin/client alts-client:
$ gcloud compute scp bin/server alts-server:
Run Server
$ gcloud compute scp alts-server$ ./server 2020/06/08 21:58:11 AuthInfo PeerServiceAccount: alts-client@mineral-minutia-820.iam.gserviceaccount.com2020/06/08 21:58:11 AuthInfo LocalServiceAccount: alts-server@mineral-minutia-820.iam.gserviceaccount.com
Run Client
Replace the value for your SERVER_SERVICE_ACCOUNT
below
$ gcloud compute scp alts-client$ ./client --addr alts-server:50051 --targetServiceAccount $SERVER_SERVICE_ACCOUNT2020/06/08 21:58:11 AuthInfo PeerServiceAccount: alts-server@mineral-minutia-820.iam.gserviceaccount.com2020/06/08 21:58:11 AuthInfo LocalServiceAccount: alts-client@mineral-minutia-820.iam.gserviceaccount.com
UnaryEcho: hello world
Output
Note that in the output we’ve identified the intrinsic service account used at each peer. The idea here is you can use this as an applicaiton-layer signal to allow or deny the inbound request. Note, the client peer info is available after the RPC
In debug mode:
Envoy
The following demonstrates envoy’s support for ALTS on GCP. This snippet does not use gRPC though you could adapt it to do that but instead just uses a plain HTTP upstream/downstream connection.
To use
Edit envoy configuration
Edit server.yaml
and client.yaml
and specify the upstream/downstream service accounts to use (peer_service_accounts
). Remember which is the peer for which end
Install Envoy on Client/Server
You can either run envoy within docker or (as i prefer), a direct binary. You can get the envoy binary by “extracting” it from the docker image
On your laptop:
$ docker cp `docker create envoyproxy/envoy:v1.13.1`:/usr/local/bin/envoy .
Copy Configuration files to client and server
Copy server.yaml
to alts-server
and client-yaml
to alts-client
Run Envoy on Client/server
On alts-server
:
./envoy -c server.yaml -l debug
On alts-client
:
./envoy -c client.yaml -l debug
Access Endpoint from client
Open up a new shell on alts-client
and run
curl -v http://localhost:18080
You should see the headers sent back to you from httpbin via two hops through envoy:
> GET /get HTTP/1.1
> Host: localhost:18080
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Tue, 09 Jun 2020 12:59:52 GMT
< content-type: application/json
< content-length: 337
< server: envoy
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 72
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Host": "www.httpbin.org",
"User-Agent": "curl/7.64.0",
"X-Amzn-Trace-Id": "Root=1-5edf87c8-442f573c7a743fdf4419cc1d",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000"
},
"origin": "34.70.140.15",
"url": "http://www.httpbin.org/get"
}
Debug logs
This is the important bit, in envoy look for the log lines on the client and server that showed ALTS
:
- Client
[2020-06-09 12:59:52.818][3782][debug][connection] [source/extensions/transport_sockets/alts/tsi_socket.cc:103] [C1] certificate_type: ALTS[2020-06-09 12:59:52.818][3782][debug][connection] [source/extensions/transport_sockets/alts/tsi_socket.cc:103] [C1] service_accont: alts-server@mineral-minutia-820.iam.gserviceaccount.com
- Server
[2020-06-09 12:59:52.819][2245][debug][connection] [source/extensions/transport_sockets/alts/tsi_socket.cc:103] [C0] certificate_type: ALTS[2020-06-09 12:59:52.819][2245][debug][connection] [source/extensions/transport_sockets/alts/tsi_socket.cc:103] [C0] service_accont: alts-client@mineral-minutia-820.iam.gserviceaccount.com
The full trace of from the Client
On the envoy server
Thats it..you can use ALTS to control precisely which systems on GCP talk to each other…there’s no faking the credentials each end uses: its part of the infrastructure itself!!!