SDKS

Node SDK

The WorkOS Node SDK provides your applications using server-side JavaScript access to the WorkOS Audit Trail and SSO APIs.

Installation

You can install the SDK package with:

Yarn:

Terminal

file_copy
yarn add @workos-inc/node

or npm:

Terminal

file_copy
npm i @workos-inc/node

View the source on GitHub.

Configuration

To use the SDK you must first provide your API key from the Developer Dashboard.

You can do this one of two ways:

First, by declaring the environment variable WORKOS_API_KEY:

Terminal

file_copy
WORKOS_API_KEY="{secretKey}" ./app

Or, you can set it after importing the module, before your application starts:

app.js

file_copy
const workos = new WorkOS('{secretKey}');

After providing your API key, you'll need to include WorkOS depending on which module system you're using:

app.js

file_copy
// ES Module Import Format
import WorkOS from '@workos-inc/node';

// CommonJS Module Import Format
const WorkOS = require('@workos-inc/node').default;

SDK Structure

After installing and configuring WorkOS, it's helpful to be oriented with the SDK's layout. This SDK is organized into separate submodules, one for each supported product:

  • auditTrail
  • sso

Each of these packages has its own associated functions for interacting with WorkOS. Calling these functions takes the general form:

workos.submodule.functionCall();

The auditTrail Object

workos.auditTrail.createEvent(event)

Create an event and publish it to the WorkOS Audit Trail.

workos.auditTrail.createEvent() accepts a JSON object containing descriptive attributes that detail your application's event. For example:

app.js

file_copy
const event = {
  group: 'abstract.com',
  location: '55.27.223.26',
  action: 'document.viewed',
  action_type: 'r',
  actor_name: 'Jairo Kunde',
  actor_id: 'user_01DGZ0FAXN978HCET66Q98QMTQ',
  target_name: 'central.class',
  target_id: 'doc_01DGZ0FAXP4HA4X0BVFKS0ZH4Y',
  occurred_at: new Date(),
};

workos.auditTrail.createEvent(event);

This results in WorkOS logging the following event:

JSON

file_copy
{
  "id": "evt_01DGZ0FB2X1X14QAFGEFNQD22X",
  "group": "abstract.com",
  "location": "55.27.223.26",
  "action": "document.viewed",
  "action_type": "r",
  "actor_name": "Jairo Kunde",
  "actor_id": "user_01DGZ0FAXN978HCET66Q98QMTQ",
  "target_name": "central.class",
  "target_id": "doc_01DGZ0FAXP4HA4X0BVFKS0ZH4Y",
  "metadata": {},
  "occurred_at": "2020-07-08T00:45:05.764Z"
}

All events are created asynchronously by default. They also support await/async behavior.

For details about the specific use of each event attribute, refer to the API Reference.

Using Metadata

The metadata attribute is a location for storing key-value data that provide additional context surrounding your events. Any relevant information that would be helpful to you or to others viewing this event in the future should be stored here.

Please refrain from storing sensitive or personally identifiable information in the metadata field.

Valid values for the metadata field include the following primitive types:

  • string
  • boolean
  • number
  • Date

You can add metadata directly to any event by appending the metadata property. For example:

app.js

file_copy
const event = {
  group: 'height.app',
  location: '93.28.25.245',
  action: 'document.created',
  action_type: 'c',
  actor_name: 'Brooklyn Heaney',
  actor_id: 'user_01DGJV266TCPG48EDA9GMTYDQ8',
  target_name: 'wooden_orchard.pvb',
  target_id: 'doc_01DGJV266TG6FJEVRB545QTR37',
  metadata: {
    description: 'Document created.',
    x_request_id: '7ff79946-c8f1-494c-a28f-7558549e6a7d',
  },
  occurred_at: new Date(),
};

workos.auditTrail.createEvent(event);

The resulting event logged by WorkOS:

JSON

file_copy
{
  "id": "evt_01DGJV26B1S8D18P6CBTTZAKFF",
  "group": "height.app",
  "location": "93.28.25.245",
  "action": "document.created",
  "action_type": "c",
  "actor_name": "Brooklyn Heaney",
  "actor_id": "user_01DGJV266TCPG48EDA9GMTYDQ8",
  "target_name": "wooden_orchard.pvb",
  "target_id": "doc_01DGJV266TG6FJEVRB545QTR37",
  "metadata": {
    "description": "Document created.",
    "x_request_id": "7ff79946-c8f1-494c-a28f-7558549e6a7d"
  },
  "occurred_at": "2020-07-08T00:45:05.764Z"
}

Good events contain all relevant, supporting information surrounding the event. Any information that could be used to inform future readers precisely what happened, how it happened, and when it happened should be included.

For more details on using the metadata attribute, check out the API Reference.

The sso Object

workos.sso.getAuthorizationURL(domain, projectID, redirectURI, apiHostname)

Generate an authorization URL to intitiate the WorkOS OAuth2 workflow.

workos.sso.getAuthorizationURL() accepts five arguments:

  • domain (string) — the Enterprise's domain, without protocol (ex. example.com), only optional with a provider parameter.
  • projectID (string) — your application's WorkOS Project ID (ex. project_01JG3BCPTRTSTTWQR4VSHXGWCQ)
  • provider (optional, string) — optional parameter that specifies the type of Connection to authenticate with. If used, a user of any domain can be authenticated. Only GoogleOAuth is currently supported. Most commonly used for "Signup with Google" buttons.
  • state (optional, string) — an optional unique identifier used to manage state across authorization transactions (ex. 1234zyx)
  • redirectURI (string) — a callback URL where your application redirects the user-agent after an authorization code is granted (ex. workos.dev/callback)

This function will return an OAuth2 query string of the form:

https://api.workos.com/sso/authorize?response_type=code&domain=${domain}&client_id=${projectID}&redirect_uri=${redirectURI}&state=${state}

For example, when used in an Express server:

app.js

file_copy
import express from 'express';
import WorkOS from '@workos-inc/node';
const app = express();
const port = 9000;

const client = new WorkOS('{secretKey}');
const domain = '{foo-corp.com}';
const redirectURI = 'https://workos.dev/callback';
const projectID = '{projectId}';

app.get('/login', (_req, res) => {
  const url = client.sso.getAuthorizationURL({
    domain,
    redirectURI,
    projectID,
  });

  res.redirect(url);
});

The response will redirect to:

https://api.workos.com/sso/authorize?response_type=code&domain=foo-corp.com&client_id=project_01JG3BCPTRTSTTWQR4VSHXGWCQ&redirect_uri=https://workos.dev/callback

workos.sso.getProfile(code, projectID)

Return the profile of an authorized user.

workos.sso.getProfile() accepts three arguments:

  • code (string) — an opaque string provided by the authorization server; will be exchanged for an Access Token when the user's profile is sent
  • projectID (string) — your application's WorkOS Project ID (ex. project_01JG3BCPTRTSTTWQR4VSHXGWCQ)

This function will return a profile object with the following attributes:

JSON

file_copy
{
  "connection_type": "IdpSAML",
  "email": "IdP.user@{foo-corp.com}",
  "first_name": "IdP",
  "id": "prof_0LT6S2JPIG7KN2HFA5EBQ7AJDR",
  "idp_id": "ks08xfdvqripex05pq3a",
  "last_name": "User",
  "object": "profile"
}

For example, if we assume Azure AD SAML as the Identity Provider, then the Express server above can be extended:

app.js

file_copy
import express from 'express';
import WorkOS from '@workos-inc/node';
const app = express();
const port = 9000;

const client = new WorkOS('{secretKey}');
const domain = '{foo-corp.com}';
const redirectURI = '{redirectURI}';
const projectID = '{projectId}';

app.get('/login', (_req, res) => {
  const url = client.sso.getAuthorizationURL({
    domain,
    redirectURI,
    projectID,
  });

  res.redirect(url);
});

app.get('/callback', async (req, res) => {
  const { code } = req.query;
  const profile = await client.sso.getProfile({
    code,
    projectID,
  });

  res.json(profile).send();
});

app.listen(port, () => console.log(`https://workos.dev/login`));

And the server's response would be:

JSON

file_copy
{
  "connection_type": "AzureSAML",
  "email": "AzureSAML.user@{foo-corp.com}",
  "first_name": "AzureSAML",
  "id": "prof_0LT6S2JPIG7KN2HFA5EBQ7AJDR",
  "idp_id": "98it0ihwkouw86td6f5z",
  "last_name": "User",
  "object": "profile"
}