syntax = "proto3"; service Doughnut { // Ask for a brand new block Block, representing an ImmutableBlock // // For now, this can only create CHBs (Content Hash Blocks), a content- // addressed type of Block whose address is computed by applying an hashing // function to their content and owner address. The resulting Block is forged // according to the given MakeImmutableBlockRequest (N.B. The Block is not // pushed yet on the key-value store) rpc MakeImmutableBlock(MakeImmutableBlockRequest) returns (Block) {} // Ask for a brand new Block, representing a MutableBlock // // Create a special type of MutableBlock, named OKB (Owner Key Block). OKBs // data are encrypted by a private key, named owner. Only people having access // to this key can read, modify or delete an OKB. The address is chosen // randomly by the key-value store. Hence, the MakeMutableBlockRequest has no // attributes. The resulting Block is forged according to the given // MakeMutableBlockRequest (N.B. The Block is not pushed yet on the key-value // store) rpc MakeMutableBlock(MakeMutableBlockRequest) returns (Block) {} // Ask for a brand new Block, representing a NamedBlock // // NamedBlock are special ImmutableBlocks whose addresses are computable using // both the public key of their owner (by default, the key-value store's // public key) and their name name. The data can be assigned to the block, // before insertion, using setter of data_plain (set_data_plain). The // resulting Block is forged according to the given MakeNamedBlockRequest // (N.B. The Block is not pushed yet on the key-value store) rpc MakeNamedBlock(MakeNamedBlockRequest) returns (Block) {} // Ask for a translation between a name and an Address // // The NamedBlocks are blocks whose address can be calculated by applying an // one way function (e.g. sha256) to a tuple (owner, name) rpc NamedBlockAddress(NamedBlockAddressRequest) returns (NamedBlockAddressResponse) {} // Fetch the block at given address rpc Fetch(FetchRequest) returns (FetchResponse) {} // Insert a new Block // // The Block to insert is given by the InsertRequest. The Block should have // been created by using Make<...>Block. Insert returns an InsertResponse, // containing the information related to the Insertion rpc Insert(InsertRequest) returns (InsertResponse) {} // Update an existing block // // The address and the new content of the Block are given by the // UpdateRequest. Update doesn't perform an upsert, hence, the update will // fail if the block doesn't exist, but also you are not allowed to update it. // The UpdateResponse will contain the information related to the result of // the insertion attempt rpc Update(UpdateRequest) returns (UpdateResponse) {} // Erase the block at the given address // // The address of the Block is given by the RemoveRequest. The ability to // remove a Block is determined by two factors: The existence of the Block and // the permission to delete it. The RemoveResponse will contain the // information related to result of the deletion attempt rpc Remove(RemoveRequest) returns (RemoveResponse) {} } // Create a request for a MutableBlock // // Related: MutableBlock, MakeMutableBlock, InsertRequest. message MakeMutableBlockRequest { } // Create a request for a NamedBlock message MakeNamedBlockRequest { // The name of the NamedBlock to create bytes key = 1; } // Create a request for an ImmutableBlock // // Related: MakeImmutableBlock, InsertRequest. message MakeImmutableBlockRequest { // The payload of the ImmutableBlock bytes data = 1; // The address of the owner block // // This address is used to find the ACB in charge of the Block, to sign the // Block and control remove permissions. Until ACB are introduced to this API, // leave this field empty to base the signature on the key-value store keys bytes owner = 2; } // Create a request to retrieve the address of a NamedBlock message NamedBlockAddressRequest { // The name to retrieve address from bytes key = 1; } // Create a request to insert a Block in the key-value store // // The InsertRequest contains informations to pass to the Insert rpc. Use // Make<...>BlockRequest to create the Block to insert message InsertRequest { // The block to insert Block block = 1; } // Create a request to Update a MutableBlock // // Update an existing MutableBlock. message UpdateRequest { // The new value of the block Block block = 1; // Whether to decrypt data automatically bool decrypt_data = 2; } // Create a request to fetch a Block from the key-value store message FetchRequest { // The address of the Block to fetch bytes address = 1; // Whether to decrypt data automatically bool decrypt_data = 2; } // A response to a NamedBlockAddressRequest, containing the address of a // NamedBlock message NamedBlockAddressResponse { // The address bytes address = 1; } // A request to remove a Block message RemoveRequest { // The address of the Block to remove bytes address = 1; } // A Version, represented as a tuple of three integers message Version { // The major int64 major = 1; // The minor int64 minor = 2; // The subminor int64 subminor = 3; } // An object representing Access Control List Entry // // Readings or writings on ACB are secured by ACLEntries, containing permissions // and encrypted tokens for each users allowed message ACLEntry { // The key public to manage permissions of Key key_koh = 1; // Whether read permission is granted bool read = 2; // Whether write permission is granted bool write = 3; // Token, containing the secret to read encrypted data // // ACB data is encrypted using a secret key. Every authorized user has a // version of this secret, him and only him can decrypt bytes token = 4; } // An object representing a PublicKey message PublicKey { // The DER representation of the PublicKey (RSA) bytes rsa = 1; } message Key { string type = 1; PublicKey public_key = 2; } // A generic Block, of any kind // // A Block is generic object that can represent any kind of block message Block { // The type of Block // // The Block is generic. Block::type can be used to determine the nature of // the Block, hence, know relevant attributes. The possible values are NB, UB, // NB, OKB, GB, ACB or CHB string type = 1; // The address of the Block bytes address = 2; // The payload of the block, data or data_plain, depeding of the Block oneof payload { // The raw data of the block (N.B. This can be encrypted) bytes data = 3; // The decyphered data payload of the block // // Related: Block::decrypted. bytes data_plain = 22; } // A constant salt, used when computing the address of the block // // This attribute is specific to CHB. bytes salt = 4; // The representation of the owner public key // // This attribute is specific to NamedBlock. bytes owner = 5; // The signature of the block content. The signature proves the integrity of // the block by ensuring data have been signed using the owner private key // // This attribute is specific to NamedBlock. bytes signature = 6; // XXX MENTIONED NOWHERE bytes owner_rsa = 7; // The name of the block // // This attribute is specific to NamedBlock. bytes name = 8; // A Key object, that can be a hash, used to the find the a User Block (UB) or // the public key of the owner of the Block. Key key_koh = 9; // The version of the Block // // This represents the number of times the block has been changed int64 version = 10; // The index of the editor in the `acl` or `acl_group` to check write // permissions // // Access Control Blocks, ACBs, contains two lists of ACL entries, one for // users, one for groups. The `editor` attribute determine which ACL entry to // use // // This attribute is specific to ACB. int64 editor = 11; // A token, containing the secret used encipher the data // // This attribute is specific to ACB. bytes owner_token = 12; // The list of ACL entries (one for each user referenced in the ACB) // // This attribute is specific to ACB. repeated ACLEntry acl = 13; // The version of the data // // Each time data are changed, this version is increased by one // // This attribute is specific to ACB. int64 data_version = 14; // The signature of the data // // This attribute is specific to ACB. bytes data_signature = 15; // Whether the Block is readable by everybody // // This attribute is specific to ACB. bool world_readable = 16; // Whether the Block is writable by everybody // // This attribute is specific to ACB. bool world_writable = 17; // A list of ACL entries (one for each group reference in the ACB) // // This attribute is specific to ACB. repeated ACLEntry group_acl = 18; // XXX // // This attribute is specific to ACB. repeated int64 group_version = 19; // Wheter the Block was marked for deletion // // This attribute is specific to ACB. bool deleted = 20; // The version to determine the type of algorithm used / to use when sealing // the Block // // If the seal version is at least 0.7.0, use encrypt, less costy than seal // // This attribute is specific to MutableBlock, ACB. Version seal_version = 21; // The version of the seal to use during next sealing // // This attribute is specific to OKB. int64 next_seal_version = 23; } // The response to a FetchRequest // // Fetching a Block guarantees to return the latest version of the Block. If the // Block doesn't exist or if you don't have permission to read the content of // the Block, this will fail message FetchResponse { // // // Always empty string type = 1; // The fetched Block, at it latest version Block block = 2; } // The response to a InsertRequest message InsertResponse { // // // Always empty string type = 1; // Whether the update succeeded bool bool = 2; } // The response to an UpdateRequest // // Updating a Block is the trickiest part of the key-value store, because you // are in charge of the conflict resolutuon. In case of conflict, the // UpdateRequest::current will be set to current version of the Block. Once you // have updated the current Block, you can re-attempt to update the block message UpdateResponse { // // // Always empty string type = 1; // A message discribing the error bytes message = 2; // The current block stored at the address Block current = 3; // Whether the update succeeded bool bool = 4; } // The response to a RemoveRequest message RemoveResponse { // // // Always empty string type = 1; // Whether the update succeeded bool bool = 2; }