github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/docs/tech/attributes.md (about)

     1  # Attributes support
     2  
     3  To support attributes the user has to pass them during TCert creation, these attributes can be used  during transaction deployment, execution or query for Attribute Based Access Control (ABAC) to determine whether the user can or cannot execute a specific chaincode  or used attributes' values for other purposes. A mechanism to validate the ownership of attributes is required in order to prove if the attributes passed by the user are correct. The Attribute Certificate Authority (ACA) has the responsibility of validate attributes and to return an Attribute Certificate (ACert) with the valid attribute values.
     4  Attributes values are encrypted using the keys defined below (section Attributes keys).
     5  
     6  ## Attribute Keys
     7  
     8  The attributes are encrypted using a key derived from a hierarchy called PreKey tree. This approach consists in deriving keys from a parent key, allowing the parent key owner, get access to derived keys. This way keys used to encrypt attributes are different among attributes and TCerts avoiding linkability while allowing an authorized auditor who owns a parent key to derive the keys in the lower levels.
     9  
    10  
    11  ### Example of prekey tree
    12  
    13      Pre3K_BI
    14              |_Pre2K_B = HMAC(Pre3K_BI, “banks”)
    15              |   |_Pre1K_BankA = HMAC(Pre2K_B, “Bank A”)
    16              |   |   |_Pre0K_BankA = HMAC(Pre1K_BankA, TCertID)
    17              |   |       |_PositionKey_BankA_TIdx = HMAC(Pre0K_BankA, "position")
    18              |   |       |_CompanyKey_BankA_TIdx = HMAC(Pre0K_BankA, "company")
    19              |   |
    20              |   |_Pre1K_BankB = HMAC(Pre2K_B, “BanKB”)
    21              |       |_Pre0K_BankB = HMAC(Pre1K_BankB, TCertID)
    22              |            |_PositionKey_BankB_TIdx = HMAC(Pre0K_BankB, "position")
    23              |            |_CompanyKey_BankB_TIdx = HMAC(Pre0K_BankB, "company")
    24              |
    25              |_Pre2K_I = HMAC(Pre3K_BI, "institutions")
    26                  |_Pre1K_InstitutionA= HMAC(Pre2K_I, "Institution A”)
    27                     |_Pre0K_InstitutionA = HMAC(_Pre1K_InstitutionA, TCertID)
    28                          |_PositionKey_InstA_TIdx = HMAC(Pre0K_InstitutionA, "position")
    29                          |_CompanyKey_InstA_TIdx = HMAC(Pre0K_InstitutionA, "company")
    30  
    31  - Pre3K_BI: is available to TCA and auditors for banks and institutions.
    32  - Pre2K_B: is available to auditors for banks
    33  - Pre1K_BankA: is available to auditors for Bank A.
    34  - Pre1K_BankB: is available to auditors for Bank B.
    35  - Pre2K_I: is available to auditors for institutions.
    36  - Pre1K_InstitutionA: is available to auditors for Institution A.
    37  
    38  Each TCert has a different PreK0 (for example Pre0K_BankA) and each TCert attribute has a different attribute key (for example PositionKey_BankA_TIdx).
    39  
    40  ## Attribute Certificate Authority
    41  
    42  Attribute Certificate Authority (ACA) has the responsibility of certify the ownership of the attributes. ACA has a database to hold attributes for each user and affiliation.
    43  
    44  1. id: The id passed by the user during enrollment
    45  2. affiliation: The entity which the user is affiliated to
    46  3. attributeName: The name used to look for the attribute, e.g. 'position'
    47  4. attributeValue: The value of the attribute, e.g. 'software engineer'
    48  5. validFrom: The start of the attribute's validity period
    49  6. validTo: The end of the attribute's validity period
    50  
    51  ### gRPC ACA API
    52  
    53  1. FetchAttributes
    54  
    55  ```
    56      rpc FetchAttributes(ACAFetchAttrReq) returns (ACAFetchAttrResp);
    57  
    58      message ACAFetchAttrReq {
    59          google.protobuf.Timestamp ts = 1;
    60          Cert eCert = 2;                  // ECert of involved user.
    61          Signature signature = 3;         // Signed using the ECA private key.
    62      }
    63  
    64      message ACAFetchAttrResp {
    65          enum StatusCode {
    66              SUCCESS = 000;
    67              FAILURE = 100;
    68          }
    69          StatusCode status = 1;
    70      }
    71  ```
    72  
    73  2. RequestAttributes
    74  
    75  ```
    76      rpc RequestAttributes(ACAAttrReq) returns (ACAAttrResp);
    77  
    78      message ACAAttrReq {
    79          google.protobuf.Timestamp ts = 1;
    80          Identity id = 2;
    81          Cert eCert = 3;                                // ECert of involved user.
    82          repeated TCertAttributeHash attributes = 4;    // Pairs attribute-key, attribute-value-hash
    83          Signature signature = 5;                       // Signed using the TCA private key.
    84      }
    85  
    86      message ACAAttrResp {
    87          enum StatusCode {
    88              FULL_SUCCESSFUL     = 000;
    89              PARTIAL_SUCCESSFUL  = 001;
    90              NO_ATTRIBUTES_FOUND = 010;
    91              FAILURE	            = 100;
    92          }
    93          StatusCode status = 1;
    94          Cert cert = 2;                  // ACert with the owned attributes.
    95          Signature signature = 3;        // Signed using the ACA private key.
    96      }
    97  ```
    98  
    99  3. RefreshAttributes
   100  
   101  ```
   102      rpc RefreshAttributes(ACARefreshReq) returns (ACARefreshResp);
   103  
   104      message ACARefreshAttrReq {
   105          google.protobuf.Timestamp ts = 1;
   106          Cert eCert = 2;                              // ECert of the involved user.
   107          Signature signature = 3;                     // Signed using enrollPrivKey
   108      }
   109  
   110      message ACARefreshAttrResp {
   111          enum StatusCode {
   112              SUCCESS = 000;
   113              FAILURE = 100;
   114  	    }
   115          StatusCode status = 1;
   116      }
   117  ```
   118  
   119  ## FLOW
   120  
   121  ![ACA flow](../images/attributes_flow.png)
   122  
   123  ### During enrollment
   124  
   125  1. The user requests an Enrollment Certificate (ECert) to ECA
   126  2. ECA creates the ECert and responds to the user with it.
   127  3. ECA issues a fetch request under TLS to the ACA passing the newly generated ECert as a parameter. This request is signed with the ECA's private key.
   128  4. The request triggers ACA asynchronous mechanism that fetches attributes' values from external sources and populates the attributes database (in the current implementation attributes are loaded from an internal configuration file).
   129  
   130  ### During TCert generation
   131  
   132  1. When the user needs TCerts to create a new transaction it requests a batch of TCerts to the TCA, and provides the following:
   133     * The batch size (i.e. how many TCerts the user is expecting)
   134     * Its ECert
   135     * A list of attributes (e.g. Company, Position)
   136  2. Under TLS TCA sends a RequestAttributes() to ACA to verify if the user is in possession of those attributes. This request is signed with TCA's private key and it contains:
   137     * User's ECert
   138     * A list of attribute names "company, position, ..."
   139  3. The ACA performs a query to the internal attributes database and there are three possible scenarios***:
   140       a. The user does not have any of the specified attributes – An error is returned.
   141       b. The user has all the specified attributes – An X.509 certificate (ACert) with all the specified attributes and the ECert public key is returned.
   142       c. The user has a subset of the requested attributes – An X.509 certificate (ACert) with just the subset of the specified attributes and the ECert public key is returned.
   143  3. The TCA checks the validity period of the ACert's attributes and updates the list by eliminating those that are expired. Then for scenarios b and c from the previous item it checks how many (and which ones) of the attributes the user will actually receive inside each TCert. This information needs to be returned to the user in order to decide whether the TCerts are useful or if further actions needs to be performed (i.e. issue a RefreshAttributes command and request a new batch, throw an error or make use of the TCerts as they are).
   144  4. The TCA could have other criteria to update the valid list of attributes.
   145  5. The TCA creates the batch of TCerts. Each TCert contains the valid attributes encrypted with keys derived from the Prekey tree (each key is unique per attribute, per TCert and per user).
   146  6. The TCA returns the batch of TCerts to the user along with a root key (Prek0) from which each attribute encryption key was derived. There is a Prek0 per TCert. All the TCerts in the batch have the same attributes and the validity period of the TCerts is the same for the entire batch.
   147  
   148  *** _In the current implementation an attributes refresh is executed automatically before this step, but once the refresh service is implemented the user will have the responsibility of keeping his/her attributes updated by invoking this method._
   149  
   150  ### Assumptions
   151  
   152  1. An Attribute Certificate Authority (ACA) has been incorporated to the Membership Services internally to provide a trusted source for attribute values.
   153  2. In the current implementation attributes are loaded from a configuration file (membersrvc.yml).
   154  3. Refresh attributes service is not implemented yet, instead, attributes are refreshed in each RequestAttribute invocation.