brew tap tink-crypto/tink-tinkey https://github.com/tink-crypto/tink-tinkey
brew install tinkey
Build the individual programs
pusd client
go build -o client *.go
popd
pushd api_server
go build -o api_server *.go
popd
pushd process_server
go build -o process_server *.go
popd
Run the api_server and process_server in separate terminals. Run the client program to see the flow from the api_server to the process_server
When running the programs you will hit the following issue https://protobuf.dev/reference/go/faq/#namespace-conflict
Run the process_server
using the following option
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./process_server
Run the api_server
using the following option
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./api_server
Run the client
using the following option
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./client
- Create an asymmetric key set with tinkey
tinkey create-keyset --key-template ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM --out private_keyset.json tinkey create-public-keyset --in private_keyset.json --out public_keyset.json
- Copy the
private_keyset.json
underprocess_server
andpublic_keyset.json
underclient
folder. Note that you should not do this for real systems. Always encrypt the private part of the key using KEK from a KMS before saving it.
- Client authenticates with API server (POST /login)
- API server returns JWT token with userid and other claims
- Client encrypts data with locally generated ephemeral DEK
- Client encrypts the DEK with a pre-created public key (
public_keyset.json
). - Client posts data to the API server for processing, including the jwt in the auth header. The data includes enckey, encdata (POST /process)
- API server verifies the jwt claims
- API server sends (userid, enckey, encdata, requestId) to process server running inside TEE. It also includes the jwt token, effectively using the jwt token for service-to-service communication.
- Process server uses the private key (
private_keyset.json
) to decrypt theenckey
and uses this key to decryptencdata
- Process server updates the plaintext data and re-encrypts it with a user-specific encryption key. The per-user encryption keys is created during start of the process server.