一键导入
api-patterns
Use when making Safeguard API calls, wiring auth strategies, or following SDK request and response patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when making Safeguard API calls, wiring auth strategies, or following SDK request and response patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Use when wiring certificate-based A2A retrieval, brokering, or related Safeguard event listeners in Node.js.
Use when changing module structure, auth internals, conditional exports, or the HTTP and storage layers.
Use when changing tsdown config, Azure Pipelines, publishing flow, or version derivation.
Use when working on Vitest configuration, appliance-backed tests, fixtures, or debugging test failures.
基于 SOC 职业分类
| name | api-patterns |
| description | Use when making Safeguard API calls, wiring auth strategies, or following SDK request and response patterns. |
| trigger | Making Safeguard API calls, SDK usage, understanding request/response patterns |
enum Service {
CORE = 'service/core',
APPLIANCE = 'service/appliance',
NOTIFICATION = 'service/notification',
A2A = 'service/a2a',
EVENT = 'service/event',
RSTS = 'RSTS',
}
https://{host}/{service}/v{apiVersion}/{relativeUrl}
4https://{host}/RSTS/oauth2/tokenAll implement the Auth interface:
interface Auth {
authenticate(host: string, httpClient: HttpClient): Promise<TokenSet>;
refreshToken?(host: string, httpClient: HttpClient): Promise<TokenSet>;
}
| Strategy | Environment | Use Case |
|---|---|---|
PasswordAuth | Node | Username/password → RSTS token |
CertificateAuth | Node only | Client cert mTLS → RSTS token |
PkceAuth | Browser | RSTS PKCE redirect flow |
PkceNonInteractiveAuth | Node | Local HTTP server + browser auto-open |
TokenAuth | Both | Pre-existing access token |
AnonymousAuth | Both | No credentials (limited API access) |
import { SafeguardClient, PasswordAuth, NodeHttpClient, Service, HttpMethod } from '@oneidentity/safeguard';
// 1. Create auth — `provider` is REQUIRED (e.g. 'Local', 'ad.example.com')
const auth = new PasswordAuth({ username: 'admin', password: 'secret', provider: 'Local' });
// 2. Create client
const client = new SafeguardClient('appliance.example.com', {
auth,
verify: false, // Only for lab/dev! Default: true
timeout: 300_000,
autoRefresh: true,
});
// 3. MUST set HttpClient before connect — platform-specific
client.setHttpClient(new NodeHttpClient({ rejectUnauthorized: false }));
// 4. Connect (authenticates)
await client.connect();
// Convenience verbs (typed)
const users = await client.get<User[]>(Service.CORE, 'Users');
const user = await client.post<User>(Service.CORE, 'Users', { json: body });
// Low-level invoke (full control)
const response = await client.invoke(Service.CORE, HttpMethod.GET, 'Me', {
fullResponse: true,
signal: controller.signal,
});
await client.disconnect();
Critical notes:
PasswordAuth requires provider — throws ConfigurationError if omittedclient.setHttpClient(...) MUST be called before connect() — throws otherwiseNodeHttpClient, browser uses BrowserHttpClientNodeHttpClient({ rejectUnauthorized: false }) disables TLS cert validationverify: false on the client is NOT sufficient to skip TLS; the HttpClient controls itThe SPP API uses its own query parameter names — NOT OData $-prefixed params.
Pass them as a flat Record<string, string | number | boolean>:
// filter, fields, orderby, page, count — no $ prefix
const users = await client.get<User[]>(Service.CORE, 'Users', {
query: { filter: 'Disabled eq false', fields: 'UserName,Name', orderby: 'UserName' }
});
filter — SPP filter expressions (e.g. Name contains "admin")fields — comma-separated field names to includeorderby — field name with optional asc/descpage / limit — paginationcount — include X-Total-Count header (boolean)The SDK passes these verbatim as URL query params. It does NOT transform them.
try {
await client.get(Service.CORE, 'Users/999999');
} catch (err) {
if (err instanceof NotFoundError) { /* 404 */ }
if (err instanceof AuthenticationError) { /* 401 — token expired? */ }
if (err instanceof TransportError) { /* network failure */ }
}
const a2a = new A2AClient('appliance.example.com', {
auth: new CertificateAuth({ certFile: 'cert.pem', keyFile: 'key.pem' }),
});
const password = await a2a.retrievePassword(apiKey);
await a2a.setPassword(apiKey, newPassword);
const accounts = await a2a.getRetrievableAccounts();
autoRefresh: true (default) → transparent re-authentication before expired requestsclient.getAccessTokenLifetimeRemaining() → seconds remainingclient.disconnect() → logout + clear stored tokens