Using the Anjuna Nitro Attestation Endpoint
The Anjuna Nitro Runtime exposes an internal HTTP endpoint, only accessible from within an Anjuna Nitro Enclave, for generating attestation reports.
This can be used to prove that a specific application is running in a secure enclave before releasing sensitive data. For example, a key management service could verify an application’s attestation report before releasing secrets, to verify the identity of the trusted application and ensure it is running in an enclave.
It can also be used to authenticate that a trusted Anjuna Nitro Enclave produced certain data. For example, a machine learning (ML) application can embed its inference result (or a hash of the result) in an attestation report. The client can verify that attestation report to confirm that a trusted application generated the inference result.
Generating an attestation report
When an Anjuna Nitro Enclave runs,
the Anjuna Nitro Runtime exposes the attestation endpoint at http://localhost:50123/api/v1/attestation/report
.
The API accepts an HTTP GET
request with three optional base64-URL-encoded query parameters,
each limited to 1024 decoded bytes:
-
publicKey
: A public key for encrypting data to the enclave or verifying its signatures. Only the enclave can decrypt or sign using the corresponding private key. -
userData
: Custom data to sign, such as API parameters or operation results, to tie the report to its intended purpose. -
nonce
: A unique, short-lived value to prevent replay attacks and ensure communication with a live enclave. Use a secure random source to generate a new nonce for each request.
The API returns the AWS Nitro Attestation Report as a CBOR-encoded COSE-signed binary document.
Show OpenAPI specification
openapi: 3.0.3
info:
title: Anjuna Nitro Attestation
description: API for Anjuna Nitro Enclaves to generate an AWS Nitro Enclave attestation report
contact:
email: support@anjuna.io
version: 1.52.0001
servers:
- url: http://localhost:50123/api/v1
paths:
/attestation/report:
get:
summary: Generate a new Nitro Attestation Report
description: Generate an attestation report with optional publicKey, userData, and nonce fields.
operationId: generateReport
parameters:
- in: query
name: publicKey
description: User-provided public key to include in the report
schema:
type: string
format: bytes, base64-URL-encoded
maxLength: 1368 # must decode to 1024 bytes or fewer
- in: query
name: userData
description: User-provided data to include in the report
schema:
type: string
format: bytes, base64-URL-encoded
maxLength: 1368 # must decode to 1024 bytes or fewer
- in: query
name: nonce
description: User-provided cryptographic nonce to include in the report
schema:
type: string
format: bytes, base64-URL-encoded
maxLength: 1368 # must decode to 1024 bytes or fewer
responses:
'200':
description: Success
content:
'*/*':
schema:
type: string
format: binary
description: AWS Nitro Attestation Report, in CBOR-encoded COSE-signed binary document format
Your application can generate an attestation report with Golang using the Anjuna go-nitro-attestation library.
Alternatively, the HTTP endpoint can be used directly with any other programming language, or even with a command line shell such as in the following example.
Both examples below must run within an enclave:
-
Go example using the Anjuna library
-
HTTP example in the shell
// Generate an ECDSA P-384 key pair
privateKey, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
// Encode the public key to ASN.1 DER bytes
publicKeyDer, _ := x509.MarshalPKIXPublicKey(privateKey.Public())
// Define application-specific payload
data := []byte("Hello World!")
// Generate a random 16-byte nonce
nonce := make([]byte, 16)
rand.Read(nonce)
// Request attestation document (each parameter is optional)
attestDocReader, _ := attester.GetAttestationReport(publicKeyDer, data, nonce)
// Read and print raw report bytes
attestDocBytes, _ := io.ReadAll(attestDocReader)
fmt.Println(hex.EncodeToString(attestDocBytes))
# Generate an ECDSA P-384 key pair
$ openssl ecparam -name secp384r1 -genkey -noout -out private.pem
$ openssl ec -in private.pem -pubout -outform DER -out public.der
# Encode user data in Base64 URL format
$ userData=$(echo "Hello World!" | basenc -w0 --base64url)
$ publicKey=$(basenc -w0 --base64url public.der)
$ nonce=$(head -c 16 /dev/random | basenc --base64url)
# Make a request to the attestation API and save the response to a file
$ curl "http://localhost:50123/api/v1/attestation/report?userData=${userData}&publicKey=${publicKey}&nonce=${nonce}" -o report.bin
# Print the report's bytes in Base64 format
$ cat report.bin | basenc --base64
Verifying an attestation report
Any application can verify attestation reports with Golang using the Anjuna go-nitro-attestation library, even if the verifier is not running in an enclave.
This can be used to confirm trust in an application before sending it sensitive data. Or, you can use it to authenticate that an output really came from a trusted application.
// Validate the report and print user data
expectedValues := verifier.PCRMap{
0: "000000", // set expected PCR0
1: "000001", // set expected PCR1
}
_ = verifier.Validate(report, expectedValues)
fmt.Println(hex.EncodeToString(report.Document.UserData))
The README for go-nitro-attestation contains more information on verifying attestation reports.
More information
For general information on attestation for AWS Nitro Enclaves, see AWS documentation: Nitro Enclaves Attestation Process.
The Anjuna Nitro Attestation Endpoint simplifies this process. For more information and example code, see Github: anjuna-security/go-nitro-attestation.
The AWS KMS integration for AWS Nitro Enclaves requires a specific workflow
involving the UserPublicKey
field of an attestation report and unwrapping the response.
For instructions on the AWS KMS integration, see Using AWS KMS with the Anjuna Nitro Attestation Endpoint.