One Identity Safeguard JavaScript/TypeScript SDK
Check out our sample projects to get started with your own custom integration to Safeguard!
One Identity open source projects are supported through One Identity GitHub issues and the One Identity Community. This includes all scripts, plugins, SDKs, modules, code snippets or other solutions. For assistance with any One Identity GitHub project, please raise a new Issue on the One Identity GitHub project page. You may also visit the One Identity Community to ask questions. Requests for assistance made through official One Identity Support will be referred back to GitHub and the One Identity Community forums where those requests can benefit all users.
All functionality in Safeguard is available via the Safeguard API. There is nothing that can be done in the Safeguard UI that cannot also be performed using the Safeguard API programmatically.
safeguard.js is provided to facilitate calling the Safeguard API from
JavaScript and TypeScript. It is meant to remove the complexity of dealing
with authentication via Safeguard's embedded secure token service (STS). The
basic usage is to create a SafeguardClient with your chosen authentication
strategy, call connect(), then call API methods using the same authenticated
client.
safeguard.js also provides an easy way to call Safeguard A2A from JavaScript. The A2A service requires client certificate authentication for retrieving passwords for application integration. When Safeguard A2A is properly configured, specified passwords can be retrieved with a single method call without requiring access request workflow approvals.
safeguard.js includes an SDK for listening to Safeguard's powerful, real-time
event notification system. Safeguard provides role-based event notifications
via SignalR to subscribed clients. The PersistentSafeguardEventListener
provides automatic reconnection with token refresh for long-running listeners.
- TypeScript-first with full type declarations
- Dual ESM/CJS — works with
importandrequire() - Node.js and Browser support
- Multiple auth strategies — Password, Certificate, PKCE (browser), PKCE Non-Interactive (headless), Token, Anonymous
- A2A client — retrieve/set passwords, SSH keys, API key secrets, broker access requests
- SignalR events — one-shot and persistent event listeners with auto-reconnect
- Secure by default — TLS verification enabled, no secrets in memory longer than needed
npm install @oneidentity/safeguardRequires Node.js 20 or later.
import { SafeguardClient, PasswordAuth, Service } from '@oneidentity/safeguard';
const client = new SafeguardClient('safeguard.sample.corp', {
auth: new PasswordAuth({
username: 'Admin',
password: 'Admin123',
provider: 'Local',
}),
});
await client.connect();
const me = await client.get(Service.CORE, 'Me');
console.log(me);
await client.disconnect();import { SafeguardClient, PkceAuth, handlePkceCallback, Service } from '@oneidentity/safeguard';
// On your callback page, call this first:
handlePkceCallback();
// On your main page:
const client = new SafeguardClient('safeguard.sample.corp', {
auth: new PkceAuth({ redirectUri: window.location.href }),
});
await client.connect(); // Redirects to Safeguard login if no stored tokens
const me = await client.get(Service.CORE, 'Me');
console.log(me);For automated scenarios where no browser is available (CI/CD, scripts):
import { SafeguardClient, PkceNonInteractiveAuth, Service } from '@oneidentity/safeguard';
const client = new SafeguardClient('safeguard.sample.corp', {
auth: new PkceNonInteractiveAuth({
username: 'Admin',
password: 'Admin123',
provider: 'Local',
}),
});
await client.connect();
const me = await client.get(Service.CORE, 'Me');
await client.disconnect();import { SafeguardClient, CertificateAuth, Service } from '@oneidentity/safeguard';
const client = new SafeguardClient('safeguard.sample.corp', {
auth: new CertificateAuth({
certFile: '/path/to/client.pem',
keyFile: '/path/to/client.key',
passphrase: 'optional-key-passphrase',
}),
});
await client.connect();
const me = await client.get(Service.CORE, 'Me');
await client.disconnect();import { SafeguardClient, AnonymousAuth, Service } from '@oneidentity/safeguard';
const client = new SafeguardClient('safeguard.sample.corp', {
auth: new AnonymousAuth(),
});
await client.connect();
const status = await client.get(Service.NOTIFICATION, 'Status');
console.log(status);import { SafeguardClient, TokenAuth, Service } from '@oneidentity/safeguard';
const client = new SafeguardClient('safeguard.sample.corp', {
auth: new TokenAuth({ accessToken: 'your-token-here' }),
});
await client.connect();
const me = await client.get(Service.CORE, 'Me');The client provides typed HTTP methods. Pass relative paths only — the SDK prepends the configured API version automatically (v4 by default):
// GET
const users = await client.get(Service.CORE, 'Users');
// GET with query parameters
const filtered = await client.get(Service.CORE, 'Users', {
query: { filter: "Name eq 'Admin'", fields: 'Id,Name' },
});
// POST (create)
const newUser = await client.post(Service.CORE, 'Users', {
json: { Name: 'newuser', PrimaryAuthenticationProvider: { Id: -1 } },
});
// PUT (update)
await client.put(Service.CORE, `Users/${newUser.Id}/Password`, {
json: 'NewPassword123',
});
// DELETE
await client.delete(Service.CORE, `Users/${newUser.Id}`);| Service | Description |
|---|---|
Service.CORE |
Most product functionality — access requests, asset management, policy, users |
Service.APPLIANCE |
Appliance-specific operations — IP address, maintenance, backups |
Service.NOTIFICATION |
Anonymous/unauthenticated — status, availability |
Service.A2A |
Application integration — credential retrieval, access request brokering |
import { A2AClient, CertificateAuth } from '@oneidentity/safeguard';
const a2a = new A2AClient('safeguard.sample.corp', {
auth: new CertificateAuth({
certFile: 'client.pem',
keyFile: 'client.key',
}),
});
// Retrieve a password
const password = await a2a.retrievePassword(apiKey);
// Retrieve an SSH private key
const sshKey = await a2a.retrievePrivateKey(apiKey);
// Set a password (write-back)
await a2a.setPassword(apiKey, 'NewPassword123');
// Discover retrievable accounts
const accounts = await a2a.getRetrievableAccounts();Real-time event support requires the optional @microsoft/signalr peer dependency:
npm install @microsoft/signalrEvent classes are imported from the @oneidentity/safeguard/events subpath:
import { SafeguardEventListener } from '@oneidentity/safeguard/events';
import { PasswordAuth, NodeHttpClient, MemoryStorage } from '@oneidentity/safeguard';
import * as signalR from '@microsoft/signalr';// Authenticate and build SignalR connection
const auth = new PasswordAuth({ username: 'Admin', password: 'Admin123', provider: 'Local' });
const httpClient = new NodeHttpClient();
const storage = new MemoryStorage();
const tokenSet = await auth.authenticate('safeguard.sample.corp', httpClient, storage);
const connection = new signalR.HubConnectionBuilder()
.withUrl(`https://safeguard.sample.corp/service/event/signalr`, {
accessTokenFactory: () => tokenSet.accessToken.expose(),
})
.withAutomaticReconnect()
.build();
const listener = new SafeguardEventListener(connection);
listener.on('NotifyEventAsync', (event) => {
console.log('Event received:', event);
});
await listener.start();For long-running processes that need to survive network interruptions and token expiration:
import { PersistentSafeguardEventListener } from '@oneidentity/safeguard/events';
const listener = new PersistentSafeguardEventListener(
connection, auth, 'safeguard.sample.corp', httpClient, storage,
);
listener.onStateChange((state) => {
console.log('State:', state);
});
listener.on('NotifyEventAsync', (event) => {
console.log('Event:', event);
});
await listener.start();The persistent listener automatically checks token lifetime and refreshes credentials before they expire (with a 60-second safety margin).
The SDK stores access tokens in memory only. Tokens do not survive a page refresh, which is the secure default for single-page applications without a backend-for-frontend (BFF).
If your application requires persistence across page reloads, you may explicitly store the token yourself — but be aware this exposes the token to cross-site scripting (XSS) attacks:
await client.connect();
// ⚠️ Customer explicitly accepts the XSS risk:
sessionStorage.setItem('my_token', client.accessToken.expose());For high-security environments, prefer in-memory tokens with re-authentication on refresh, or implement a BFF pattern where tokens never reach the browser.
Credentials and access tokens are wrapped in SecretValue, a class that
redacts content from toString(), toJSON(), and console.log() output.
This prevents accidental logging of secrets.
To retrieve the raw string value (e.g., for HTTP headers or storage), call
.expose():
const tokenSet = await auth.authenticate(host, httpClient, storage);
const raw: string = tokenSet.accessToken.expose(); // explicit opt-inTLS certificate verification is enabled by default in this SDK. The
Node-side NodeHttpClient constructs an undici.Agent with
rejectUnauthorized: true, so connections to an appliance whose certificate
chain does not validate are refused at the TLS layer.
The correct way to talk to an appliance whose certificate is issued by a private / corporate CA is to provide the CA bundle to the SDK — not to disable verification:
import { readFileSync } from 'node:fs';
import { SafeguardClient, NodeHttpClient, PasswordAuth } from '@oneidentity/safeguard';
const ca = readFileSync('/etc/ssl/corp-root-ca.pem');
const client = new SafeguardClient('safeguard.corp.example', {
auth: new PasswordAuth({ /* ... */ }),
});
client.setHttpClient(new NodeHttpClient({ ca, rejectUnauthorized: true }));
await client.connect();NodeHttpClient accepts a PEM string or Buffer (single cert or
concatenated bundle). Verification stays on; only the trust anchor changes.
For local appliances with self-signed certificates the supported opt-out is
the per-instance rejectUnauthorized: false flag on the HTTP client:
// Development only — never use in production
client.setHttpClient(new NodeHttpClient({ rejectUnauthorized: false }));This affects only this SafeguardClient instance.
Node.js honours the process-wide
NODE_TLS_REJECT_UNAUTHORIZED=0
environment variable at the TLS layer below undici. If that variable is
set when your program starts, all TLS verification in the entire Node
process is disabled — including this SDK's connections, and any other
HTTPS calls your application makes (telemetry, package mirrors, third-party
APIs, etc.). Node itself prints a one-time warning when the variable is
honoured.
This SDK deliberately does not override or unset this variable: it is a documented Node.js mechanism that operators sometimes set intentionally in CI or dev shells, and silently re-enabling verification from the library would be surprising. But you should be aware that:
- It is process-wide, not SDK-specific. Setting it to bypass a lab appliance also exposes every other outbound HTTPS call in the same process.
- It cannot be re-enabled per-connection from JavaScript once set — even
new NodeHttpClient({ rejectUnauthorized: true })is overridden by the env var. - It must not be set in production. Prefer the custom-CA approach above.
If you find NODE_TLS_REJECT_UNAUTHORIZED=0 in a deployment environment,
treat it as a finding to remediate, not as a working configuration.
The SafeguardClient constructor validates the host parameter to prevent
injection attacks. Only bare hostnames or IP addresses are accepted — URLs,
paths, ports, query strings, and whitespace are rejected with a
ConfigurationError.
client.getAccessTokenLifetimeRemaining() decodes the JWT exp claim
client-side. This is a convenience for scheduling token refresh — never use it
as an authorization decision. The server is the sole authority on token
validity.
The Safeguard API is a REST-based Web API. Safeguard API endpoints are called using HTTP operators and JSON requests and responses. The Safeguard API is documented using Swagger. You may use Swagger UI to call the API directly or to read the documentation about URLs, parameters, and payloads.
To access the Swagger UI use a browser to navigate to:
https://<address>/service/<service>/swagger
<address>= Safeguard network address<service>= Safeguard service to use
To access the Swagger OpenAPI specification:
https://<address>/service/<service>/swagger/v4/swagger.json
| Parameter | Example | Description |
|---|---|---|
filter |
filter=Name eq 'Admin' |
Filter results |
fields |
fields=Id,Name |
Select specific properties |
orderby |
orderby=Name or orderby=-Name |
Sort ascending/descending |
page |
page=0 |
Page number (0-based) |
limit |
limit=100 |
Results per page |
count |
count=true |
Include total count |
q |
q=admin |
Full-text search |
See MIGRATION.md for a complete guide to upgrading from the legacy JavaScript API to the v8.0 TypeScript SDK.
| Project | Language | Description |
|---|---|---|
| SafeguardDotNet | C# | .NET SDK |
| PySafeguard | Python | Python SDK |
| SafeguardJava | Java | Java SDK |
| safeguard-ps | PowerShell | PowerShell module |
| safeguard-bash | Bash | Bash utilities |