// Copyright 2020 Prysmatic Labs. // // 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 ethereum.eth.service; import "google/api/annotations.proto"; import "google/protobuf/descriptor.proto"; import "google/protobuf/empty.proto"; option csharp_namespace = "Ethereum.Eth.Service"; option go_package = "github.com/prysmaticlabs/prysm/proto/eth/service"; option java_multiple_files = true; option java_outer_classname = "KeyManagementServiceProto"; option java_package = "org.ethereum.eth.service"; option php_namespace = "Ethereum\\Eth\\Service"; // Validator Key Management Standard API // // The validator key management API is a set of endpoints to be used for keystore management in the validator client. // // This service is defined in the upstream Ethereum consensus APIs repository (beacon-apis/apis/keystores). service KeyManagement { // ListKeystores for all keystores known to and decrypted by the keymanager. // // HTTP response status codes: // - 200: Successful response // - 401: Unauthorized // - 403: Forbidden from accessing the resource // - 500: Validator internal error rpc ListKeystores(google.protobuf.Empty) returns (ListKeystoresResponse) { option (google.api.http) = { get: "/internal/eth/v1/keystores" }; } // ImportKeystores generated by the Eth2.0 deposit CLI tooling. // Users SHOULD send slashing_protection data associated with the imported // pubkeys. MUST follow the format defined in EIP-3076: Slashing Protection Interchange Format. // // HTTP response status codes: // - 200: Successful response // - 401: Unauthorized // - 403: Forbidden from accessing the resource // - 500: Validator internal error rpc ImportKeystores(ImportKeystoresRequest) returns (ImportKeystoresResponse) { option (google.api.http) = { post: "/internal/eth/v1/keystores", body: "*" }; } // DeleteKeystores must delete all keystores from `request.pubkeys` that are known to the keymanager and exist // in its persistent storage. Additionally, DELETE must fetch the slashing protection data for the requested keys from // persistent storage, which must be retained (and not deleted) after the response has been sent. Therefore in the // case of two identical delete requests being made, both will have access to slashing protection data. // In a single atomic sequential operation the keymanager must: // // 1. Guarantee that key(s) can not produce any more signature; only then // 2. Delete key(s) and serialize its associated slashing protection data // // DELETE should never return a 404 response, even if all pubkeys from request.pubkeys have no extant keystores // nor slashing protection data. // // HTTP response status codes: // - 200: Successful response // - 401: Unauthorized // - 403: Forbidden from accessing the resource // - 500: Validator internal error rpc DeleteKeystores(DeleteKeystoresRequest) returns (DeleteKeystoresResponse) { option (google.api.http) = { delete: "/internal/eth/v1/keystores", body: "*" }; } rpc ListRemoteKeys(google.protobuf.Empty) returns (ListRemoteKeysResponse) { option (google.api.http) = { get: "/internal/eth/v1/remotekeys" }; } rpc ImportRemoteKeys(ImportRemoteKeysRequest) returns (ImportRemoteKeysResponse) { option (google.api.http) = { post: "/internal/eth/v1/remotekeys", body: "*" }; } rpc DeleteRemoteKeys(DeleteRemoteKeysRequest) returns (DeleteRemoteKeysResponse) { option (google.api.http) = { delete: "/internal/eth/v1/remotekeys", body: "*" }; } } message ListKeystoresResponse { message Keystore { bytes validating_pubkey = 1; string derivation_path = 2; } repeated Keystore data = 1; } message ImportKeystoresRequest { repeated string keystores = 1; repeated string passwords = 2; string slashing_protection = 3; } message ImportKeystoresResponse { repeated ImportedKeystoreStatus data = 1; } message DeleteKeystoresRequest { repeated bytes pubkeys = 1; } message DeleteKeystoresResponse { repeated DeletedKeystoreStatus data = 1; string slashing_protection = 2; } message ImportedKeystoreStatus { enum Status { IMPORTED = 0; DUPLICATE = 1; ERROR = 2; } Status status = 1; string message = 2; } message DeletedKeystoreStatus { enum Status { DELETED = 0; NOT_FOUND = 1; NOT_ACTIVE = 2; ERROR = 3; } Status status = 1; string message = 2; } message ListRemoteKeysResponse { message Keystore { bytes pubkey = 1; string url = 2; bool readonly = 3; } repeated Keystore data = 1; } message ImportRemoteKeysRequest { message Keystore { bytes pubkey = 1; string url = 2; } repeated Keystore remote_keys = 1; } message ImportRemoteKeysResponse { repeated ImportedRemoteKeysStatus data = 1; } message DeleteRemoteKeysRequest { repeated bytes pubkeys = 1; } message DeleteRemoteKeysResponse { repeated DeletedRemoteKeysStatus data = 1; } message ImportedRemoteKeysStatus { enum Status { UNKNOWN = 0; IMPORTED = 1; DUPLICATE = 2; ERROR = 3; } Status status = 1; string message = 2; } message DeletedRemoteKeysStatus { enum Status { NOT_FOUND = 0; DELETED = 1; ERROR = 3; // skips 2 to match Delete KeyStore status which has error = 3. } Status status = 1; string message = 2; }