@brazosd/node
v0.1.2
Published
Brazosd Node.js SDK with automatic cloud function identity
Readme
Brazosd Node.js SDK
Node.js 22.13+ ESM client generated from Brazosd's OpenAPI schemas, with automatic cloud-function identity and no runtime dependencies.
Install the public npm package:
npm install @brazosd/nodeFor installations in mainland China, use the npm mirror:
npm install @brazosd/node --registry=https://registry.npmmirror.comInclude the installed runtime dependencies in your deployment package. Cloud
functions do not install packages during startup. To test local SDK changes,
run npm pack ./sdks/node and install the resulting archive instead.
import { createClient } from '@brazosd/node';
const brazosd = createClient();
const snapshots = await brazosd.api.listSnapshots();
const agents = await brazosd.api.listAgents({ limit: 20 });
const functions = await brazosd.serverless.listApps();
const organizations = await brazosd.anclax.listOrgs();Methods use OpenAPI operation IDs and a single options object when parameters are present. Request and response types come from the schema. The three API groups are:
| Property | Schema source | Base path |
| --- | --- | --- |
| api | api/openapi/v1/ | /api/v1 |
| serverless | app/serverless/api/openapi.yaml | /api/v1/serverless |
| anclax | The Anclax version pinned by go.mod | /api/v1 |
All declared operations are generated, including Cloud Drive, sessions, snapshots, agents, organization management, cloud functions and SQLite databases. Availability is still determined by the caller's existing permissions and the endpoint's credential requirements.
Cloud Drive
Cloud Drive uses the generated operations directly:
import { createHash } from 'node:crypto';
import { createClient } from '@brazosd/node';
const brazosd = createClient();
const directory = '@brazosd://org.drive/123/reports';
await brazosd.api.createCloudDriveDirectory({ requestBody: { path: directory } });
const path = `${directory}/today.json`;
const data = JSON.stringify({ visits: 42 });
await brazosd.api.uploadCloudDriveFile({
path,
sha256: createHash('sha256').update(data).digest('hex'),
formData: { file: new File([data], 'today.json', { type: 'application/json' }) },
overwrite: true,
});
const response = await brazosd.api.downloadCloudDrive({ path });
const report = await response.json();
const entries = await brazosd.api.getCloudDrive({ path: directory });Use your organization's numeric ID. getCloudDrive returns an array for a directory or a streaming Response for a file. downloadCloudDrive always returns a Response. Binary responses and declared download redirects remain streams; JSON responses are parsed. Download redirects never forward authentication headers or cookies to object storage. Writes are not redirected or retried.
For large uploads, use Node's openAsBlob to construct a file-backed File, and compute SHA-256 with createReadStream and createHash before uploading. The generated multipart transport accepts File/Blob, not filesystem paths. ifMatch accepts the current SHA-256 for optimistic concurrency. Other operations include statCloudDrive, copyCloudDrive, moveCloudDrive and deleteCloudDrive.
Authentication and permissions
Inside a cloud function, createClient() reads the access token and internal API URL from /run/brazosd/identity/credentials.json. The trusted runtime refreshes credentials and atomically replaces that file. Reads are coalesced and cached for at most one second, bounded by credential expiry. The SDK never reads a refresh token. Warm-pool instances have no user identity; credentials are absent from deployment packages and development snapshots.
A service user follows the same API authorization rules as other organization users. Enterprise service users start without grants; use existing user/group policies to grant API and resource access. Changes apply to subsequent API requests. Deactivating the service user or retiring the instance revokes access, including Anclax APIs. Creating a client does not grant permissions.
For development outside a function, supply your own authorized credential:
const client = createClient({
apiUrl: 'http://localhost:2910/api/v1',
credentials: async () => ({ accessToken: process.env.BRAZOSD_ACCESS_TOKEN }),
});Each client keeps its own URL, credential provider and request configuration. Concurrent clients do not share global authentication state. Public operations work without credentials when apiUrl is supplied. A schema-defined Authorization parameter, when present, takes precedence over the client's credential provider.
Sign in with Brazosd
SSO requires @brazosd/node 0.1.2 or later. createSSO() supports
org-user (same-organization user API credentials) and
identity (an identity JWT for users from any organization):
import { createSSO } from '@brazosd/node';
const sso = createSSO({
appId: process.env.BRAZOSD_APP_ID,
redirectUri: 'https://your-app.example/auth/brazosd/callback',
loginSecret: process.env.SSO_LOGIN_SECRET, // 32 random bytes as base64url
});
const { authorizationUrl, setCookie } = await sso.beginLogin('identity');
// Send setCookie, then redirect to authorizationUrl.
// On the registered callback:
// const { tokens, identity, clearCookie } = await sso.completeLogin(url, cookie);The SDK binds the browser transaction with an encrypted HttpOnly cookie, state
and PKCE. Service credentials remain on the app server. Store the verified
identity or user credentials in your own server session and send an opaque
session cookie to the browser. Identity JWTs contain account_id, org_id,
user_id and sub=String(account_id); (iss, sub) is the recommended identity
key. They cannot call Brazosd APIs or refresh API credentials.
sso.userClient({getTokens, saveTokens}) refreshes org-user credentials and
keeps each user's identity isolated. Shared session stores must compare-and-swap
updates using the expectedRefreshToken supplied to saveTokens. Call
sso.revoke(tokens) on logout and delete the app session. No failures fall back
to service-user permissions.
JWT verification uses strict issuer/audience/type/signature/expiry checks and
memory plus SQLite JWKS caching. The default cache is
~/.cache/brazosd-sso/jwks.sqlite; supply a SQLiteSSOKeyCache or SSOKeyCache
adapter for other storage. See the SSO integration guide
for callbacks, session lifecycle, private deployments and complete examples.
Install or update with npm install @brazosd/node@^0.1.2.
Errors and cancellation
API errors throw BrazosdError with status and a bounded response body. Handle permission errors, conflicts and throttling explicitly. Generated calls return a CancelablePromise: call .cancel() before completion to abort the HTTP request. Cancellation rejects with CancelError. A client-wide signal is also supported; cancel a returned stream through its Response.body.
const controller = new AbortController();
const client = createClient({ signal: controller.signal });
const pending = client.api.listSnapshots();
// Call pending.cancel() or controller.abort() when the operation is no longer needed.
const snapshots = await pending;
const rangedClient = createClient({ headers: { Range: 'bytes=0-1023' } });
const part = await rangedClient.api.downloadCloudDrive({ path: '@brazosd://org.drive/123/video.mp4' });Regeneration and validation
Releases use sdks/node/VERSION independently of the server version. Changing
that file on main triggers .github/workflows/publish-sdk.yaml, which tests
the SDK, publishes to npm, requests npmmirror synchronization, and verifies
installation from the mirror. Rerun a failed mirror synchronization with the same
version; changed package contents require a new version.
After the first npm publication, configure a GitHub Actions trusted publisher for
cloudcarver/brazosd, workflow publish-sdk.yaml, with direct publishing
allowed. The workflow uses OIDC and does not need an npm token. Run
node scripts/publish.mjs --dry-run in this directory to validate packaging
without publishing.
make gen-sdk-node
cd sdks/node
npm test
npm run typecheck
npm packGeneration uses openapi-typescript-codegen, the same generator as the web frontend, pinned to version 0.29.0. It requires the repository Anclax binary (.anclax/bin/anclax, overridable with ANCLAX), Go and Node.js. After npm ci, npm run generate also works directly in this directory.
Edit the OpenAPI sources and src/, then regenerate. The script bundles the core schema, reads the backend's pinned Anclax schema, generates independent clients and bundles index.js plus index.d.ts. Intermediate src/generated/ files are ignored. Only the public bundle, declarations and README are packaged. Do not edit generated artifacts directly. No service-specific authentication or manually maintained Cloud Drive methods are needed.
See workload identity for credential lifecycle and deployment configuration.
