- Docs
- SaaS Shield
- Suite
- TSC SDKs (Legacy)
- NodeJS SDK
– title: Tenant Security Client NodeJS description: Overview of the Tenant Security Client for NodeJS and a quickstart for how to use it with the Tenant Security Proxy
Tenant Security Client NodeJS
The SDK is published to NPM and can be installed via
Consolenpm add @ironcorelabs/tenant-security-nodejs
The minimum Node version supported by this library is Node 10. This library also contains TypeScript definitions.
Quickstart
This is a minimal example of round tripping a document that gets encrypted to a key controlled by a tenants KMS.
JavaScriptconst {TenantSecurityClient, DocumentMetadata} = require("@ironcorelabs/tenant-security-nodejs"); // Initialize the client with a Tenant Security Proxy domain and API key. // Typically this would be done once when the application or service initializes const client = new TenantSecurityClient(PROXY_ENDPOINT, API_KEY); // Create a map containing your document data const document = { ssn: Buffer.from("000-12-2345", "utf-8"), address: Buffer.from("2825-519 Stone Creek Rd, Bozeman, MT 59715", "utf-8"), name: Buffer.from("Jim Bridger", "utf-8"), }; // Create metadata used to associate this document to a tenant, name the document, and // identify the service or user making the call const metadata = new DocumentMetadata(TENANT_ID, "serviceOrUserId", "PII"); // Request a key from the KMS and use it to encrypt the document client .encryptDocument(document, metadata) .then((encryptResult) => { /* … persist the EDEK and encryptedDocument to your persistence layer … */ const edek = encryptResult.edek; const encryptedDocument = encryptResult.encryptedDocument; /* … retrieve the encrypted fields and EDEK from your persistence layer */ // Recreate the encrypted document from persisted data const recreated = {encryptedDocument, edek}; // Decrypt the document back to plaintext return client.decryptDocument(recreated, metadata); }) .then((decryptedDoc) => { // Access decrypted fields from the doc const name = decryptedDoc.plaintextDocument.name.toString("utf-8"); });
Examples
Examples of using the Tenant Security Client SDK to protect sensitive data can be found on GitHub.
SDK Documentation
The Node SDK contains several classes which provide the functionality necessary to communicate with the Tenant Security Proxy.
class DocumentMetadata
constructor(tenantId, requestingUserOrServiceId?, dataLabel?, sourceIp?, objectId?, requestId?, otherData?)
Parameters
Parameter Name | Value | Description |
---|---|---|
tenantId | string | Unique ID of tenant that is performing the operation. |
[requestingUserOrServiceId] | string | Unique ID of user/service that requested the data. |
[dataLabel] | string | Classification of data being processed. |
[sourceIp] | string | IP address of the user or service that requested the data. |
[objectId] | string | Identifier of the data being processed. |
[requestId] | string | Unique ID that ties host application request ID to Tenant Security Proxy logs. |
[otherData] | {[string]: string} | Additional key/value pairs to add to metadata which will be logged in full within the Tenant Security Proxy logs. |
class EventMetadata
constructor(tenantId, requestingUserOrServiceId, dataLabel?, timestampMillis?, sourceIp?, objectId?, requestId?, otherData?)
Parameters
Parameter Name | Value | Description |
---|---|---|
tenantId | string | Unique ID of tenant that is performing the operation. |
requestingUserOrServiceId | string | Unique ID of user/service that requested the data. |
[dataLabel] | string | Classification of data being processed. |
[timestampMillis] | string | Time when the event occurred. Defaults to current time if not specified. |
[sourceIp] | string | IP address of the user or service that requested the data. |
[objectId] | string | Identifier of the data being processed. |
[requestId] | string | Unique ID that ties host application request ID to Tenant Security Proxy logs. |
[otherData] | {[string]: string} | Additional key/value pairs to add to metadata which will be logged in full with the event. |
class TenantSecurityClient
constructor(tspDomain: string, apiKey: string)
Parameters
Parameter Name | Value | Description |
---|---|---|
tspDomain | string | Domain where the Tenant Security Proxy is running in your infrastructure. |
apiKey | string | Key to use for requests to the Tenant Security Proxy. |
isCiphertext(bytes)
Check if the provided bytes are a valid encrypted document.
Parameters
Parameter Name | Value | Description |
---|---|---|
bytes | Buffer | Bytes to verify. |
Response
Returns a boolean denoting if the provided bytes are valid ciphertext.
encryptDocument(document, metadata)
Encrypt the provided document. Documents are provided as a map of fields from the document id/name (string) to bytes (Buffer). Uses the Tenant Security Proxy to generate a new document encryption key (DEK), encrypt that key (EDEK) and then uses the DEK to encrypt all of the provided document fields.
Parameters
Parameter Name | Value | Description |
---|---|---|
document | {[string]: Buffer} | Document to encrypt. Each field in the provided document will be encrypted with the same key. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a map from each fields id/name to encrypted bytes as well as the EDEK and discards the DEK.
JSON{ "encryptedDocument": {[string]: Buffer}, "edek": string }
encryptStream(inputStream, outputStream, metadata)
Encrypt the provided stream of bytes without having to read in the full bytes. Writes out the encrypted bytes to the output stream.
Parameters
Parameter Name | Value | Description |
---|---|---|
inputStream | NodeJS.ReadableStream | A stream of readable bytes. |
outputStream | NodeJS.WritableStream | A writable destination stream |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with the EDEK and discards the DEK. Once the Promise resolves all of the encrypted bytes will have been written to the output stream.
JSON{ "edek": string }
encryptDocumentWithExistingKey(document, metadata)
Encrypt the provided document reusing an existing encrypted document encryption key (EDEK). Makes a call out to the Tenant Security Proxy to decrypt the EDEK and then uses the resulting key (DEK) to encrypt the document. This allows callers to update/re-encrypt data that has already been encrypted with an existing key. For example, if multiple columns in a DB row are all encrypted to the same key and one of those columns needs to be updated, this method allows the caller to update a single column without having to re-encrypt every field in the row with a new key.
Parameters
Parameter Name | Value | Description |
---|---|---|
document.edek | string | Existing EDEK used to encrypt documents. |
document.plaintextDocument | {[string]: Buffer} | Collection of fields to re-encrypt with the existing key. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a map from each fields id/name to encrypted bytes as well as the EDEK and discards the DEK.
JSON{ "encryptedDocument": {[string]: Buffer}, "edek": string }
encryptDocumentBatch(documentList, metadata)
Encrypt a map of documents from the ID of the document to the list of fields to encrypt. Makes a call out to the Tenant Security Proxy to generate a collection of new DEK/EDEK pairs for each document ID provided. This function supports partial failure so it returns two objects, one of document ID to successfully encrypted document and one of document ID to a TenantSecurityException
.
Parameters
Parameter Name | Value | Description |
---|---|---|
documentList | {[string]: {[string]: Buffer}} | Collection of fields to encrypt from the field name to the bytes to encrypt. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys of each map returned will be the same keys provided in the original document list.
JSON{ "successes": { [string]: { "encryptedDocument": {[string]: Buffer}, "edek": string } }, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
encryptDocumentBatchWithExistingKey(documentList, metadata)
Re-encrypt a existing map of documents from the ID of the document to the previously encrypted document. Makes a call out to the Tenant Security Proxy to decrypt the EDEKs present in each provided document. This function supports partial failure so it returns two objects, one of document ID to successfully re-encrypted document and one of document ID to a TenantSecurityException.
Parameters
Parameter Name | Value | Description |
---|---|---|
documentList | {[string]: {plaintextDocument: {[string]: Buffer}, edek: string}} | Collection of plaintext documents with the EDEK that was previously used to encrypt them. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys of each map returned will be the same keys provided in the original document list.
JSON{ "successes": { [string]: { "encryptedDocument": {[string]: Buffer}, "edek": string } }, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
decryptDocument(encryptedDoc, metadata)
Decrypt the provided document. Decrypts the documents encrypted document key (EDEK) using the Tenant Security Proxy and uses it to decrypt and return the document bytes. The DEK is then discarded.
Parameters
Parameter Name | Value | Description |
---|---|---|
encryptedDoc.edek | string | EDEK used to encrypt the document. |
encryptedDoc.encryptedDocument | {[string]: Buffer} | Collection of fields to decrypt from the field name to the bytes to decrypt. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with each documents decrypted field bytes.
JSON{ "plaintextDocument": {[string]: Buffer}, "edek": string }
decryptStream(edek: string, inputStream, outputStream, metadata)
Use the provided EDEK to decrypt the bytes from the provided input stream and write the decrypted bytes out to the provided output stream.
Parameters
Parameter Name | Value | Description |
---|---|---|
edek | string | EDEK that was used to encrypt the bytes in the provided inputStream. |
inputStream | NodeJS.ReadableStream | A stream of readable encrypted bytes. |
outputStream | NodeJS.WritableStream | A writable destination stream |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with the EDEK and discards the DEK. Once the Promise resolves all of the decrypted bytes will have been written to the output stream.
JSON{ "edek": string }
decryptDocumentBatch(documentList, metadata)
Decrypt a map of documents from the ID of the document to its encrypted content. Makes a call out to the Tenant Security Proxy to decrypt all of the EDEKs in each document. This function supports partial failure so it returns two objects, one of document ID to successfully decrypted document and one of document ID to a TenantSecurityException
.
Parameters
Parameter Name | Value | Description |
---|---|---|
documentList | {[string]: {encryptedDocument: {[string]: Buffer}, edek: string}} | Collection of encrypted documents with the EDEK that was previously used to encrypt them. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys of each map returned will be the same keys provided in the original document list.
JSON{ "successes": { [string]: { "plaintextDocument": {[string]: Buffer}, "edek": string } }, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
rekeyEdek(edek, newTenantId, metadata)
Rekey the provided EDEK to a tenant. Decrypts the EDEK and then encrypts the DEK to the new tenant using the Tenant Security Proxy. The DEK is then discarded. The old tenant and new tenant can be the same in order to rekey the EDEK to the tenant’s latest primary config.
Parameters
Parameter Name | Value | Description |
---|---|---|
edek | string | EDEK to rekey. |
newTenantId | string | Tenant ID to rekey the document to. |
metadata | DocumentMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves to a string, encoded using base64
, containing the re-encrypted EDEK.
logSecurityEvent(securityEvent, metadata)
Send a security event for a specific tenant to the SIEM that tenant has configured for logging. Makes a call to the Tenant Security Proxy to send the event.
Parameters
Parameter Name | Value | Description |
---|---|---|
securityEvent | SecurityEvent | Category and type of event to log. |
metadata | EventMetadata | Metadata to attach to the event. |
The SecurityEvent
is a supertype for a collection of different event categories:
AdminEvent
, CustomSecurityEvent
, DataEvent
, PeriodicEvent
, and UserEvent
.
A list of the different events in each category is here.
The CustomSecurityEvent
allows you to define your own events, if none of the predefined options fit your use case.
Response
Returns a Promise which resolves to void if there was no error sending the event.
class FieldMetadata
constructor(tenantId, requestingUserOrServiceId?, dataLabel?, sourceIp?, objectId?, requestId?, otherData?)
Parameters
Parameter Name | Value | Description |
---|---|---|
tenantId | string | Unique ID of tenant that is performing the operation. |
[requestingUserOrServiceId] | string | Unique ID of user/service that requested the data. |
[dataLabel] | string | Classification of data being processed. |
[sourceIp] | string | IP address of the user or service that requested the data. |
[objectId] | string | Identifier of the data being processed. |
[requestId] | string | Unique ID that ties host application request ID to Tenant Security Proxy logs. |
[otherData] | {[string]: string} | Additional key/value pairs to add to metadata which will be logged in full within the Tenant Security Proxy logs. |
interface DeterministicPlaintextField
This describes the shape of objects that are passed to and returned by the deterministic encryption routines.
Members
Parameter Name | Value | Description |
---|---|---|
plaintextField | Buffer | Data to encrypt. |
secretPath | string | Portion of data path used to choose the secret. |
derivationPath | string | Portion of data path used to derive key from secret. |
interface DeterministicEncryptedField
This describes the shape of the encrypted objects that are passed to and returned by the deterministic encryption routines. ##### Members
Parameter Name | Value | Description |
---|---|---|
encryptedField | Buffer | Encrypted data with secret ID prefix. |
secretPath | string | Portion of data path used to choose the secret. |
derivationPath | string | Portion of data path used to derive key from secret. |
class DeterministicTenantSecurityClient
constructor(tspDomain: string, apiKey: string)
Parameters
Parameter Name | Value | Description |
---|---|---|
tspDomain | string | Domain where the Tenant Security Proxy is running in your infrastructure. |
apiKey | string | Key to use for requests to the Tenant Security Proxy. |
A deterministic encryption client can also be constructed using the public member TenantSecurityClient.deterministicClient
.
That client is constructed using the tspDomain
and apiKey
that were used to construct the TenantSecurityClient
.
isCiphertext(bytes)
Check if the provided bytes are a deterministically encrypted field.
Parameters
Parameter Name | Value | Description |
---|---|---|
bytes | Buffer | Bytes to verify. |
Response
Returns a boolean denoting whether the provided bytes are valid ciphertext.
encryptField(field, metadata)
Deterministically encrypt the provided field using the secrets for the tenant’s current KMS.
Parameters
Parameter Name | Value | Description |
---|---|---|
field | DeterministicPlaintextField | Field to encrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a DeterministicEncryptedField
.
encryptFieldBatch(fields, metadata)
Deterministically encrypt a batch of new fields using the secrets for the tenant’s current KMS. Takes a map from identifying field IDs to DeterministicPlaintextField
s.
This function supports partial failure so it returns two objects, a map of field IDs to successfully encrypted fields and a map of field IDs to TenantSecurityException
s.
Parameters
Parameter Name | Value | Description |
---|---|---|
fields | {[string]: DeterministicPlaintextField} | Collection of fields - map from field ID to field to encrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys in each map returned will be the same field ID keys provided in the original fields
object.
JSON{ "successes": {[string]: DeterministicEncryptedField}, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
decryptField(encryptedField, metadata)
Decrypt the previously deterministically encrypted field. Extracts information about the secret to use from the header embedded in the encrypted field.
Parameters
Parameter Name | Value | Description |
---|---|---|
encryptedField | DeterministicEncryptedField | Field to decrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a DeterministicPlaintextField
.
decryptFieldBatch(encryptedFields, metadata)
Decrypt a batch of fields using the secrets used to deterministically encrypt them. Takes a map from identifying field IDs to DeterministicEncryptedField
s.
This function supports partial failure so it returns two objects, a map of field IDs to successfully decrypted fields and a map of field IDs to TenantSecurityException
s.
Parameters
Parameter Name | Value | Description |
---|---|---|
fields | {[string]: DeterministicEncryptedField} | Collection of fields - map from field ID to field to decrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys in each map returned will be the same field ID keys provided in the original fields
object.
JSON{ "successes": {[string]: DeterministicPlaintextField}, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
rotateField(encryptedField, metadata)
Decrypt a previously deterministically encrypted field using the secret information in the header and re-encrypt it using the secrets for the tenant’s current KMS. This method is intended for processing records that are affected by secret rotation.
Parameters
Parameter Name | Value | Description |
---|---|---|
encryptedField | DeterministicEncryptedField | Field to re-encrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a DeterministicEncryptedField
.
rotateFieldBatch(fields, metadata)
Decrypt a batch of fields that were previously deterministically encrypted, then re-encrypt them using the secrets for the tenant’s current KMS. Takes a map from identifying field IDs to DeterministicEncryptedField
s.
This function supports partial failure so it returns two objects, a map of field IDs to successfully re-encrypted fields and a map of field IDs to TenantSecurityException
s.
Parameters
Parameter Name | Value | Description |
---|---|---|
encryptedFields | {[string]: DeterministicEncryptedField} | Collection of fields - map from field ID to field to re-encrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys in each map returned will be the same field ID keys provided in the original fields
object.
JSON{ "successes": {[string]: DeterministicEncryptedField}, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
generateSearchTerms(field, metadata)
Deterministically encrypt the provided field using the current secrets and any in-rotation secrets for the tenant’s current KMS. If rotation is in progress and this returns two values, you should search for matches to either of those values.
Parameters
Parameter Name | Value | Description |
---|---|---|
field | DeterministicPlaintextField | Field to encrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with an array of DeterministicEncryptedField
. This array will have one or two values, depending on
whether rotation is in progress.
generateSearchTermsBatch(fields, metadata)
Deterministically encrypt a batch of fields using the current secrets and any in-rotation secrets for the tenant’s current KMS. If rotation is in progress and and any of the successful results contain two values, you should search for matches to either of those values.
Parameters
Parameter Name | Value | Description |
---|---|---|
fields | {[string]: DeterministicPlaintextField} | Collection of fields - map from field ID to field to encrypt. |
metadata | FieldMetadata | Metadata for this operation. |
Response
Returns a Promise which resolves with a collection of successes and failures that occurred during operation. The keys in each map returned will be the same field ID keys provided in the original fields
object. Each key in the success
maps to an array of one or two DeterministicEncryptedField
s.
JSON{ "successes": {[string]: [DeterministicEncryptedField] }, "failures": {[string]: TenantSecurityException}, "hasSuccesses": boolean, "hasFailures": boolean }
class TenantSecurityException
All errors within the client library will be an instance of the TenantSecurityClientException
. This custom exception exposes an error message as well
as an error code that provides more information as to what error occurred. All error codes can be seen within the library source.
Changelog
The changelog can be viewed in the library repository.