We have successfully made an attested function call with the Blocky AS CLI and received the function's purported output. Before we trust that output, however, we should first verify that:
- it was our function that was executed and
- it was executed by a Blocky AS server and
- that server was running in a TEE
Let's start by looking at the entirety of the output returned by
bky-as attest-fn-call:which outputsjq -r '.' out.json{ "enclave_attested_application_public_key": { "enclave_attestation": "eyJwbGF0Zm9ybSI6InBsYWluIiwicGxhdGZvcm1fYXR0ZXN0YXRpb25zIjpbImV5SmtZWFJoSWpvaVpYbEthbVJZU2pKYVZqa3daVmhDYkVscWIybGpSRWt4VG0xemVFbHBkMmxhUjBZd1dWTkpOa2xyU1QwaUxDSnRaV0Z6ZFhKbGJXVnVkQ0k2ZXlKd2JHRjBabTl5YlNJNkluQnNZV2x1SWl3aVkyOWtaU0k2SW5Cc1lXbHVJbjE5IiwiZXlKa1lYUmhJam9pVkRKMFNXTnJTa05MTVdnMlVtNUpORlpGVWxaVWVscFBaVmQwVldKWVNYbFRWazV6V1RGR2NWcEVTVDBpTENKdFpXRnpkWEpsYldWdWRDSTZleUp3YkdGMFptOXliU0k2SW5Cc1lXbHVJaXdpWTI5a1pTSTZJbkJzWVdsdUluMTkiLCJleUprWVhSaElqb2lWVlZhTlUwd1RtcGFNRm8xVTBWa2VsRlZlR3RWU0U1UFZERldURkp0VWpaV1ZYQjRWMjVhYWs1cmJ6MGlMQ0p0WldGemRYSmxiV1Z1ZENJNmV5SndiR0YwWm05eWJTSTZJbkJzWVdsdUlpd2lZMjlrWlNJNkluQnNZV2x1SW4xOSIsImV5SmtZWFJoSWpvaVRIbDBiVlJYTVZOT01IUjJVMGR3U0dReVpIRlVWR2hNVFd0c1ZVNUVNR2xtVVQwOUlpd2liV1ZoYzNWeVpXMWxiblFpT25zaWNHeGhkR1p2Y20waU9pSndiR0ZwYmlJc0ltTnZaR1VpT2lKd2JHRnBiaUo5ZlE9PSIsImV5SmtZWFJoSWpvaVdtZzBkRzFGSzNZelVuWklhRlJ1UkhKRlFYVjZXRUZ3VFZwNksxRmpSekJyTVdVNFkzRk1iamRxTUQwaUxDSnRaV0Z6ZFhKbGJXVnVkQ0k2ZXlKd2JHRjBabTl5YlNJNkluQnNZV2x1SWl3aVkyOWtaU0k2SW5Cc1lXbHVJbjE5Il19", "claims": { "enclave_measurement": { "platform": "plain", "code": "plain" }, "public_key": { "curve_type": "p256k1", "data": "BOkHrBB+XzFr8TDUO6NykTmr2ISlcQjd2QFy3CcgFyHGsALdPsNOUKFdzUJqZvc6J/+fMmR7KoHjGwgjM8K2IT4=" } } }, "transitive_attested_function_call": { "transitive_attestation": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA5ZjY0NGU5ODE1ZmQ5NGI0NGEwMzc2NzE4NTYzMzUzMzc2Yjk5ZmVhZmQ4ZmFmZThiYTFmNTllNzQ2ZTA3M2VhMTYzODhhZmI5YmU2MzM1NjYxNThkYzYyYmM0NzJhYjhlYWEzOWU0NGQ0ZTA3MDI3OTdiZTM0YmMwNGY2MWZlYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKaGVsbG9Xb3JsZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgGE2OWY3M2NjYTIzYTlhYzVjOGI1NjdkYzE4NWE3NTZlOTdjOTgyMTY0ZmUyNTg1OWUwZDFkY2MxNDc1YzgwYTYxNWIyMTIzYWYxZjVmOTRjMTFlM2U5NDAyYzNhYzU1OGY1MDAxOTlkOTViNmQzZTMwMTc1ODU4NjI4MWRjZDI2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1IZWxsbywgV29ybGQhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAYTY5ZjczY2NhMjNhOWFjNWM4YjU2N2RjMTg1YTc1NmU5N2M5ODIxNjRmZTI1ODU5ZTBkMWRjYzE0NzVjODBhNjE1YjIxMjNhZjFmNWY5NGMxMWUzZTk0MDJjM2FjNTU4ZjUwMDE5OWQ5NWI2ZDNlMzAxNzU4NTg2MjgxZGNkMjYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQftR9RME7XGzVjvn52lyuZ0r85PHw4bvN5zc+UW9arS8T6PZRnlZYsJtGIBuD+UVK367JR92KBZzY5mSlpzm0esBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", "claims": { "hash_of_code": "9f644e9815fd94b44a0376718563353376b99feafd8fafe8ba1f59e746e073ea16388afb9be633566158dc62bc472ab8eaa39e44d4e0702797be34bc04f61fec", "function": "helloWorld", "hash_of_input": "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", "output": "SGVsbG8sIFdvcmxkIQ==", "hash_of_secrets": "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26" } } }The JSON output consists of two main entities: an enclave attestation containing the Blocky AS server's public key and a transitive attestation containing our function's inputs and outputs. The enclave attestation is used to verify the TEE platform and Blocky AS server code, whereas the transitive attestation is used to verify our function call.
To verify the attestations, we need to provide
bky-aswith the expected TEE platform and Blocky AS server code measurement. This information is passed in via theconfig.toml:which outputscat config.toml# a set of acceptable server enclave measurements for CLI to interact with acceptable_measurements = [ # a measurement that is valid for when the server is running on a non-TEE environment { platform = "plain", code = "plain" }, ] # token authorizing CLI's access to the server auth_token = "BLOCKY AS API TOKEN" # the server that the CLI interacts with. # `local-server` is a special host value that will start a local attestation # service server for testing and development. To interact with a production # server, replace `local-server` with the appropriate server endpoint. host = "local-server"The TEE platform and code measures here are "plain" because our example is configured to start and run a local non-TEE development server. In production, however, you would specify a real Blocky AS server endpoint, code measure, and TEE Platform (which we cover in Get a Developer API Key).
Extract the enclave and transitive attestations from the output and pass them to
bky-as verify-fn-call, where it will use the values in our config to validate the attestations.jq '{ enclave_attested_application_public_key: .enclave_attested_application_public_key.enclave_attestation, transitive_attested_function_call: .transitive_attested_function_call.transitive_attestation }' out.json | bky-as verify-fn-call > verified.jsonIf both attestations are authentic and correct,
bky-as verify-fn-callwill output the now verified function claims.which outputsjq -r '.transitive_attested_function_call.claims' verified.json{ "hash_of_code": "9f644e9815fd94b44a0376718563353376b99feafd8fafe8ba1f59e746e073ea16388afb9be633566158dc62bc472ab8eaa39e44d4e0702797be34bc04f61fec", "function": "helloWorld", "hash_of_input": "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", "output": "SGVsbG8sIFdvcmxkIQ==", "hash_of_secrets": "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26" }The
bky-as verify-fn-callonly verifies that the enclave and transitive attestations were made by a Blocky AS server running within a TEE. It is your responsibility to use those transitively attested claims to verify that thehash_of_code,hash_of_input, andhash_of_secretsmatch your function code and call arguments.which outputsopenssl dgst -sha3-512 ./main.wasm echo -n "" | openssl dgst -sha3-512SHA3-512(./main.wasm)= 9f644e9815fd94b44a0376718563353376b99feafd8fafe8ba1f59e746e073ea16388afb9be633566158dc62bc472ab8eaa39e44d4e0702797be34bc04f61fec SHA3-512(stdin)= a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26Since we did not pass any input or secrets to our function, an empty value is used when calculating
hash_of_inputandhash_of_secrets.
If you would like to learn more about TEEs and the attestation and verification process, check out Trusted Execution Environments in our Concepts section. Otherwise, continue on to the next section where we show you how to get a free developer API key so that you can run your functions on real Blocky AS servers and TEEs.