| // Copyright 2023 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| syntax = "proto3"; |
| |
| package fcp.confidentialcompute; |
| |
| import "google/protobuf/duration.proto"; |
| import "google/protobuf/timestamp.proto"; |
| import "proto/attestation/endorsement.proto"; |
| import "proto/attestation/evidence.proto"; |
| import "proto/micro_rpc/options.proto"; |
| |
| option java_multiple_files = true; |
| |
| // The Ledger is responsible for ensuring that access to encrypted blobs of data |
| // conforms to a data access policy, including usage limits. This service also |
| // ensures crypto erasure of the blobs by rotating the keypairs used to encrypt |
| // them. |
| // |
| // This service defines the API for Ledger's Oak enclave app. The service |
| // definition is compatible with the Oak microRPC libraries: |
| // https://github.com/project-oak/oak/tree/main/micro_rpc. |
| // |
| // To use this service: |
| // 1. Create one or more key pairs (CreateKey). |
| // 2. Encrypt a blob using the public key and associate it with a data access |
| // policy (no interaction with the Ledger). |
| // 3. Request that the Ledger service unwrap the blob's encryption key so that |
| // it can be read (AuthorizeAccess). |
| service Ledger { |
| // Creates a new public/private keypair for encrypting the symmetric keys used |
| // to encrypt blobs. |
| // |
| // The resulting keypair can be used to encrypt many blobs; access to those |
| // blobs will be independently authorized. Access to the blobs will be |
| // disallowed once the keypair expires or is deleted. |
| // method_id: 1 |
| rpc CreateKey(CreateKeyRequest) returns (CreateKeyResponse) { |
| option (.oak.micro_rpc.method_id) = 1; |
| } |
| |
| // Deletes a public/private keypair. Once deleted, any blobs encrypted with |
| // the keypair will no longer be accessible. |
| // |
| // Use RevokeAccess instead to disallow access to a specific blob. |
| // method_id: 2 |
| rpc DeleteKey(DeleteKeyRequest) returns (DeleteKeyResponse) { |
| option (.oak.micro_rpc.method_id) = 2; |
| } |
| |
| // Authorizes the caller to read an encrypted blob. If the enclave requesting |
| // access is authorized by the blob's policy and the remaining access budget, |
| // the Ledger will decrypt and return the blob's symmetric key (re-encrypted |
| // so that only the enclave can read it). |
| // |
| // For more information about blob encryption and access policies, see |
| // https://github.com/google-parfait/confidential-federated-compute/tree/main/ledger_enclave_app#readme. |
| // method_id: 3 |
| rpc AuthorizeAccess(AuthorizeAccessRequest) |
| returns (AuthorizeAccessResponse) { |
| option (.oak.micro_rpc.method_id) = 3; |
| } |
| |
| // Prevents all future access to an encrypted blob; all subsequent |
| // AuthorizeAccess requests for the blob will fail. |
| // method_id: 4 |
| rpc RevokeAccess(RevokeAccessRequest) returns (RevokeAccessResponse) { |
| option (.oak.micro_rpc.method_id) = 4; |
| } |
| } |
| |
| message CreateKeyRequest { |
| // The current time, which must be monotonically increasing. |
| google.protobuf.Timestamp now = 1; |
| |
| // The TTL of the created key. |
| google.protobuf.Duration ttl = 2; |
| } |
| |
| message CreateKeyResponse { |
| // The serialized bytes of the public key. |
| // |
| // This field holds a CBOR Web Token (CWT; RFC 8392) signed by the application |
| // key in `attestation_evidence`. The CWT and COSE key (RFC 9052) will contain |
| // at least the following claims and parameters: |
| // |
| // CWT Claims (https://www.iana.org/assignments/cwt/cwt.xhtml) |
| // -65537: COSE_Key containing the public key parameters (bstr) |
| // 4: Expiration Time (int) |
| // 6: Issued At (int) |
| // |
| // COSE Key Parameters (https://www.iana.org/assignments/cose/cose.xhtml) |
| // 1: Key Type (int) |
| // 2: Key ID (bstr) |
| // 3: Algorithm (int) |
| // |
| // Supported COSE Algorithms: |
| // -65537: HPKE-Base-X25519-SHA256-AES128GCM |
| bytes public_key = 1; |
| |
| reserved 2 to 5; |
| } |
| |
| message DeleteKeyRequest { |
| // The public key CWT of the key to delete. This should match |
| // `CreateKeyResponse.public_key`. |
| bytes public_key = 2; |
| |
| reserved 1; |
| } |
| |
| message DeleteKeyResponse {} |
| |
| message AuthorizeAccessRequest { |
| // The current time, which must be monotonically increasing. |
| google.protobuf.Timestamp now = 1; |
| |
| // The serialized fcp.confidentialcompute.AccessPolicy the blob is subject to. |
| // This must match the hash in the BlobHeader. |
| bytes access_policy = 2; |
| |
| // The serialized fcp.confidentialcompute.BlobHeader of the blob being |
| // accessed. |
| bytes blob_header = 3; |
| |
| // Encapsulated HPKE secret key used (along with one of the Ledger's private |
| // keys) to decrypt `encrypted_symmetric_key`. The encapsulated key will have |
| // been produced as part of encrypting the blob's symmetric key using HPKE. |
| bytes encapsulated_key = 4; |
| |
| // The blob's encrypted symmetric key, used to encrypt the blob data using |
| // AEAD. This symmetric key should have been encrypted using the Ledger-owned |
| // public key indicated in the blob header. The plaintext should be a COSE_Key |
| // structure (RFC 9052), but this is not enforced by this method. |
| bytes encrypted_symmetric_key = 5; |
| |
| // The public key to use to encrypt the response. |
| // |
| // This field holds a CBOR Web Token (CWT) signed by the application key in |
| // `recipient_attestation_evidence`. The CWT and COSE key (RFC 9052) will |
| // contain at least the following claims and parameters: |
| // |
| // CWT Claims (https://www.iana.org/assignments/cwt/cwt.xhtml) |
| // -65537: COSE_Key containing the public key parameters (bstr) |
| // -65538: google.protobuf.Struct containing app-specific config properties |
| // |
| // COSE Key Parameters (https://www.iana.org/assignments/cose/cose.xhtml) |
| // 1: Key Type (int) |
| // 3: Algorithm (int) |
| // |
| // Supported COSE Algorithms: |
| // -65537: HPKE-Base-X25519-SHA256-AES128GCM |
| bytes recipient_public_key = 6; |
| |
| // The attestation evidence for the application requesting access. |
| oak.attestation.v1.Evidence recipient_attestation_evidence = 9; |
| |
| // The attestation endorsements for the application requesting access. |
| oak.attestation.v1.Endorsements recipient_attestation_endorsements = 11; |
| |
| // Optional tag to disambiguate between otherwise identical accesses in the |
| // policy. This field is an orchestration-level hint, not something attested |
| // by the sealed application. |
| string recipient_tag = 8; |
| |
| // Nonce used by the recipient to ensure the same AuthorizeAccessResponse |
| // cannot be replayed multiple times by an unsealed portion of the stack to |
| // cause it to process the same data multiple times. The recipient will |
| // discard it after using it once as part of the associated data to decrypt |
| // the symmetric key. This nonce must be appended to the associated data for |
| // the symmetric key. |
| bytes recipient_nonce = 10; |
| |
| reserved 7; |
| } |
| |
| message AuthorizeAccessResponse { |
| // Encapsulated HPKE secret key for decrypting `encrypted_symmetric_key`. |
| bytes encapsulated_key = 1; |
| |
| // The symmetric key for reading the data, encrypted with HPKE using |
| // `AuthorizeAccessRequest.recipient_public_key`. The associated data for the |
| // hybrid encryption is `reencryption_public_key` + |
| // `AuthorizeAccessRequest::recipient_nonce`. |
| bytes encrypted_symmetric_key = 2; |
| |
| // If the application will be re-encrypting its output, the CWT for the public |
| // key to use. The CWT has the same required claims and parameters as |
| // `CreateKeyResponse.public_key`. Reusing the same public key as the input |
| // ensures that derived objects have the same expiration time as the original |
| // data. This key can be ignored if the application doesn't encrypt its |
| // outputs (e.g., because it produces anonymized aggregate results). |
| bytes reencryption_public_key = 3; |
| } |
| |
| message RevokeAccessRequest { |
| // The COSE "kid" property (RFC 9052) of the key used to encrypt the blob. |
| bytes key_id = 3; |
| |
| // The id of the blob, matching the id in its header. |
| bytes blob_id = 2; |
| |
| reserved 1; |
| } |
| |
| message RevokeAccessResponse {} |
| |
| // LedgerRequest and LedgerResponse combine individual request and response |
| // messages above, and used by the replicated implementation of the Ledger. |
| message LedgerRequest { |
| oneof request { |
| // Creates a new public/private keypair for encrypting the symmetric keys |
| // used to encrypt blobs. |
| CreateKeyRequest create_key = 1; |
| // Deletes a public/private keypair. Once deleted, any blobs encrypted with |
| // the keypair will no longer be accessible. |
| DeleteKeyRequest delete_key = 2; |
| // Authorizes the caller to read an encrypted blob. If the enclave |
| // requesting access is authorized by the blob's policy and the remaining |
| // access budget, the Ledger will decrypt and return the blob's symmetric |
| // key (re-encrypted so that only the enclave can read it). |
| AuthorizeAccessRequest authorize_access = 3; |
| // Prevents all future access to an encrypted blob; all subsequent |
| // AuthorizeAccess requests for the blob will fail. |
| RevokeAccessRequest revoke_access = 4; |
| } |
| } |
| |
| message LedgerResponse { |
| // Error status similar to google.rpc.Status. |
| message Status { |
| int32 code = 1; |
| string message = 2; |
| } |
| |
| oneof response { |
| // Response for CreateKeyRequest. |
| CreateKeyResponse create_key = 1; |
| // Response for DeleteKeyRequest. |
| DeleteKeyResponse delete_key = 2; |
| // Response for AuthorizeAccessRequest. |
| AuthorizeAccessResponse authorize_access = 3; |
| // Response for RevokeAccessRequest. |
| RevokeAccessResponse revoke_access = 4; |
| // Error response for all requests. |
| Status error = 5; |
| } |
| } |
| |
| // Ledger configuration - used to configure replicated Ledger job. |
| message LedgerConfig {} |