Identity Manager Service

Purpose

The Identity Manager Service acts as the gatekeeper to the network. It is formed of two components:

  • Issuance: Responsible for issuing certificates to new nodes wanting to join the network.
  • Revocation: (Optional) Responsible for handling certificate revocation requests as well as hosting the CRLendpoints that are used by participants to check a certificate’s revocation status.

Running The Identity Manager Service

Once the Identity Manager has been configured, it can be run via the command:

java -jar identity-manager-<VERSION>.jar --config-file <CONFIG_FILE>

Optional parameter:

--working-dir=<DIR>

This will set the working directory to the specified folder. The service will look for files in that folder. This means certificates, config files etc. should be under the working directory. If not specified it will default to the current working directory (the directory from which the service has been started).

On success you should see a message similar to:

Network management web services started on localhost:1300 with [RegistrationWebService, CertificateRevocationWebService, MonitoringWebServer]

Configuration

The main elements that need to be configured for the Identity Manager are:

Address

The address parameter must be included in the top level of the configuration and represents the host and port number that the Identity Service will bind to upon startup. The host can either be the IP address or the hostname of the machine that Identity Manager is running on. For example:

address = "<SERVER_IP/SERVER_HOST>:<PORT_NUMBER>"

Database

The Identity Manager service is backed by a SQL database which it uses to store information such as Certificate Signing Requests (CSRs) and (optionally) Certificate Revocation Requests (CRRs). The connection settings must be included within the database configuration block in the config file. The main options that should be included here are:

  • driverClassName - the DB driver class name (e.g com.microsoft.sqlserver.jdbc.SQLServerDriver for Microsoft SQL Server, org.postgresql.Driver for postgres)
  • jdbcDriver - the path to the appropriate JDBC driver jar (e.g path/to/mssql-jdbc-7.2.2.jre8.jar)
  • url - the connection string for the DB
  • user - the username for the DB
  • password - the password for the DB

Database Setup

The database can either be setup prior to running the Identity Manager service or, alternatively, it can be automatically prepared on startup via the built-in migrations. To enable the running of database migrations on startup the optional runMigration parameter within the database configuration should be set to true. Additionally, if the Identity Manager service is being run using the same DB instance as an accompanying Network Map service then the Identity Manager schema name must be specified via the schema parameter within the database configuration block:

database {
    ...
    runMigration = true
    schema = identity_manager
}

Additional Properties

Additional database properties can be loaded by including an optional additionalProperties config block. In CENM 1.0 these are restricted to HikariCP configuration settings.

database {
    ...
    additionalProperties {
        connectionTimeout = 60000
        maxLifetime = 3200000
        poolName = "myPool123"
    }
}

Example

An example configuration for an Identity Manager service using a Microsoft SQL Server database, configured to run the migrations on startup is:

database {
    driverClassName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    jdbcDriver = "path/to/mssql-<EXAMPLE_JDBC_DRIVER>.jar"
    url = "jdbc:sqlserver://<EXAMPLE_CONNECTION_STRING>"
    user = "example-user"
    password = "example-password"
    schema = "identity_manager"
    runMigration = true
    additionalProperties {
        connectionTimeout = 60000
        maxLifetime = 3200000
        poolName = "myPool123"
    }
}

Embedded shell (optional)

See Shell Configuration for more information on how to configure the shell.

Issuance Workflow

The Issuance workflow is one of two components within the Identity Manager. In order for a new node to join the network, it first needs a certificate that is signed by the Identity Manager. It acquires this by submitting a Certificate Signing Request (CSR) to the Identity Manager which is handled by the Issuance workflow. The workflow determines how the CSR gets approval as well as how the desired certificate is signed.

CSR Approval Mechanism

Before a certificate can be issued to a new node, its CSR first needs to be approved. The mechanism by which approval is granted can vary from a basic automatic approval approach to a more manual, production grade approach like JIRA integration. The approval mechanism is configured by specifying the plugin class responsible for handling CSR approvals within the Issuance workflow inside the Identity Manager’s config file. The CENM currently ships with two included plugins:

  • Auto approval
  • JIRA workflow

An approval mechanism must be specified.

Auto Approval

Auto approval results in the Issuance workflow blindly approving every request it receives. This is useful for testing as it negates the need for an external approval process.

This mechanism can be enabled by referencing the auto approval workflow plugin within the config file:

workflows {
    "issuance" {
        type = ISSUANCE
        ...
        plugin {
            pluginClass = "com.r3.enmplugins.approveall.ApproveAll"
        }
    }
}
JIRA Workflow

The Identity Manager service can use JIRA to manage the certificate signing request approval work flow. This can be enabled by referencing the JIRA CSR workflow plugin within the config file along with the associated configuration parameters:

workflows {
    "issuance" {
        type = ISSUANCE
        ...
        plugin {
            pluginClass = "com.r3.enmplugins.jira.JiraCsrWorkflowPlugin"
            config {
                address = <IDENTITY_MANAGER_JIRA_HOST> # e.g. "https://identity-manager-jira-host.r3.com/"
                projectCode = <PROJECT_CODE>
                username = <USERNAME>
                password = <PASSWORD>
            }
        }
}

See Workflow for more information.

JIRA Project Configuration

See JIRA Set-Up for more information about how to configure a JIRA project for CSR approval.

CSR Signing Mechanism

Once a CSR signing request has been approved then a certificate can be signed and issued to the node. Similarly to the approval mechanism above, this can be achieved via one of two mechanisms:

  • Local Signing Service
  • External Signing Service
Local Signing Service

The local signing service is recommended for testing and toy environments. Given a local key store containing the relevant signing keys, it provides the functionality to automatically sign all approved CSRs on a configured schedule. No human interaction is needed and the credentials for the key stores have to be provided upfront. The service is an integrated signer that is a cut-down version of the standalone Signing Services and provides no HSM integration or ability to manually verify changes. It is strongly recommended against using this for production environments.

In order for the local signer to function, it needs to be able to access Identity Manager’s certificate and keypair which should have been previously generated (see Certificate Hierarchy Guide for more information). The local signer uses local key stores which should include the necessary signing keys along with their full certificate chains.

To enable the local signer, the top level localSigner configuration block should be added to the config file:

localSigner {
    keyStore {
        file = exampleKeyStore.jks
        password = "example-keystore-password"
    }
    keyAlias = "example-key-alias"
    keyPassword = "example-key-password" # optional - defaults to key store password
    signInterval = 15000 # signing interval in millis
}

In this example, the key store defined within the local signer should contain the Identity Manager’s key pair used for signing any CSR requests along with the full certificate chain back to the root of the network.

External Signing Service

The production grade signing mechanism is the external Signing Services. This has all the functionality of the integrated local signer as well as HSM integration and the ability for a user to interactively verify and sign incoming CSRs. It should be used in all production environments where maximum security and validation checks are required.

In order to retrieve the CSR information, the signing service will communicate with the Identity Manager via its Issuance internal server. This is the only configuration option that is needed if signing of CSRs is being done via the external signing service.

Issuance Internal Server

Similarly to the other ENM services, the Identity Manager is designed to be able to communicate between other services such as the Network Map and Signing services. Both the Issuance and, optionally, the Revocation workflows have their own internal listening server that is created on startup which can receive and respond to messages from other ENM services. For example, the Revocation workflow’s ENM listener can respond to messages from the Network Map regarding certificate statuses of current participants which the Network Map service will then use when refreshing the latest Network Map.

To configure this internal server, the configuration block enmListener should be added within the Issuance workflow’s config:

workflows {
    "issuance" {
        type = ISSUANCE
        ...
        enmListener {
            port = 10001
            reconnect = true
        }
        ...
    }
    ...
}

Restricting A Node’s Corda Version (optional)

The optional configuration versionInfoValidation can be added to the Issuance workflow configuration block to exclude nodes running an old version of Corda from successfully submitting a CSR. The configuration parameter minimumPlatformVersion represents the minimum platform version that a node has to be running to be able to submit a CSR. If this is set, then any node that attempts to submit a CSR and is running a version of Corda with a platform version less than this will be automatically rejected. This can be used to ensure that all nodes that join the network have access to certain features.

workflows {
    "issuance" {
        type = ISSUANCE
        ...
        versionInfoValidation {
            minimumPlatformVersion = 4
        }
        ...
    }
    ...
}

Revocation Workflow (optional)

The Revocation workflow is the second of the two main components in the Identity Manager service. It is an optional component that is responsible for handling incoming Certificate Revocation Requests (CRRs) to revoke a node’s certificate (acquired via a previously approved CSR) as well as hosting the Certificate Revocation Lists (CRLs) to enable the participants on the network to verify the validity of other’s certificates.

Similarly to the Issuance workflow, the Revocation workflow determines how a CRR gets approved and signed.

CRR Approval Mechanism

In order to revoke a node’s certificate and therefore be evicted from the network, a CRR needs to be approved and signed by the network operator. The method by which the CRR is approved is, similar to the Issuance workflow, configured by specifying the plugin class responsible for the handling of the CRRs within the Revocation workflow inside the Identity Manager’s config file. The CENM ships with two included plugins:

  • Auto approval
  • JIRA workflow

An approval mechanism must be specified.

Auto Approval

Auto approval results in the Revocation workflow blindly approving every request it receives. This is useful for testing as it negates the need for an external approval process.

This mechanism can be enabled by referencing the auto approval workflow plugin within the config file:

workflows {
    "revocation" {
        type = REVOCATION
        ...
        plugin {
            pluginClass = "com.r3.enmplugins.approveall.ApproveAll"
        }
    }
}
JIRA Workflow

The Issuance workflow can alternatively use JIRA to manage CRR approval. This can be enabled by referencing the JIRA CRR workflow plugin within the config file along with the associated configuration parameters:

workflows {
    "revocation" {
        type = REVOCATION
        ...
        plugin {
            pluginClass = "com.r3.enmplugins.jira.JiraCrrWorkflowPlugin"
            config {
                address = <REVOCATION_JIRA_HOST> # e.g. "https://revocation-jira-host.r3.com/"
                projectCode = <PROJECT_CODE>
                username = <USERNAME>
                password = <PASSWORD>
            }
        }
}

See Workflow for more information.

CRR Signing Mechanism

Once CRR have been approved they need to be signed by the Identity Manager. Similarly to the Issuance workflow, this can be achieved via two mechanisms:

  • Local Signing Service
  • External Signing Service
Local Signing Service

As the local signer is a top-level configuration block, it is shared amongst all configured workflows within the Identity Manager. That is, the same key used for signing approved CSRs will be used to sign approved CRRS. See the “Local Signing Service” section within the above Issuance workflow documentation to see how to configured this.

External Signing Service

Also similarly to CSR signing, the production grade signing mechanism for CRRs is the external Signing Services. This has all the functionality of the integrated local signer as well as HSM integration and the ability for a user to interactively verify and sign incoming CRRs. It should be used in all production environments where maximum security and validation checks are required.

In order to retrieve the CRR information, the signing service will communicate with the Revocation Service via its Revocation internal server. This is the only configuration option that is needed if signing of CSRs is being done via the external signing service.

Revocation Internal Server

Similarly to the Issuance workflow, the Revocation workflow is configured with an internal listening server to enable communication between other services such as the Network Map and Signing services. To configure this, the configuration block enmListener should be added within the Revocation workflow’s config:

workflows {
    "revocation" {
        type = REVOCATION
        ...
        enmListener {
            port = 10001
            reconnect = true
        }
        ...
    }
    ...
}

CRL Configuration

There are an additional two parameters that need to be specified with the revocation workflow config block:

  • crlCacheTimeout: The time (in milliseconds) for nodes to cache the CRL for

  • crlFiles: The list of CRLs for other participants within the certificate chain. This is necessary as when a node checks for revoked certificates, it needs to check all certificates within the certificate chain. This parameter can be used to include CRLs to remove the requirement for node operators to provide their own CRL infrastructure (explained below).

For example:

workflows {
    "revocation" {
        type = REVOCATION
        ...
        crlCacheTimeout = 100000
        crlFiles = ["./crl-files/root.crl", "./crl-files/subordinate.crl", "./crl-files/identity-manager.crl"]
        ...
    }
    ...
}
TLS-level (empty) CRL

The downside of enabling certificate revocation is that all issuing authorities within the same chain must provide the infrastructure by which connections can retrieve the revocation lists for their keys:

+------------------+
|       Root       | - Creates and signs a CRL to ensure we can revoke the Identity Manager certificate
+------------------+
         |
+------------------+
| Identity Manager | - *This* level is where the dynamic CRL list is provided for revoking node certificates
+------------------+   upon request
         |
+------------------+
|       Node       | - When issuing TLS certificates, node operators can opt to use the empty certificate
+------------------+   revocation list to avoid the need to provide their own CRL infrastructure.
         |
+------------------+
|        TLS       |
+------------------+

This has the effect that Node operators must also provide CRL infrastructure for the TLS certificates they issue that is signed by their own key. Should Node operators wish to circumvent this requirement they can take advantage of a convenience option whereby they can refer to a URL endpoint hosted by the network operator within their certificates which is always empty.

Given that the operator of a network is already committed to providing CRL infrastructure, they can choose to make that empty list available to node operators as a convenience.

Node Configuration

Running a Revocation service does not guarantee that revoked certificates will be checked before nodes communicate with each other. Node configuration changes may be required to enable this behaviour. For more information see the documentation for the specific release version of Corda of the node in question.

An example node configuration that enables revocation checking is:

tlsCertCrlDistPoint = "http://<IDENTITY_MANAGER_HOST>/certificate-revocation-list/empty"
tlsCertCrlIssuer = "C=US, L=New York, OU=Corda, O=R3 HoldCo LLC, CN=Corda Root CA" # the ordering of the X500 name parts is important
crlCheckSoftFail = false # strict CRL checking is enabled, meaning that the SSL connection will fail if the CRL cannot be obtained or is invalid

Example Configuration

Test Configuration

Below is an example of a testing configuration of the Identity Manager. It is configured with a Issuance and Revocation workflow, using a local signer and auto approval of CSRs and CRRs.

 address = "localhost:10000"

database {
  driverClassName = org.h2.Driver
  url = "jdbc:h2:file:./identity-manager-persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=0;AUTO_SERVER_PORT=0"
  user = "example-db-user"
  password = "example-db-password"
}

localSigner = {
  keyStore = {
   file = exampleKeyStore.jks
   password = "example-password"
  }
  keyAlias = "example-key-alias"
  signInterval = 15000
  crlDistributionUrl = "http://"${address}"/certificate-revocation-list/doorman"
}

workflows {
  "issuance" = {
    type = ISSUANCE
    updateInterval = 1000
    enmListener {
      port = 5050
      reconnect = true
    }
    plugin {
      pluginClass = "com.r3.enmplugins.approveall.ApproveAll"
    }
  },
  "revocation" = {
    type = REVOCATION
    enmListener {
      port = 5051
      reconnect = true
    }
    plugin {
      pluginClass = "com.r3.enmplugins.approveall.ApproveAll"
    }
    crlCacheTimeout = 2000
    crlFiles = ["./crl/root.crl", "./crl/subordinate.crl", "./crl-files/tls.crl"]
  }
}

shell {
  sshdPort = 10002
  user = "testuser"
  password = "example-password"
}

identity-manager-test-valid.conf

Production Configuration

Below is an example of a more production-like configuration of the Identity Manager. It is configured with a Issuance and Revocation workflow, using JIRA workflows for CSR/CRR approvals, no local signer and also using SSL for secure communication between ENM services. In this scenario, all approved requests would be signed using an external signing service (see Signing Services).

address = "localhost:10000"

database {
    driverClassName = org.h2.Driver
    url = "jdbc:h2:file:./identity-manager-persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=0;AUTO_SERVER_PORT=0"
    user = "example-db-user"
    password = "example-db-password"
}

workflows {
    "issuance" = {
        type = ISSUANCE
        updateInterval = 1000
        enmListener {
            port = 5051
            reconnect = true
            ssl {
                keyStore {
                    location = exampleSslKeyStore.jks
                    password = "password"
                }
                trustStore {
                    location = exampleSslTrustStore.jks
                    password = "trustpass"
                }
            }
        }
        plugin {
            pluginClass = "com.r3.enmplugins.jira.JiraCsrWorkflowPlugin"
            config {
                address = "https://doorman-jira-host.r3.com/"
                projectCode = "CSR"
                username = "example-jira-username"
                password = "example-jira-password"
            }
        }
    },
    "revocation" = {
        type = REVOCATION
        enmListener {
            port = 5052
            reconnect = true
            # note that this SSL configuration could use different keys to the above if desired
            ssl {
                keyStore {
                    location = exampleSslKeyStore.jks
                    password = "password"
                }
                trustStore {
                    location = exampleSslTrustStore.jks
                    password = "trustpass"
                }
            }
        }
        plugin {
            pluginClass = "com.r3.enmplugins.jira.JiraCrrWorkflowPlugin"
            config {
                address = "https://doorman-jira-host.r3.com/"
                projectCode = "CRR"
                username = "example-jira-username"
                password = "example-jira-password"
            }
        }
        crlCacheTimeout = 2000
        crlFiles = ["./crl/root.crl", "./crl/subordinate.crl", "./crl-files/tls.crl"]
    }
}

shell {
    sshdPort = 10002
    user = "testuser"
    password = "example-password"
}

identity-manager-prod-valid.conf