Developing an External Agent Web Service

Developing an External Agent Web Service

This article will guide you through the development of an external agent web service with express.js using a sample application as a template.

High level architecture

1320

You will be developing the external agent web service (extauthn web service). Its function is to:

  • Receive requests from the bridge agent
  • Perform operations on your organization's identity source database via its own database specific protocol
  • Respond to the bridge agent according to the API contracts

Read more about IBM Security Verify Bridge architecture.

The API contracts

Request Contract

Your external agent web service receives requests from the bridge agent. The following are details of the request contract:

HTTP AttributeRequirementDescription
METHODMandatoryPOST only
URL PathMandatory/action
Content-TypeMandatoryapplication/json
AcceptMandatoryapplication/json
AuthorizationSee descriptionRequired if On-Prem agent has been configured for Client Credentials granted Bearer token or Basic authentication
Request Payload AttributeRequirementDescription
operationMandatoryOne of password-verify, password-change
requestedAttributesOptional for password-verifyArray of strings representing the preferred set of user attributes to be returned on successful verification responses. These attributes will be made available to ISV for attribute mapping and JITP.
parametersMandatoryThe parameters which are specific to the operation
parameters/usernameMandatoryThe username or subject of the operation
parameters/passwordRequired for password-verifyThe password to be validated
parameters/oldpasswordOptional for password-changeThe users current password to be changed
parameters/newpasswordRequired for password-changeThe users new password
addressedToMandatory for get-statusLabel of the external auth service
idMandatory for get-statusOperation id

HTTP REQUEST SAMPLE

POST  https://external.mod.com/action/
content-type: application/json
accept: application/json
authorization: Basic gobledeegoop
{
    "operation": "password-verify",
    "parameters": {
      "username": "scott",
      "password": "scott11111"
    },
    "requestedAttributes": ["cn", "mobile_number", "display_name"]
}

Response Contract

AttributeRequirementDescription
operationMandatoryThe function or operation that was processed
status.resultMandatoryThe over job processing result status. Status codes are described below
status.messageOptionalMessage about the status result
parametersOptionalOptional but highly recommended object containing the parameters specific to the response operation. In the case of password-verify success response, this object should contain the users group membership and account attributes so that ISV may perform JITP.
parameters/userOptionalObject containing attributes of string arrays representing the users account attributes
parameters/user/OptionalArray of values associated with the users account attribute
parameters/groupsOptionalArray of strings representing the group names of which the user is a member
replyFromMandatory for get-statusLabel of external auth agent
idMandatory for get-statusOperation id of the get-status operation (echo'd back from request)
connectionMandatory for get-statusShould be OK for good connection on get-status request

Status codes include the following:

ValueHTTP Status CodeDescription
SUCCESS200Operation processing was successful
ERROR200Generic error or failure
USER_NOT_FOUND200User not found in target data store
USER_ACCOUNT_LOCKED200Users account is locked
INVALID_PARAMETERS200Parameter data was incorrect or missing
UNAVAILABLE200Something associated with the target system is unavailable
PASSWORD_EXPIRED200The user's password has expired and must be reset
PASSWORD_MUST_BE_CHANGED200The user's password must be changed (can occur after a password reset)
PASSWORD_CHANGE_FAILED200Unable to change the users password (generic failure)
PASSWORD_QUALITY200Unable to change the users password because it does not meet required quality (EG length)
ACCOUNT_RESTRICTION200Account is not usable at this time or place

HTTP RESPONSE SAMPLE

HTTP/1.1 200 OK
content-type: application/json
{
    "operation": "password-verify",
    "status": {
        "result": "SUCCESS"
    },
    "parameters": {
        "groups": [
            {
                "name": "developer",
                "id": "608000GTNH"
            },
            {
                "name": "admin",
                "id": "608000GTNF"
            }
        ],
        "user": {
            "cn": [
                "Scott Admin"
            ],
            "mobile_number": [
                "111-222-3333"
            ],
            "displayName": [
                "Scott"
            ]
        }
    }
}

Some operations may not generate a HTTP RESPONSE BODY, and in that case a 204 is acceptable instead of a 200 (with content-length: 0).

get-status operation

The following are examples of the request/response for the get-status operation

Request

{
    "addressedTo": "extauthn",
    "id": "0",
    "operation": "get-status"
}

Response

{
    "replyFrom": "extauthn",
    "status": {
        "result": "SUCCESS"
    },
    "id": "0",
    "operation": "get-status",
    "connection": "OK"
}

Take a look at the provided sample application to see how the API contracts can be implemented.

Authentication

Before processing the above requests, your web service should confirm the identity of the bridge agent in order to protect your web service from unauthorized use. The bridge agent will identify itself to your web service via one of the following authentication flows:

MethodDescription
Basic AuthEach request from the bridge agent sends a base64 encoded username:password in the request header to your web service. If the username:password is recognized by your web service the request can proceed.
MTLSThe bridge agent presents a client certificate to your web service. If that client certificate is recognized by your web service as being signed by a trusted CA your web service will allow the connection. MTLS can be used alone or in conjunction with Basic Auth or OAuth.
Symmetric Signed JWTBoth the bridge agent and your web service have a secret key. The bridge agent creates a JWT (JSON Web Token) and signs it with the secret key. The same secret key is then used by your web service to verify the JWT.
Asymmetric Signed JWTThe bridge agent signs a JWT (JSON Web Token) with a private key. Your web service can verify the validity of this JWT using a corresponding public key/certificate.
OAuth Client CredentialsThe bridge agent completes a client credentials OAuth flow with some OAuth Authorization server. The OAuth server presents the bridge agent with an access token. The access token is then sent as a header to your web service. This token is then sent by your web service to the OAuth authorization server's introspect endpoint. If the token is valid then the request is authorized.

The provided sample application demonstrates a working implementation of each of these authentication flows. By default the sample application uses Basic Auth. See the section on enabling authentication flows in the sample application to use the other flows.

Using the provided Sample Application

A sample, reference implementation of an external agent web service is supplied via GitHub repository. The Sample Application demonstrates how to:

  1. Implement the API contracts
  2. Authenticate with the sample application

Note: Although the the sample application is designed to handle requests from the bridge agent, you do not need to be running the bridge agent while developing/testing the sample application. Instead you can make use of the provided CURL scripts to simulate the requests from the bridge agent. See using the sample application as an ISV identity source when you are ready to test against a live ISV instance.

Download and run the sample application

To download and run the sample application, clone the repository:

git clone [email protected]:IBM-Security/Verify-Bridge-Authentication-Sample-App.git

This will create a directory called Verify-Bridge-Authentication-Sample-App/. The directory contains two subdirectories:

  1. sample-application/ - housing the sample application
  2. tests/ - housing the CURL tests

Change directory into the sample-application/ directory and run npm install to install the requisite packages.

cd Verify-Bridge-Authentication-Sample-App/sample-application
npm install

Before you run your server you should set the environment variables and generate the required TLS certificates covered in the following sections.

Configuring the web service (environment variables)

The root of the sample-application directory contains a file called .env_example. Rename it to .env

# Web Server variables
PORT=8555
LOGGER_PREFIX='Extauthn Web Service'

# Authorization specific variables...
SettingMeaning
PORTThe port on which your https server will run
LOGGER_PREFIXThe prefix that appears before lines logged to the terminal

You can leave the authentication specific variables on their defaults for now. See the section on authentication to learn more.

Generating the TLS certificates

The bridge agent will communicate with your external agent web service via https. You will need to generate the following certificates and their private keys:

CertificateDefault namePurpose
Root CAextauthn.caroot.crtThis is the root CA certificate whose private key is used to sign the other certificates. It allows the bridge agent and your web service to know which certificates to trust. This certificate should be provided to the bridge agent during the ISV identity agent setup and to your web service when using MTLS.
Server Certificateextauthn.agent.crtThis certificate is signed by the root ca's private key (extauthn.caroot.key) and is presented BY your web service TO the bridge agent during the TLS handshake.
Client Certificateextauthn.client.crtThis certificate is used during MTLS, is signed by the root CA's private key (extauthn.caroot.key) and is presented BY the bridge agent TO your web service during the TLS handshake as a means of authenticating the bridge agent.

Before generating the certificates for the example application rename the certs/.env_example file to .env. Open the file, you should see something like the following:

# TLS generation variables
BRIDGE_AGENT_IP=
BRIDGE_AGENT_DNS=

WEB_SERVER_IP=
WEB_SERVER_DNS=

COUNTRY='AU'
STATE='Queensland'
LOCATION='Gold Coast'
ORGANIZATION='My Company'

By default running the certs.sh script will generate certificates that work only on the local machine (127.0.0.1). This is fine if you intend on running both the bridge agent and web service on the local machine. However if you plan on running the bridge agent (or the CURL tests simulating it) and web service on different machines you should set the values for the BRIDGE_AGENT_IP and WEB_SERVER_IP to the IP addresses of these machines. Or if you know their hostnames, set those accordingly.

BRIDGE_AGENT_IP='172.16.236.128'
BRIDGE_AGENT_DNS=bridge_agent.myhost

WEB_SERVER_IP='172.16.236.1'
WEB_SERVER_DNS=extauthn_webserver.myhost

Generate the required TLS certificates by running the cert.sh script in the certs/ directory.

Run

chmod +x certs.sh
./certs.sh

Your certs/ directory should now contain the following files:

drwxr-xr-x user group 768 B  Thu Oct 13 21:50:57 2022 .
drwxr-xr-x user group 416 B  Thu Oct 13 18:56:08 2022 ..
.rw-r--r-- user group 223 B  Thu Oct 13 21:41:51 2022 .env
.rw-r--r-- user group  41 B  Thu Oct 13 21:28:15 2022 .gitignore
.rw-r--r-- user group 180 B  Thu Oct 13 21:50:57 2022 cert.extauthn.agent.conf
.rw-r--r-- user group 261 B  Thu Oct 13 21:50:57 2022 cert.extauthn.client.conf
.rwxr-xr-x user group 3.8 KB Thu Oct 13 21:41:00 2022 certs.sh
.rwxr-xr-x user group 130 B  Thu Oct 13 19:33:59 2022 cleanup.sh
.rw-r--r-- user group 307 B  Thu Oct 13 21:50:56 2022 csr.extauthn.agent.conf
.rw-r--r-- user group 310 B  Thu Oct 13 21:50:57 2022 csr.extauthn.client.conf
.rw-r--r-- user group 1.3 KB Thu Oct 13 21:50:57 2022 extauthn.agent.crt
.rw-r--r-- user group 1.0 KB Thu Oct 13 21:50:56 2022 extauthn.agent.csr
.rw-r--r-- user group 1.6 KB Thu Oct 13 21:50:56 2022 extauthn.agent.key
.rw-r--r-- user group 2.5 KB Thu Oct 13 21:50:57 2022 extauthn.agent.p12
.rw-r--r-- user group 1.1 KB Thu Oct 13 21:50:56 2022 extauthn.caroot.crt
.rw-r--r-- user group 1.7 KB Thu Oct 13 21:50:56 2022 extauthn.caroot.key
.rw-r--r-- user group 1.3 KB Thu Oct 13 21:50:57 2022 extauthn.client.crt
.rw-r--r-- user group 1.0 KB Thu Oct 13 21:50:57 2022 extauthn.client.csr
.rw-r--r-- user group 1.6 KB Thu Oct 13 21:50:57 2022 extauthn.client.key
.rw-r--r-- user group 2.5 KB Thu Oct 13 21:50:57 2022 extauthn.client.p12
.rw-r--r-- user group  17 B  Thu Oct 13 21:50:57 2022 extauthn.srl
.rw-r--r-- user group 130 B  Thu Oct 13 21:50:56 2022 ssl.cfg

IMPORTANT NOTE

The certificates generated are for testing the sample application web service and shouldn't be used in your production environment. When you are ready to deploy, make sure you use your organization's own certificates or have them generated for use with the external agent web service accordingly.

Running the sample application

Ensure that you have configured the web service and created the TLS certificates then run the server by typing

npm start

If you see the following output your server is running correctly.

HTTPS Listening on port          8555

The application is running with nodemon which means any changes you make to the application will automatically restart the server.

You can test application using the provided CURL tests to ensure that the application conforms to the API contracts.

If you would like to use the sample application as an identity source for your live ISV tenant and see it working in real time you will need to:

  1. Set up your identity agent on ISV
  2. Install and run the bridge agent

Testing your web service with CURL requests

Once you have your web service running, you can test that it conforms to the API contracts by using the CURL command to manually hit the /action endpoint. To assist with this we have provided various scripts for testing each of the operations.

Open the tests/curl/ directory, you should see the following subdirectories each corresponding to a different authentication method:

  1. BasicAuth/
  2. BasicAuthOverMTLS/
  3. MTLS/

Inside of these directories are the following bash scripts:

ScriptOperation
get-status.shSend the web service a get-status operation
password-verify.shSends the web service a password-verify operation
password-change.shSends the web service password-change operation
invalid-operationSend the web service an unknown operation.sh value
unauthorized.shSends the web service a valid password-verify operation by has without the correct authorization

Before running these scripts open the tests/.env_example file and rename it to .env. Make sure you set the host and port of your web service as well as the certificate details. By default these details will work with the sample application, tweak them as appropriate.

# Path to certificates directory
CERT_PATH='../../../sample-application/certs/'
CA_CERT_NAME='extauthn.caroot.crt'

# Extauthn server info
EXTAUTHN_SERVER_HOST=localhost
EXTAUTHN_SERVER_PORT=8555

# Basic Auth info
BASIC_AUTH_USERNAME=admin
BASIC_AUTH_PASSWORD=passw0rd
INVALID_BASIC_AUTH_USERNAME=jerry
INVALID_BASIC_AUTH_PASSWORD=abcdef

# Client Cert and Key for mtls
CLIENT_CERT_NAME='extauthn.client.crt'
CLIENT_CERT_KEY='extauthn.client.key'

EXTAUTHN_SERVER_HOST and EXTAUTHN_SERVER_PORT refer to the hostname and port where your web service is running.

The CERT_PATH simply points to the location of the certs/ directory relative to the locations of the tests scripts.

Running the CURL scripts

Before running the tests make sure the appropriate authentication middleware is enabled. The default middleware is basic authentication so you would run the tests in the tests/curl/BasicAuth/ directory.

To run any of the bash tests simply run the corresponding script, for instance password-verify:

chmod +x password-verify.sh
./password-verify.sh

You'll see output that looks like the following

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 248
ETag: W/"f8-bDOG/ZHdodpQnYcCaI1Xhpf/Wgc"
Date: Mon, 10 Oct 2022 12:32:21 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"operation":"password-verify","status":{"result":"SUCCESS"},"parameters":{"groups":[{"name":"developer","id":"608000GTNH"},{"name":"admin","id":"608000GTNF"}],"user":{"cn":["Scott Admin"],"mobile_number":["111-222-3333"],"displayName":["Scott"]}}}%            

As you develop your application, tweak the contents of the bash script to produce the desired results. For instance to see the result of a request for a user not in the data source modify the password-verify.sh request to ask for a user that doesn't exist, in this example we ask for frankie

--data-raw '{
    "operation": "password-verify",
    "parameters": {
      "username": "frankie",
      "password": "scott11111"
    },
    "requestedAttributes": ["cn", "mobile_number", "displayName"]
}'

You'll see the following response

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 110
ETag: W/"6e-AX+whB1hU5sA52YZ3uvRBOccdL4"
Date: Mon, 10 Oct 2022 12:34:57 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"operation":"password-verify","status":{"result":"USER_NOT_FOUND","message":"User not found in data source"}}%               

Demonstrating correct handling of USER_NOT_FOUND as specified in the API contracts.

Using the sample application with ISV

If you would like to use the sample application as an identity source for your ISV tenant you will need to do the following:

  1. Create your identity agent on ISV
  2. Install and run the bridge agent

1. Creating your Identity Agent on ISV

To use the provided sample application as an identity source on ISV you must create an identity source on ISV. By default the sample application will use basic authentication. For other authentication types see the authentication section.

The sample application using basic authentication will require the following settings:

SettingValueExplanation
URIhttps://localhost:8555This is the location that the bridge agent will look for your running web service. If you are running the web service on the same machine use localhost otherwise set the hostname and port appropriately.
Authentication TypeBasic authenticationTells the bridge agent to authenticate with the web service using Basic Auth
UsernameadminBasic auth username
Passwordpassw0rdBasic auth Password
The certificate authorityCopy the text inside the extauthn.caroot.crt file you created when you created the tls certificatesThe CA cert certificate whose private key was used sign the other certificates. This tells tells the bridge agent to trust TLS certificates presented to it by the web service.
Private key certificate nameLeave this blank. If you would like to use MTLS in addition to Basic Auth refer to the MTLS section for setting this value
AttributesdisplayName, givenName, mobile_numberThe attributes that should be requested for JITP provisioning. Set this to displayName, givenName, mobile_number.
1364

Attributes

For attributes, enter displayName, givenName, mobile_number. This is the list of attributes that we'd like the bridge agent to request from the web service and is returned upon a successful password-verify request. These attributes and values are then made available for attribute mapping to ISV cloud directory account attributes during Just-In-Time Provisioning (JITP). See the example data source sample-application/data_source/data_source.js file to see what attributes can be requested from the sample application.

During development of an external agent web service the ISV administrator who performs this Identity Agent configuration step will need to consult with the web service developer to find out what attributes the web service has access to and can return upon a successful password-verify request.

1002

Set the attribute mappings

mobile_number->mobile_number
givenName->given_name
1834

Name your agent and identity source and hit Save and continue to create your sample application identity agent.

1000

Finally you'll be presented with the API credentials that your bridge agent will require. Download the bridge agent from the X-Force App Exchange and use the credentials supplied to during this step when installing and running the bridge agent.

1862

2. Installing and running the Bridge Agent on Windows

Download the bridge agent from the X-Force App Exchange and run the installer and following the prompts.

After installing you'll be presented with the Tenant Configuration screen pictured below

511

Enter the Client ID and Client Secret you received when creating the Identity Agent.

511

Check the box to enable tracing and take note of the Trace file name (default bridge_agent.log).

511

The bridge agent should now be running as service. If you would like to see the bridge agent's console output open powershell and type the following command, substituting in the filepath of the logfile you created while setting up the bridge agent:

Get-Content 'C:\Program Files\IBM\BridgeAgent\bridge_agent.log' -Tail 50 -Wait

The bridge agent log may be able to help you to troubleshoot and issues you have.

Restarting or Restarting the Bridge Agent

You may find that you want to stop or restart the bridge agent service. To do this on your windows machine press Win+R and type services.msc

378

In the following screen select the service named IBM Security Verify Bridge (ibm_bridge_agent) and click stop or restart to stop or restart the bridge agent.

979

Successful Authentication

Once running, the bridge agent will connect to ISV and retrieve the configuration you created while setting up the identity agent. The bridge agent will then attempt attempt to connect to one of the URIs specified for your web service in the Identity Agent configuration.

You should see the sample application log to its console something like the following:

Extauthn Web Service | HTTPS Listening on port   8555
Extauthn Web Service | 
Request headers received:
Extauthn Web Service | {"host":"172.16.236.1:8555","user-agent":"Go-http-client/1.1","transfer-encoding":"chunked","accept":"application/json","authorization":"Basic YWRtaW46cGFzc3cwcmQ=","content-type":"application/json","accept-encoding":"gzip"}
Extauthn Web Service | Attempting Basic Authentication
Extauthn Web Service | Basic Auth: {"name":"admin","pass":"passw0rd"}
Extauthn Web Service | Basic auth successful
Extauthn Web Service | Request body:
Extauthn Web Service | {"addressedTo":"extauthn","id":"0","operation":"get-status"}
Extauthn Web Service | Replied:
Extauthn Web Service | {"replyFrom":"extauthn","status":{"result":"SUCCESS"},"id":"0","operation":"get-status","connection":"OK"}

Congratulations the bridge agent is successfully authenticating with your web service using basic authentication over TLS. You can now log into your ISV tenant using the credentials in the data_source/data_source.json file.

Logging in to ISV using the sample application as the identity source

With the bridge agent successfully authenticating with the web service you should now to able to login to ISV using the credentials specified in the mock data source (data_source/data_source.json).

Select the identity source you created:

1674

Type the credentials from the data_source/data_source.json file:

username: scott
password: scott11111
882

Your sample application should output the following to its console

Request headers received:
Extauthn Web Service | {"host":"172.16.236.1:8555","user-agent":"Go-http-client/1.1","transfer-encoding":"chunked","accept":"application/json","authorization":"Basic YWRtaW46cGFzc3cwcmQ=","content-type":"application/json","accept-encoding":"gzip"}
Extauthn Web Service | Attempting Basic Authentication
Extauthn Web Service | Basic Auth: {"name":"admin","pass":"passw0rd"}
Extauthn Web Service | Basic auth successful
Extauthn Web Service | Request body:
Extauthn Web Service | {"enqueuedTime":"2022-10-14 01:52:08.192","operation":"password-verify","parameters":{"password":"scott11111","username":"scott"},"requestedAttributes":["displayName","givenName","SN"]}
Extauthn Web Service | Replied
Extauthn Web Service | {"operation":"password-verify","status":{"result":"SUCCESS"},"parameters":{"groups":[{"name":"developer","id":"608000GTNH"},{"name":"admin","id":"608000GTNF"}],"user":{"displayName":["Scott"],"givenName":["Scott"],"SN":["Admin"]}}}

You should now be successfully logged into ISV as scott.

Enabling authentication flows in the sample application

The sample application supports the following authentication methods:

  1. Basic Auth (Default)
  2. MTLS
  3. Symmetric Signed JWT
  4. Asymmetric Signed JWT
  5. OAuth

MTLS can also be used in conjunction with Basic Auth and OAuth see enabling MTLS with these flows.

Basic Authentication

Basic Authentication expects an authorization header to be sent to the web service in the format Basic username:password where username:password is base64 encoded. For example a request header for the username:password credentials of admin:passw0rd would look like the following:

"authorization":"Basic YWRtaW46cGFzc3cwcmQ="

Enabling Basic Authentication in the Sample Application

To enable basic authentication in your sample application open server.js and make make sure that the basicAuthen middleware is uncommented

// Authentication (uncomment desired)
app.use(basicAuthen);                       // Basic Auth
// app.use(mtls);                              // MTLS
// app.use(symmetricJwt);                      // Symmetric signed JWT
// app.use(asymmetricJwt);                     // Asymmetric signed JWT

Setting the .env variables for Basic Authentication

Open .env at the root of your project directory and set the expected username and password. This is the username and password your server will expect to see in the authorization header. You can leave these values as is.

# Basic Auth Variables
BASIC_AUTH_USERNAME=admin
BASIC_AUTH_PASSWORD=passw0rd

IDENTITY AGENT CONFIG FOR BASIC AUTH

In the Identity Agent UI configure you basic auth

SettingSample Application ValueExplanation
UsernameadminBasic auth username
Passwordpassw0rdBasic auth Password
The certificate authorityCopy the text inside the extauthn.caroot.crt file you created when you created the tls certificatesThe CA cert certificate whose private key was used sign the other certificates. This is how your web service knows to trust the certificate presented by your web service during the TLS hand shake
Private key certificate nameLeave this one blank for now. This can be set if you want to use MTLS in addition to Basic Auth. Refer to the MTLS section for more details
1364

MTLS Authentication

When using MTLS the bridge agent presents its client certificate to the web service. The web service checks to see if the certificate is trusted (signed by a trusted certificate authority). If the client certificate presented is trusted the web service will allow the request, otherwise the request will be denied.

Enabling MTLS in the Sample Application

To enable MTLS authentication in your sample application open server.js and make make sure that the mtls middleware is uncommented

// Authentication (uncomment desired)
// app.use(basicAuthen);                       // Basic Auth
app.use(mtls);                              // MTLS
// app.use(symmetricJwt);                      // Symmetric signed JWT
// app.use(asymmetricJwt);                     // Asymmetric signed JWT

To use MTLS make sure that your https server config includes

requestCert: true,
rejectUnauthorized: false,

For example

const httpsServerConfig = {
    key: fs.readFileSync(PATH_TO_KEY),
    cert: fs.readFileSync(PATH_TO_CRT),
    ca: fs.readFileSync(PATH_TO_CA),
    requestCert: true,
    rejectUnauthorized: false,
}

IDENTITY AGENT CONFIG FOR MTLS

Before configuring MTLS make sure that you import the client certificate and its associated private key onto the windows machine.

Importing the root certificate with Powershell

Start powershell as an administrator then type the following command substituting C:\extauthn.caroot.crt with the path of your extauthn.caroot.crt you created during your TLS certificate setup.

Import-Certificate -FilePath C:\extauthn.caroot.crt -CertStoreLocation Cert:\LocalMachine\root
Importing the client certificate and key with Powershell

Start powershell as an administrator then type the following command substituting C:\extauthn.client.p12 with the path of your extauthn.client.p12 you created during your TLS certificate setup.

Import-PfxCertificate -FilePath C:\extauthn.client.p12 -CertStoreLocation Cert:\LocalMachine\My

You should see see output like the following

   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject
----------                                -------
8BEB4C0A77090F2BEDA49BCC0A57B03E8242540B  CN=extauthn.client, OU=MyUnit, O=MyOorg, S=QLD, C=AU

Copy the value under subject CN=extauthn.client, OU=MyUnit, O=MyOorg, S=QLD, C=AU, you will need this value when configuring your Identity Agent on ISV.

IDENTITY AGENT SETTINGS FOR MTLS

In the Identity Agent UI set the Authentication Type to MTLS and then set the following values:

SettingValue
The certificate authorityCopy the text inside the extauthn.caroot.crt file you created when you created the tls certificates
Private key certificate nameEnter the subject value that appeared after you imported your clicent certificate with powershell. Or type certutil -store MY to and copy the value for Subject. For example CN=extauthn.client, OU=MyUnit, O=MyOorg, S=QLD, C=AU

Example of the Private Key Certificate Name

628 644
Using MTLS with Basic Auth or OAuth

If you would like to use MTLS in addition to Basic Auth or OAuth, open the server.js file and uncomment both MTLS AND the other Auth type you'd like to use

// Authentication (uncomment desired)
app.use(basicAuthen);                       // Basic Auth
app.use(mtls);                              // MTLS
// app.use(symmetricJwt);                      // Symmetric signed JWT
// app.use(asymmetricJwt);                     // Asymmetric signed JWT

Then follow the steps above for importing the certificate on windows and setting the private key certificate name:

1074

Signed JWT Authentication

Choosing JWT Authentication causes your the bridge agent to send a signed JSON Web Token (JWT) to your external agent web service.

Example header

{
  "host": "localhost:8555",
  "user-agent": "Go-http-client/1.1",
  "transfer-encoding": "chunked",
  "accept": "application/json",
  "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjUxMTAyMjcsImlzcyI6IkJyaWRnZUFnZW50Iiwic3ViIjoic3ViampqIn0.FYcDCwMdQA4Ibx17hPvrfrpnUAYe6sB_bTtfDI2PA2A",
  "content-type": "application/json",
  "accept-encoding": "gzip"
}

Enabling Symmetric Signed JWT Authentication in the Sample Application

Uncomment the symmetricJwt middleware

// Authentication (uncomment desired)
// app.use(basicAuthen);                       // Basic Auth
// app.use(mtls);                              // MTLS
app.use(symmetricJwt);                      // Symmetric signed JWT
// app.use(asymmetricJwt);                     // Asymmetric signed JWT

Setting the .env variables for Symmetric Signed JWT authentication

Open .env at the root of your project directory and set the expected secret key, subject and prefix of the signed JWT.

# Symmetric JWT variables
SYMMETRIC_JWT_SECRET_KEY=mySuperSecret
SYMMETRIC_JWT_SUBJECT=JwtAuth
SYMMETRIC_JWT_PREFIX='Bearer '

IDENTITY AGENT CONFIG FOR SYMMETRIC SIGNED JWT

Open the Identity Agent UI and select JSON Web Token (JWT). Complete the following sections

SettingSample Application ValueExplanation
HTTP headerauthorizationThe name of the header. The sample application uses authorization.
JWT header value prefixBearer The prefix that appears before the JWT in the header. Set this to whatever you have set in the .env file. Remember to include the space after Bearer if that's the prefix you're using.
Sub claimJwtAuthThe sub claim in the JWT. Must match what you have set in the .env file
Signing AlgorithmHS256Must be either HS256, HS384 or HS512 as these are the symmetric signing algorithms.
Secret Key ValuebXlTdXBlclNlY3JldA==Must be the base64 encoded versions of whatever you specified in the .env file for SYMMETRIC_JWT_SECRET_KEY
Maximum valid lifetime60How long the JWT should be valid
The certificate authorityCopy and paste the value of the extauthn.caroot.crt that you created when setting up your TLS certificatesRoot certificate that tells the bridge agent to trust TLS connections from the sample application.
1456

Enabling Asymmetric Signed JWT Authentication in the Sample Application

Uncomment the asymmetricJwt middleware

// Authentication (uncomment desired)
// app.use(basicAuthen);                       // Basic Auth
// app.use(mtls);                              // MTLS
// app.use(symmetricJwt);                      // Symmetric signed JWT
app.use(asymmetricJwt);                     // Asymmetric signed JWT

Setting the .env variables for Asymmetric Signed JWT authentication

Open .env at the root of your project directory and set the expected secret key, subject and prefix of the signed JWT.

# Asymmetric JWT variables
ASYMMETRIC_JWT_PUBLIC_CERTIFICATE_PATH='./certs/extauthn.client.crt'
ASYMMETRIC_JWT_SUBJECT=JwtAuth
ASYMMETRIC_JWT_ALGORITHM=RS256
ASYMMETRIC_JWT_PREFIX='Bearer '

Notice now that we are specifying the path of the public certificate. That is because we will be using this public key to verify the signed JWT.

Accordingly, this means the bridge agent will need to use the corresponding private key in order to sign the JWT.

Import the private key into the windows keystore by running powershell as an administrator and typing the following command replacing C:\extauthn.client.p12 with the path of your extauthn.client.p12 file.

Import-PfxCertificate -FilePath C:\extauthn.client.p12 -CertStoreLocation Cert:\LocalMachine\My

You will should see an output like the following:

   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject
----------                                -------
8BEB4C0A77090F2BEDA49BCC0A57B03E8242540B  CN=extauthn.client, OU=SecurityDev, O=IBM, S=QLD, C=AU

Make a note of this Subject value (CN=extauthn.client, OU=SecurityDev, O=IBM, S=QLD, C=AU) as you will need to specify this value as the Private key certificate name when setting up up your Identity Agent on ISV.

IDENTITY AGENT CONFIG FOR ASYMMETRIC SIGNED JWT

Open the Identity Agent UI and select JSON Web Token (JWT). Complete the following sections

SettingSample Application ValueExplanation
HTTP headerauthorizationThe name of the header. The sample application uses authorization.
JWT header value prefixBearer The prefix that appears before the JWT in the header. Set this to whatever you have set in the .env file. Remember to include the space after Bearer if that's the prefix you're using
Sub claimJwtAuthThe sub claim in the JWT. Must match what you have set in the .env file
Signing AlgorithmRS256MUST be the same as the ASYMMETRIC_JWT_ALGORITHM set in the .env file. Other asymmetric signing algorithms include: RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512
Private Key Certificate NameCN=extauthn.client, OU=SecurityDev, O=IBM, S=QLD, C=AUMy be the subject name in the windows keystore. Retrieve it by typing certutil -store MY
Maximum valid lifetime60How long the JWT should be valid
The certificate authorityCopy and paste the value of the extauthn.caroot.crt that you created when setting up your TLS certificatesRoot certificate that tells the bridge agent to trust TLS connections from the sample application
1456

OAuth Authentication

The OAuth flow works by having the bridge agent perform a client credentials OAuth flow against an OAuth authorization server (ISV is used in this example). The flow works as follows:

  1. The bridge agent sends its client credentials to the authorization server for an access token.
  2. The access token is then sent as a Bearer token in an authorization header to your web service
  3. Your web service confirms the validity of this web token using the OAuth server's introspect endpoint.

Enabling OAuth Authentication in the Sample Application

Uncomment the OAuth middleware

// Authentication (uncomment desired)
// app.use(basicAuthen);                       // Basic Auth
// app.use(mtls);                              // MTLS
// app.use(symmetricJwt);                      // Symmetric signed JWT
// app.use(asymmetricJwt);                     // Asymmetric signed JWT
app.use(oauth);                             // Oauth         
Create an API client in ISV

To use this OAuth sample with ISV you will need to create an API client.

Don't select any entitlements.

Use the client id and the client secret of this API Client in following steps.

Set the the OAuth .env variables

Open the .env file a the root of your project directory and set the following variables:

# OAuth Variables
OAUTH_CLIENT_ID=12345678-1234-1234-1234-123456789012
OAUTH_CLIENT_SECRET=abcd1234
OAUTH_INTROSPECT_URL=https://tenant.verify.ibm.com/v1.0/endpoint/default/introspect
SettingValue
OAUTH_CLIENT_IDThe client_id of the API client you created
OAUTH_CLIENT_SECRETThe client_secret of the API client you created
OAUTH_INTROSPECT_URLThe url of the ISV tenant you created your API client on followed by the introspection endpoint /v1.0/endpoint/default/introspect

Configuring OAuth in Identity Agent Web UI

The Identity Agent settings are used by the bridge agent to talk to your web service. Enter the following settings

SettingValue
Token endpoint urlThe url of your ISV tenant followed by /v1.0/endpoint/default/token
Client IDThe client_id of the API client you created
Client SecretThe client_secret of the API client you created
The certificate authorityThe CA certs whose private keys have been used to sign the TLS certificates of both your tenant (when talking talking to the introspect endpoint) and your web service. Leave this blank, we'll import the CA cert on the windows machine.
Private key certificate nameLeave blank for now. If you want to use MTLS alongside OAuth, see the MTLS section for setting this field.
1456

Installing the root certificate on the windows machine

In order for the bridge agent to know to trust the TLS certificate presented by your web service you'll need to import the extauthn.caroot.crt certificate into the root keystore on windows.

To do, run powershell as administrator and type the following command, replacing C:\extauthn.caroot.crt with the path your extauthn.caroot.crt file

Import-Certificate -FilePath C:\extauthn.caroot.crt -CertStoreLocation Cert:\LocalMachine\root