Uploaded image for project: 'Fabric'
  1. Fabric
  2. FAB-5346

Support Attribute-Based Access Control (ABAC) for enrollment certificates

    Details

      Description

      Some doc links:
      fabric: https://github.com/hyperledger/fabric/tree/master/core/chaincode/lib/cid (note in particular https://github.com/hyperledger/fabric/tree/master/core/chaincode/lib/cid#getting-an-attribute-value)
      fabric-ca: http://hyperledger-fabric-ca.readthedocs.io/en/latest/users-guide.html#attribute-based-access-control

      See See https://docs.google.com/document/d/1GP5tcN0oK9Zewed9h5pLiM2BowWPhtgFUGXEDKjeGGo for more information for earlier design discussions.

      ----------------------------------------------------------------------------------------------------------------------
      The goal of this feature is to support attribute-based access control (ABAC) for both chaincode and fabric.
      For fabric, see FAB-3752 for how this feature will be used by MSP to ensure that the caller has admin authority. For chaincode, the caller's attribute name and value will be accessible in order to make arbitrary authorization decisions based on user-defined attributes.

      The fabric-ca-server already allows associating arbitrary user-defined attributes with an identity. This feature will support adding attributes to an ECert as an x509 extension in the clear or encrypted. When an attribute is encrypted in an ECert, a decryption key will be returned separately to the client (i.e. not part of the ECert). It is up to the client to decide how to pass the key to fabric or chaincode. For example, it may be passed in the transient data field of a transaction so that chaincode has access to it but it is not stored on the ledger. This should be the default behavior of an SDK.

      So when an ECert is generated, the following decisions must be made:
      1) Which (if any) attributes should be added to the certificate?
      2) For each of these attributes,
      2a) what if the identity does not have the attribute? Should we error or just skip the attribute?
      2b) if the identity has an attribute, should it be encrypted or appear in the clear?

      This behavior will be controlled as follows:

      We add the following to an enrollment and reenrollment requests:

             AttributeRequests []struct{
                      Name string,
                      Require bool,  // error if the identity doesn't have the attribute
                      Encrypt bool,   // encrypt the attribute in the ecert
             }
      

      If this is specified in the enrollment/reenrollment request, then use it to make attribute decisions.

      The "fabric-ca-client register" CLI command will be enhanced to support the following:

      # fabric-ca-client register -u ... -id.attrs <attrName>=<attrValue>[:ecert]
      
      If the ":ecert" suffix is added to an attribute name and value when registered, then by default that
      attribute will be added to the ECert when issued.
      
      Examples:
      
      # fabric-ca-client register --id.name user1 --id.secret user1pw --id.type user --id.affiliation org1 -id.attrs attr1=val1:ecert
      Registers user1 with an attribute named "attr1" and value of "val1" and mark it as "ecert" so that it is included in
      the user's ECert by default.
      
      # FABRIC_CA_CLIENT_HOME=user1 fabric-ca-client enroll -u http://user1:user1pw@localhost:7054
      Enroll user1.  You can then print user1/msp/signcerts/cert.pem with openssl and see "attr1" with a value of "val1" in the certificate.
      
      

      The above describes how to generate an ECert with attributes.
      The following is the basic API for accessing the attributes in an ECert.

      // Get attributes from a certificate with secretAttrInfo for encrypted attributes which is passed separately.
      func GetAttributesFromCert(cert *x509.Certificate, secretAttrInfo string) (*Attributes, error)
      // Get a list of attribute names
      func (a *Attributes) Names() []string
      // Determine if an attribute with a specified name is found
      func (a *Attributes) Contains(attrName string) bool
      // Get the value of an attribute
      func (a *Attributes) Value(attrName string) (string, bool, error)
      

      See https://docs.google.com/document/d/1GP5tcN0oK9Zewed9h5pLiM2BowWPhtgFUGXEDKjeGGo for more information

        Attachments

          Issue Links

            Activity

              Toggl

              Enter your Toggl API token
              Mark as billable
              Apply JIRA issue labels


              {{ currentTimer.description|limitTo:35 }}...
              {{hours}} hour{{hoursS}}, {{minutes}} minute{{minutesS}}, {{seconds}} second{{secondsS}}

                People

                • Assignee:
                  harrisob@us.ibm.com Bret Harrison
                  Reporter:
                  smithbk Keith Smith
                  Watchers:
                  animesh k, Bret Harrison, chen xuan, Clarity Zhang, Cornelius Ihle, Frédéric BIDON, Keith Smith, Nik Frunza, Nitin Gaur, Saad Karim, Sadok SADDEM, Shuai Wang, Subramanian Palaniappan, Takayuki Suzuki
                • Votes:
                  5 Vote for this issue
                  Watchers:
                  14 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: