Hi all, How would someone securely store API secre...
# suitescript
b
Hi all, How would someone securely store API secrets/keys that you create manually? I looked into native API secrets management but it only stores secrets that it creates. Any way to achieve this? TIA
c
The link you provided above references the correct feature - you can store secrets you create, then programmatically access them without exposing the secret data. See this article about creating secrets: https://system.netsuite.com/app/help/helpcenter.nl?fid=section_160216498405.html
b
Oh I see that I can add the
secret
to password field here, but this is in the UI. I need to achieve this programmatically.
For more context, I get the secret from external source through an API call. I then need to store it during that process.
i
Is the secret only being used for the process you are running within that timeframe or does that secret remain active for a long period of time?
b
use Form.addCredentialField in a user event script deployed on a custom record to create a credential field
then create that record in a script while using dynamic mode so that you can set the credential field and then get back its guid
will not work if you are doing this in a user event, since user events wont trigger other user events
b
@Israel Gonzalez need to store it for future reuse @battk that kind of makes sense, will try it out. The process mentioned before runs in a restlet, so that’s where I will try and create this field to get guid. thanks
@battk I tried what you suggested and got most of the way. I’m stuck in the user event script where I have the
form.addCredentialField
api called, like this:
Copy code
const form = context.form;
const credField = form.addCredentialField({...});
I’m not sure how to add the secret to this credField. I tried with defaultValue:
Copy code
credField.defaultValue = someSecret;
But I get the same secret if I log the form in my restlet, and not the GUID which I was hoping for. I didn’t find any other way to input a value to the field. Any suggestions?
b
you dont use a default value
you set the field using dynamic mode from your restlet
then get its value, which will change into the guid
b
I think I got the GUID now. Thanks @battk Now onto storing and making use of it.
From the APIs perspective, GUID is the same as the secret ID created natively. So for long term use, should I just store GUID? And when required, use it with one of the APIs? But then I’m not even using the API secrets management to encrypt the key I want to store. Could anyone have any insight on this?
b
the main difference is that api secrets can be edited and have a ui to do so
b
to retrieve the stored
key
from GUID, I would have to use one of the
API secrets
APIs anyways, right?
After I have the
GUID
, I could run this to get the `secretKey`:
Copy code
const secretKey = crypto.createSecretKey({
    guid: guid,
    encoding: encode.Encoding.UTF_8
});
What I’m confused here is, do I have to run this during the storing process or just when retrieving the key?
b
secret keys and api secrets are different things
there is a fair chance you dont know what a secret key is used for if the encoding is utf-8
b
It is from NetSUite’s example 🙂
but yeah you are right, newbie on this whole encryption thing
b
a lot of the examples in suitescript arent useful beyond syntax
b
but my question still remains. 🙂 What exactly should I be storing? Just the GUID I got from
form.addCredentialField
field or do I need to convert that to something else? I need it for long term use, meaning this doesn’t change without manual step.
b
storing the guid is fine
store it the same way you would the id from an api secret
b
I keep coming back to this thread as I’m still not clear on how to use the GUID that I created for client secret. I will try to put as much context as possible and hope someone can help me 🙂 In the beginning of an integration, NetSuite receives host, clientId and clientSecret from an external system. I used
form.addCredentialField
like below to create GUID of the clientSecret.
Copy code
const secretCredField = form.addCredentialField({
    id: "custpage_client_secret_guid",
    label: "Client Secret",
    restrictToDomains: ["example.com"],
    restrictToScriptIds: ["customscript_secrets_ue"],
    restrictToCurrentUser: false,
  });
I store this clientSecret GUID along with host and clientId in a custom record. Now when NetSuite needs to make a call to that external system, I need to create a HTTPS
Authorization
header with above info using basic authentication scheme like below.
Copy code
Basic base64Encode(clientId:clientSecret)
Now my question is, which API should I use to retrieve the original clientSecret from the GUID? My options are
https.createSecretKey
and
https.createSecureString
. I believe I should use the second one but please tell me if I’m wrong. And what encoding do I use (default is UTF_8)? I didn’t use any encoding when creating GUID.
Copy code
clientSecret = https.createSecureString({
  input: clientSecretGuid,
  inputEncoding: https.Encoding.UTF_8
});
Again, this returns an
https.SecureString
object. How do I extract actual clientSecret string from it? I even tried below and prefix
Basic
after but it doesn’t seem to work too.
Copy code
const base64Encoded = https.createSecureString({
    input: `${clientId}:${clientSecretGuid}`,
    inputEncoding: https.Encoding.BASE_64,
  });
Not being able to log the encoded strings, even during dev, is pretty frustrating 😄 Any help here would be appreciated. TIA
b
input encoding is what you would use to tell netsuite how you entered the secret
the example here being if the password was "open sesame", thats plain text
in which case you would want to use utf-8, a text based encoding
however, if your secret was binary, you wouldnt be able to enter the binary into a credential field or api secret
they only accept text
so you would need to encode the binary into text, then you could enter the secret
if you chose base64 encoding for that encoding, the input encoding would be base64
utf-8 would be inappropriate for binary data, it cant actually represent all binary content
utf-8 uses the first few bits for metadata
b
I pass the clientSecret as is, so I guess I can use
UTF_8
How would I extract the original clientSecret from the
https.SecureString
object that the
https.createSecureString
returns?
b
you cant extract it
you can only use suitescript to tell how to manipulate and then where to use it
at no point will you be in a position to log the contents of the guid or secret
you couldnt actually do it until netsuite added functionality to make it possible
if you only need the secret for this purpose, i personally would recommend you generate the authorization header ahead of time and then put it in the credential field
basic authentication is always the same header, which means you can generate it ahead of time, though it does make it less secure due to it
b
Interesting idea
Oh does it have to be inside curly braces if something is encoded, like GUID?
b
secure strings, are treated like templates
with the id inside the curly brace being replaced with the contents before netsuite sends the https request