Client Certificate Authentication in API Test

Please paste the permalink to the page in question below:

If asking about a particular script please copy your script or relevant snippet below:

Please share your question/describe your issue below. Include any screenshots that may help us understand your question:

I understood that New Relic uses http-request module for API Tests. I am wondering if I can do client certificate authentication as supported by the library.
And for the certificate and key, can I load it from a file, or should I code the pem string there?

@liyu_yi you should be able to provide the client certificate as mentioned in the request documentation. You would have something like this:

$http.get({
    url: 'https://newrelic.com',
    agentOptions: {
        cert: '<CERT HERE>',
        key: '<KEY HERE>'
    }
}, function(err, resp, body){
  console.log(err, resp, body);
});
1 Like

My use case is private minion.

This is the github agentOptions request documentation: https://github.com/request/request#using-optionsagentoptions

Yet ‘path’ can not be loaded:

var path = require(‘path’);

Error: Module “path” cannot be loaded

Hey @genelev As you have found, path is not one of the supported modules in Synthetics right now. From a quick search I see that module allows for specifying a path on the host for the script to interact with, reading/writing. Obviously with public minions there is a concern around allowing access to the host. As those minions are used by all Synthetics customers we do not want to take that risk of opening up a potential security hole.

Your use case being very different. In Private Minions anything done to the host only affects you locally, there’s less concern there. As such I think it’s definitely a valid Feature Idea to open up Private Minions to any importable Node module.

I’ll go ahead and file that feature request for you internally. Could you post in the Feature Ideas space? We can add a poll over there and others can vote on this feature & share their thoughts.

Any updates on this. We have a similar use case to test private minions by passing the certs. can you point me to sample API test script which we can use to test our private minions by passing client certificates?

Hi @Bhaskar.Nagaraj, you have 2 options here if you are using Private Minions.
_
For Synthetics, secrets for scripted monitors can be managed with the Secure Credentials feature
_
The value of a secure credential can not exceed 3000 characters, and currently doesn’t support line breaks. That being said you can work around line breaks by storing the value as base64 and then decrypting the base64 value in the script using the atob 3rd party node module
_
For example, I have a secure credential with a PEM file stored in base64:

const atob = require('atob');
const PEM = atob($secure.PEMTEST);

Alternatively, with Containerized Private Minions you can now load Custom npm modules that can be used within a script :slight_smile:

Hello @rdouglas, @bburkholder I have a similar use case where I am using secure credentials in my script to provide the client certificare and private key. I have encoded the certificate and key(with line breaks) in base64 format and am using the atob library to decode the credentials back to binary format. I am facing “Error: error:0906D06C:PEM routines:PEM_read_bio:no start line” error while validating the script. Stuck here since a few days now. Any leads would be highly appreciated! My login function is something like this -

var coblogin = function () {
log("<===============Running Cobrand Login API===============>");
var deferred = Q.defer();

if (!(cobrandPassword == "" || cobrandPassword == null)) {

    
    var options = {
        uri: url + '/cobrand/login',

       agentOptions: {
            
            key:   atob($secure.SSL_CERTIFICATE),
            cert : atob($secure.SSL_KEY), 
        
        },
        
        headers: {
            'Canonical-Resource': 'CobrandLogin',
            'Content-Type': 'application/json',
            'Cobrand-Name': '' + cobrandName + '',
            'Api-Version': '1.0'
        },
        
        body: '{"cobrand" : {"cobrandLogin": "' + cobrandLogin + '", "cobrandPassword": "' + cobrandPassword + '"}}'
    };

Hello again, I tried a few approaches from github to solve the “no start line” error, and am able to validate the script successfully, with desired response, when passing the certificate and key directly in the agent options, in the format-
“-----BEGIN RSA PRIVATE KEY … asdfasdf\n-----END RSA PRIVATE KEY-----\n”

But am still facing issues with line breaks in secure credentials. Since .pem certificate and .key are already base64 encoded ascii, how do I accomodate newline while encoding and further use it in the secure credentials?

Thanks again!

Hi @ssachdeva,

Glad to hear you were able to get the script to successfully validate! So you’ve base64 encoded your cert into the secure credentials value field right? Note, it can take only 3000 characters, so if the value is greater than that you’ll need to split the value and recombine in your script.

When accessing the value in your script, the newline characters will not be output if you use something like:

console.log(options.agentOptions.cert)

However, you will see \n if you log the object:

console.log(options)

When you did a base64 encoding of your cert, did you do something like this?

# encode
base64 cert.pem > base64_cert.pem

# should be one line without breaks
cat base64_cert.pem

# decode to check that it worked
base64 -d base64_cert.pem > decoded_cert.pem
cat decoded_cert.pem

If you need to split the cert into several base64 encoded files, you can do something like this:

base64 cert.pem | split -C 2500

It will generate files up to 2500 characters in length and with names like xaa, xab, xac, etc.

Looking forward to hearing how that works for you!

1 Like

Thanks a lot for your help! :slightly_smiling_face: I’m able to use the secure credentials with certificate and it works perfectly fine now. I was under the impression that since the .pem certificate is already in base64 encoded format, and append -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- later as a string, but this whole certificate file is decoded at once, maybe that’s why the certificate was not read properly earlier.

Again, thanks a lot for your help, and the quick response!:slightly_smiling_face:

Glad that’s working for you :smiley: Thanks for letting us know.

A post was split to a new topic: Message: “No such file or directory”

A post was split to a new topic: Monitor one URL passing, crt/key and password