@oneidentity/safeguard 1.0.5 → 8.0.0-pre36948
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +408 -279
- package/dist/browser-C_ziogDF.d.ts +447 -0
- package/dist/browser-C_ziogDF.d.ts.map +1 -0
- package/dist/browser.d.ts +447 -0
- package/dist/browser.js +756 -0
- package/dist/browser.js.map +1 -0
- package/dist/events-RcqBZBsR.d.ts +185 -0
- package/dist/events-RcqBZBsR.d.ts.map +1 -0
- package/dist/events-zHsrmRBj.d.cts +185 -0
- package/dist/events-zHsrmRBj.d.cts.map +1 -0
- package/dist/events.cjs +190 -0
- package/dist/events.cjs.map +1 -0
- package/dist/events.d.cts +166 -0
- package/dist/events.d.ts +166 -0
- package/dist/events.js +188 -0
- package/dist/events.js.map +1 -0
- package/dist/index-BN3IescB.d.cts +668 -0
- package/dist/index-BN3IescB.d.cts.map +1 -0
- package/dist/index-ir5Qeequ.d.ts +668 -0
- package/dist/index-ir5Qeequ.d.ts.map +1 -0
- package/dist/index.cjs +1248 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +668 -0
- package/dist/index.d.ts +668 -0
- package/dist/index.js +1215 -0
- package/dist/index.js.map +1 -0
- package/package.json +100 -44
- package/src/LocalStorage.js +0 -72
- package/src/README.md +0 -67
- package/src/SessionStorage.js +0 -90
- package/src/safeguard.js +0 -872
- package/src/safeguard.min.js +0 -1
- package/src/safeguardJsAccessTokenChecker.js +0 -44
- package/src/safeguardJsAccessTokenChecker.min.js +0 -1
package/README.md
CHANGED
|
@@ -1,279 +1,408 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
```
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
1
|
+
[](https://www.npmjs.com/package/@oneidentity/safeguard)
|
|
2
|
+
[](https://github.com/OneIdentity/safeguard.js/blob/main/LICENSE)
|
|
3
|
+
|
|
4
|
+
# safeguard.js
|
|
5
|
+
|
|
6
|
+
One Identity Safeguard JavaScript/TypeScript SDK
|
|
7
|
+
|
|
8
|
+
-----------
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<i>Check out our <a href="samples">sample projects</a> to get started with your own custom integration to Safeguard!</i>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
-----------
|
|
15
|
+
|
|
16
|
+
## Support
|
|
17
|
+
|
|
18
|
+
One Identity open source projects are supported through [One Identity GitHub issues](https://github.com/OneIdentity/safeguard.js/issues) and the [One Identity Community](https://www.oneidentity.com/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](https://github.com/OneIdentity/safeguard.js/issues) page. You may also visit the [One Identity Community](https://www.oneidentity.com/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.
|
|
19
|
+
|
|
20
|
+
## Introduction
|
|
21
|
+
|
|
22
|
+
All functionality in Safeguard is available via the Safeguard API. There is
|
|
23
|
+
nothing that can be done in the Safeguard UI that cannot also be performed
|
|
24
|
+
using the Safeguard API programmatically.
|
|
25
|
+
|
|
26
|
+
safeguard.js is provided to facilitate calling the Safeguard API from
|
|
27
|
+
JavaScript and TypeScript. It is meant to remove the complexity of dealing
|
|
28
|
+
with authentication via Safeguard's embedded secure token service (STS). The
|
|
29
|
+
basic usage is to create a `SafeguardClient` with your chosen authentication
|
|
30
|
+
strategy, call `connect()`, then call API methods using the same authenticated
|
|
31
|
+
client.
|
|
32
|
+
|
|
33
|
+
safeguard.js also provides an easy way to call Safeguard A2A from JavaScript.
|
|
34
|
+
The A2A service requires client certificate authentication for retrieving
|
|
35
|
+
passwords for application integration. When Safeguard A2A is properly
|
|
36
|
+
configured, specified passwords can be retrieved with a single method call
|
|
37
|
+
without requiring access request workflow approvals.
|
|
38
|
+
|
|
39
|
+
safeguard.js includes an SDK for listening to Safeguard's powerful, real-time
|
|
40
|
+
event notification system. Safeguard provides role-based event notifications
|
|
41
|
+
via SignalR to subscribed clients. The `PersistentSafeguardEventListener`
|
|
42
|
+
provides automatic reconnection with token refresh for long-running listeners.
|
|
43
|
+
|
|
44
|
+
### Features
|
|
45
|
+
|
|
46
|
+
- **TypeScript-first** with full type declarations
|
|
47
|
+
- **Dual ESM/CJS** — works with `import` and `require()`
|
|
48
|
+
- **Node.js and Browser** support
|
|
49
|
+
- **Multiple auth strategies** — Password, Certificate, PKCE (browser), PKCE Non-Interactive (headless), Token, Anonymous
|
|
50
|
+
- **A2A client** — retrieve/set passwords, SSH keys, API key secrets, broker access requests
|
|
51
|
+
- **SignalR events** — one-shot and persistent event listeners with auto-reconnect
|
|
52
|
+
- **Secure by default** — TLS verification enabled, no secrets in memory longer than needed
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install @oneidentity/safeguard
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Requires Node.js 20 or later.
|
|
61
|
+
|
|
62
|
+
## Getting Started
|
|
63
|
+
|
|
64
|
+
### Password Authentication (Node.js)
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { SafeguardClient, PasswordAuth, Service } from '@oneidentity/safeguard';
|
|
68
|
+
|
|
69
|
+
const client = new SafeguardClient('safeguard.sample.corp', {
|
|
70
|
+
auth: new PasswordAuth({
|
|
71
|
+
username: 'Admin',
|
|
72
|
+
password: 'Admin123',
|
|
73
|
+
provider: 'Local',
|
|
74
|
+
}),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await client.connect();
|
|
78
|
+
|
|
79
|
+
const me = await client.get(Service.CORE, 'v4/Me');
|
|
80
|
+
console.log(me);
|
|
81
|
+
|
|
82
|
+
await client.disconnect();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### PKCE Authentication (Browser)
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { SafeguardClient, PkceAuth, handlePkceCallback, Service } from '@oneidentity/safeguard';
|
|
89
|
+
|
|
90
|
+
// On your callback page, call this first:
|
|
91
|
+
handlePkceCallback();
|
|
92
|
+
|
|
93
|
+
// On your main page:
|
|
94
|
+
const client = new SafeguardClient('safeguard.sample.corp', {
|
|
95
|
+
auth: new PkceAuth({ redirectUri: window.location.href }),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await client.connect(); // Redirects to Safeguard login if no stored tokens
|
|
99
|
+
|
|
100
|
+
const me = await client.get(Service.CORE, 'v4/Me');
|
|
101
|
+
console.log(me);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### PKCE Non-Interactive (Headless Automation)
|
|
105
|
+
|
|
106
|
+
For automated scenarios where no browser is available (CI/CD, scripts):
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { SafeguardClient, PkceNonInteractiveAuth, Service } from '@oneidentity/safeguard';
|
|
110
|
+
|
|
111
|
+
const client = new SafeguardClient('safeguard.sample.corp', {
|
|
112
|
+
auth: new PkceNonInteractiveAuth({
|
|
113
|
+
username: 'Admin',
|
|
114
|
+
password: 'Admin123',
|
|
115
|
+
provider: 'Local',
|
|
116
|
+
}),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await client.connect();
|
|
120
|
+
const me = await client.get(Service.CORE, 'v4/Me');
|
|
121
|
+
await client.disconnect();
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Client Certificate Authentication
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { SafeguardClient, CertificateAuth, Service } from '@oneidentity/safeguard';
|
|
128
|
+
|
|
129
|
+
const client = new SafeguardClient('safeguard.sample.corp', {
|
|
130
|
+
auth: new CertificateAuth({
|
|
131
|
+
certFile: '/path/to/client.pem',
|
|
132
|
+
keyFile: '/path/to/client.key',
|
|
133
|
+
passphrase: 'optional-key-passphrase',
|
|
134
|
+
}),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
await client.connect();
|
|
138
|
+
const me = await client.get(Service.CORE, 'v4/Me');
|
|
139
|
+
await client.disconnect();
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Anonymous Access
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { SafeguardClient, AnonymousAuth, Service } from '@oneidentity/safeguard';
|
|
146
|
+
|
|
147
|
+
const client = new SafeguardClient('safeguard.sample.corp', {
|
|
148
|
+
auth: new AnonymousAuth(),
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
await client.connect();
|
|
152
|
+
const status = await client.get(Service.NOTIFICATION, 'v4/Status');
|
|
153
|
+
console.log(status);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Pre-existing API Token
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { SafeguardClient, TokenAuth, Service } from '@oneidentity/safeguard';
|
|
160
|
+
|
|
161
|
+
const client = new SafeguardClient('safeguard.sample.corp', {
|
|
162
|
+
auth: new TokenAuth({ accessToken: 'your-token-here' }),
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
await client.connect();
|
|
166
|
+
const me = await client.get(Service.CORE, 'v4/Me');
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Calling the API
|
|
170
|
+
|
|
171
|
+
The client provides typed HTTP methods:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// GET
|
|
175
|
+
const users = await client.get(Service.CORE, 'v4/Users');
|
|
176
|
+
|
|
177
|
+
// GET with query parameters
|
|
178
|
+
const filtered = await client.get(Service.CORE, 'v4/Users', {
|
|
179
|
+
query: { filter: "Name eq 'Admin'", fields: 'Id,Name' },
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// POST (create)
|
|
183
|
+
const newUser = await client.post(Service.CORE, 'v4/Users', {
|
|
184
|
+
json: { Name: 'newuser', PrimaryAuthenticationProvider: { Id: -1 } },
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// PUT (update)
|
|
188
|
+
await client.put(Service.CORE, `v4/Users/${newUser.Id}/Password`, {
|
|
189
|
+
json: 'NewPassword123',
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// DELETE
|
|
193
|
+
await client.delete(Service.CORE, `v4/Users/${newUser.Id}`);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Services
|
|
197
|
+
|
|
198
|
+
| Service | Description |
|
|
199
|
+
|---------|-------------|
|
|
200
|
+
| `Service.CORE` | Most product functionality — access requests, asset management, policy, users |
|
|
201
|
+
| `Service.APPLIANCE` | Appliance-specific operations — IP address, maintenance, backups |
|
|
202
|
+
| `Service.NOTIFICATION` | Anonymous/unauthenticated — status, availability |
|
|
203
|
+
| `Service.A2A` | Application integration — credential retrieval, access request brokering |
|
|
204
|
+
|
|
205
|
+
## A2A (Application to Application)
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { A2AClient, CertificateAuth } from '@oneidentity/safeguard';
|
|
209
|
+
|
|
210
|
+
const a2a = new A2AClient('safeguard.sample.corp', {
|
|
211
|
+
auth: new CertificateAuth({
|
|
212
|
+
certFile: 'client.pem',
|
|
213
|
+
keyFile: 'client.key',
|
|
214
|
+
}),
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Retrieve a password
|
|
218
|
+
const password = await a2a.retrievePassword(apiKey);
|
|
219
|
+
|
|
220
|
+
// Retrieve an SSH private key
|
|
221
|
+
const sshKey = await a2a.retrievePrivateKey(apiKey);
|
|
222
|
+
|
|
223
|
+
// Set a password (write-back)
|
|
224
|
+
await a2a.setPassword(apiKey, 'NewPassword123');
|
|
225
|
+
|
|
226
|
+
// Discover retrievable accounts
|
|
227
|
+
const accounts = await a2a.getRetrievableAccounts();
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Event Listeners (SignalR)
|
|
231
|
+
|
|
232
|
+
Real-time event support requires the optional `@microsoft/signalr` peer dependency:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm install @microsoft/signalr
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Event classes are imported from the `@oneidentity/safeguard/events` subpath:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import { SafeguardEventListener } from '@oneidentity/safeguard/events';
|
|
242
|
+
import { PasswordAuth, NodeHttpClient, MemoryStorage } from '@oneidentity/safeguard';
|
|
243
|
+
import * as signalR from '@microsoft/signalr';
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### One-Shot Listener
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
// Authenticate and build SignalR connection
|
|
250
|
+
const auth = new PasswordAuth({ username: 'Admin', password: 'Admin123', provider: 'Local' });
|
|
251
|
+
const httpClient = new NodeHttpClient();
|
|
252
|
+
const storage = new MemoryStorage();
|
|
253
|
+
const tokenSet = await auth.authenticate('safeguard.sample.corp', httpClient, storage);
|
|
254
|
+
|
|
255
|
+
const connection = new signalR.HubConnectionBuilder()
|
|
256
|
+
.withUrl(`https://safeguard.sample.corp/service/event/signalr`, {
|
|
257
|
+
accessTokenFactory: () => tokenSet.accessToken.expose(),
|
|
258
|
+
})
|
|
259
|
+
.withAutomaticReconnect()
|
|
260
|
+
.build();
|
|
261
|
+
|
|
262
|
+
const listener = new SafeguardEventListener(connection);
|
|
263
|
+
|
|
264
|
+
listener.on('NotifyEventAsync', (event) => {
|
|
265
|
+
console.log('Event received:', event);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
await listener.start();
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Persistent Listener (Auto-Reconnect)
|
|
272
|
+
|
|
273
|
+
For long-running processes that need to survive network interruptions and
|
|
274
|
+
token expiration:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { PersistentSafeguardEventListener } from '@oneidentity/safeguard/events';
|
|
278
|
+
|
|
279
|
+
const listener = new PersistentSafeguardEventListener(
|
|
280
|
+
connection, auth, 'safeguard.sample.corp', httpClient, storage,
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
listener.onStateChange((state) => {
|
|
284
|
+
console.log('State:', state);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
listener.on('NotifyEventAsync', (event) => {
|
|
288
|
+
console.log('Event:', event);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
await listener.start();
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The persistent listener automatically checks token lifetime and refreshes
|
|
295
|
+
credentials before they expire (with a 60-second safety margin).
|
|
296
|
+
|
|
297
|
+
## Security
|
|
298
|
+
|
|
299
|
+
### Token Storage (Browser)
|
|
300
|
+
|
|
301
|
+
The SDK stores access tokens **in memory only**. Tokens do not survive a page
|
|
302
|
+
refresh, which is the secure default for single-page applications without a
|
|
303
|
+
backend-for-frontend (BFF).
|
|
304
|
+
|
|
305
|
+
If your application requires persistence across page reloads, you may
|
|
306
|
+
explicitly store the token yourself — but be aware this exposes the token to
|
|
307
|
+
cross-site scripting (XSS) attacks:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
await client.connect();
|
|
311
|
+
// ⚠️ Customer explicitly accepts the XSS risk:
|
|
312
|
+
sessionStorage.setItem('my_token', client.accessToken.expose());
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
For high-security environments, prefer in-memory tokens with re-authentication
|
|
316
|
+
on refresh, or implement a BFF pattern where tokens never reach the browser.
|
|
317
|
+
|
|
318
|
+
### SecretValue
|
|
319
|
+
|
|
320
|
+
Credentials and access tokens are wrapped in `SecretValue`, a class that
|
|
321
|
+
redacts content from `toString()`, `toJSON()`, and `console.log()` output.
|
|
322
|
+
This prevents accidental logging of secrets.
|
|
323
|
+
|
|
324
|
+
To retrieve the raw string value (e.g., for HTTP headers or storage), call
|
|
325
|
+
`.expose()`:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
const tokenSet = await auth.authenticate(host, httpClient, storage);
|
|
329
|
+
const raw: string = tokenSet.accessToken.expose(); // explicit opt-in
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### TLS Verification
|
|
333
|
+
|
|
334
|
+
TLS certificate verification is **enabled by default** and should never be
|
|
335
|
+
disabled in production. For development environments with self-signed
|
|
336
|
+
certificates:
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
// Development only — never use in production
|
|
340
|
+
const client = new SafeguardClient('dev-appliance.local', {
|
|
341
|
+
auth: new PasswordAuth({ ... }),
|
|
342
|
+
verify: false,
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
For production with a custom CA:
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
const client = new SafeguardClient('safeguard.corp', { auth });
|
|
350
|
+
client.setHttpClient(new NodeHttpClient({ ca: '/path/to/ca-bundle.pem' }));
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Host Validation
|
|
354
|
+
|
|
355
|
+
The `SafeguardClient` constructor validates the `host` parameter to prevent
|
|
356
|
+
injection attacks. Only bare hostnames or IP addresses are accepted — URLs,
|
|
357
|
+
paths, ports, query strings, and whitespace are rejected with a
|
|
358
|
+
`ConfigurationError`.
|
|
359
|
+
|
|
360
|
+
### Token Lifetime
|
|
361
|
+
|
|
362
|
+
`client.getAccessTokenLifetimeRemaining()` decodes the JWT `exp` claim
|
|
363
|
+
client-side. This is a convenience for scheduling token refresh — never use it
|
|
364
|
+
as an authorization decision. The server is the sole authority on token
|
|
365
|
+
validity.
|
|
366
|
+
|
|
367
|
+
## About the Safeguard API
|
|
368
|
+
|
|
369
|
+
The Safeguard API is a REST-based Web API. Safeguard API endpoints are called
|
|
370
|
+
using HTTP operators and JSON requests and responses. The Safeguard API is
|
|
371
|
+
documented using Swagger. You may use Swagger UI to call the API directly or
|
|
372
|
+
to read the documentation about URLs, parameters, and payloads.
|
|
373
|
+
|
|
374
|
+
To access the Swagger UI use a browser to navigate to:
|
|
375
|
+
`https://<address>/service/<service>/swagger`
|
|
376
|
+
|
|
377
|
+
- `<address>` = Safeguard network address
|
|
378
|
+
- `<service>` = Safeguard service to use
|
|
379
|
+
|
|
380
|
+
To access the Swagger OpenAPI specification:
|
|
381
|
+
`https://<address>/service/<service>/swagger/v4/swagger.json`
|
|
382
|
+
|
|
383
|
+
### Query Parameters
|
|
384
|
+
|
|
385
|
+
| Parameter | Example | Description |
|
|
386
|
+
|-----------|---------|-------------|
|
|
387
|
+
| `filter` | `filter=Name eq 'Admin'` | Filter results |
|
|
388
|
+
| `fields` | `fields=Id,Name` | Select specific properties |
|
|
389
|
+
| `orderby` | `orderby=Name` or `orderby=-Name` | Sort ascending/descending |
|
|
390
|
+
| `page` | `page=0` | Page number (0-based) |
|
|
391
|
+
| `limit` | `limit=100` | Results per page |
|
|
392
|
+
| `count` | `count=true` | Include total count |
|
|
393
|
+
| `q` | `q=admin` | Full-text search |
|
|
394
|
+
|
|
395
|
+
## Migration from v7.x
|
|
396
|
+
|
|
397
|
+
See [MIGRATION.md](MIGRATION.md) for a complete guide to upgrading from the
|
|
398
|
+
legacy JavaScript API to the v8.0 TypeScript SDK.
|
|
399
|
+
|
|
400
|
+
## Related Projects
|
|
401
|
+
|
|
402
|
+
| Project | Language | Description |
|
|
403
|
+
|---------|----------|-------------|
|
|
404
|
+
| [SafeguardDotNet](https://github.com/OneIdentity/SafeguardDotNet) | C# | .NET SDK |
|
|
405
|
+
| [PySafeguard](https://github.com/OneIdentity/PySafeguard) | Python | Python SDK |
|
|
406
|
+
| [SafeguardJava](https://github.com/OneIdentity/SafeguardJava) | Java | Java SDK |
|
|
407
|
+
| [safeguard-ps](https://github.com/OneIdentity/safeguard-ps) | PowerShell | PowerShell module |
|
|
408
|
+
| [safeguard-bash](https://github.com/OneIdentity/safeguard-bash) | Bash | Bash utilities |
|