Fabric-ca-server’s main purpose is to act as a CA (certificate authority) that can be used to obtain X509 public cert and private key – something needed in order to write records to fabric ledger. Why? because every entry is signed by the author and provides attestation (think about paper records and statements that require a signature to prove authenticity). The public cert and private key-pair is obtained by making an
enroll call against the fabric-ca-server. But before a user can be enrolled, they need to exist in the first place. This is done by making a
register call against the fabric-ca-server (when running in non-LDAP mode) which does the same thing as when a user signs up to use a service like Facebook – a record is created in a database with their username and password.
Although fabric-ca-server can be used to register users, that is not its main purpose. LDAP is a more commonly used technology to register users. In addition to user registration, LDAP also provides user authentication; this is something fabric-ca-server does not provide and hence the motivation for running it with LDAP.
Why run Fabric-ca-server with LDAP?
Fabric-ca-server can be run without using LDAP – in fact that is the default setting as it is simple and avoids dependency. In that case it creates a sqlite3 db by default as a store of usernames and passwords. The db can be changed to mysql or postgres. However, the problem running in this mode is that the fabric-ca-server does not provide any API for user-authentication. In any practical application, there would be a web frontend through which chaincode invocations would happen. This web-frontend would require user-authentication . There are various ways to achieve the authentication:
- one could keep on using the sqlite3 db of fabric-ca-server and build an API on top of the sqlite3 db that the web app can call for authenticating users. sqlite3 by itself does not come with such an API. In fact sqlite3 db stores data in a local file. It does not provide any server. Also it has no support for multi-threading and data corruption will happen if db is accessed concurrently from multiple threads. What if we are running not one but two (or three) fabric-ca servers? Each server will need its own local copy of the db. The usual issues creep in – copies need to be in sync etc. sqlite3 db has no support for any of these.
- so at minimum it looks like one would need to replace sqlite3 db with MySql or Postgres that provides a server that both fabric-ca as well as the web app could use for authentication.
- yet another alternative is to store usernames, passwords and other user-metadata (emails, full name, etc.) in a LDAP server. This server would be used by both the web-app as well as the fabric-ca server(s) for user-authentication. One advantage of using LDAP vs. MySql or Postgres is that LDAP comes with standardized APIs for IAM.
Below are some tips to help you run fabric-ca-server with LDAP:
- Use openssl CLI to generate ID certificate(s) (single cert if using self-signed) for your fabric-ca-server and TLS certificates:
- LDAP server will need a TLS key-pair and a trusted CA file if clientauth is enabled
- fabric-ca-server will need 2 key-pairs. One when its acting as a server (when fabric-ca-client connects to it) and another one when its acting as a client (when it connects to OpenLDAP). It will also need trusted CA file if clientauth is enabled
- one key-pair will be needed for fabric-ca-client if clientauth is enabled
- it is possible to re-use the same key-pair and trusted CA file
- you have to choose an LDAP server. OpenLDAP is free. Use the dockerized version available here. It is based on alpine. we found it better than the more popular osixia/docker-openldap image.
- Fix the docker image above so that it stores hashed passwords . This is done by enabling the ppolicy overlay and setting
olcPPolicyHashCleartext: TRUE. The
olcPasswordHashsetting just controls the format in which password will be hashed. It is an important setting but it will have no effect unless password hashing is enabled in the first place which is done by setting
olcPPolicyHashCleartext: TRUE. More on password hashing 
- Follow steps here to initialize the database
- set GODEBUG=netdns=go when running fabric-ca-server to avoid SIGSEGV
- configure fabric-ca-server to use LDAP by setting
- The node sdk for Hyperledger Fabric does not support connecting to a fabric-ca-server that has clientauth enabled  (another example of many bugs with HL fabric). because of this we need to set
noclientcertotherwise bad things gonna happen. when the issue with node-sdk has been addressed (if it does), then change it to
requireandverifyclientcertwhich is the most secure setting.
- in this mode, no bootstrap user:password needs to be given to fabric-ca-server (the
- in this mode, you will never run
fabric-ca-client register. Instead users will be registered in the LDAP server using
ldapaddor ldapjs from a node app.
- if your CA server is an ICA, no parent server URL needs to be given (the
-uoption). You provide the complete chain of certificates from your CA server to the root via the
- fabric-ca-server will not be able to establish TLS connection on port 389 using starttls (the recommended way). So to use TLS we have to use port 636. 
- the fabric-ca-server-config.yaml file is needed to solve following issue
- the sqlite3 db is still needed by fabric-ca-server to store the certificates
- Use promised-ldap to communicate and interact with the openldap server from your node based web app