@gebsecure01/sdk 0.2.1
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/CHANGELOG.md +64 -0
- package/README.md +188 -0
- package/dist/index.cjs +1241 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2378 -0
- package/dist/index.d.ts +2378 -0
- package/dist/index.js +1218 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Changelog — @gebsecure01/sdk
|
|
2
|
+
|
|
3
|
+
All notable changes to the TypeScript SDK. Format: [Keep a Changelog](https://keepachangelog.com/);
|
|
4
|
+
versioning: [SemVer](https://semver.org/) as described in [`../VERSIONING.md`](../VERSIONING.md).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.2.1] - 2026-10-01
|
|
9
|
+
|
|
10
|
+
Compatible with GebSecure API `v1` (gateway/api OpenAPI 0.1.0), same servers as 0.2.0. Conformance suite:
|
|
11
|
+
fixtures v1 incl. `verbs.json`, `runtime.json`, `admin.json` (110 scenarios; `execute.json` APPR-004…APPR-010).
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- `executeWithApproval()` no longer races the server. After the approval was granted it executed a second time with the
|
|
15
|
+
approval id, while the platform worker (`execution-resume`) resumes the stored execution itself and consumes
|
|
16
|
+
the single-use approval, so the helper failed nondeterministically (`ApprovalNotGranted` with status
|
|
17
|
+
`consumed`, `conflict` "Approval has already been used", or 400 "Request violates a data constraint"). It
|
|
18
|
+
now waits for the approval and then polls `getExecution` until the execution is terminal, and returns that
|
|
19
|
+
result (`replayed` set, approval and risk from the first response); it never executes twice. A `consumed`
|
|
20
|
+
approval counts as granted. Rejected, expired and cancelled approvals raise `ApprovalNotGrantedError`; an approved
|
|
21
|
+
execution that has not finished by the deadline raises `TimeoutError` (code `timeout`, status 0); a resumed
|
|
22
|
+
execution that fails is returned with `status: 'failed'`. The signature is unchanged.
|
|
23
|
+
|
|
24
|
+
## [0.2.0] - 2026-09-30
|
|
25
|
+
|
|
26
|
+
Compatible with GebSecure API `v1` (gateway/api OpenAPI 0.1.0, including `/v1/inspect`, `/v1/dlp/scan`,
|
|
27
|
+
`/v1/traces/spans` and `/v1/simulations/run`). Conformance suite: fixtures v1 + `verbs`, `runtime`, `admin`.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- HTTP verbs `PUT`, `PATCH`, `DELETE`; per-call `idempotencyKey` option (sent as `Idempotency-Key`,
|
|
31
|
+
makes the call retryable); `204` responses resolve to `undefined`.
|
|
32
|
+
- Runtime: `inspect`, `dlpScan`, `reportSpans`, `buildSpan`, `traceparentOf`, `runSimulation` with
|
|
33
|
+
`SimulationFailedError` (carries the typed run) for `failOnMismatch`.
|
|
34
|
+
- Session auth for CLIs: `login` (refresh token in the body), `refreshSession`, `logout`, `me`, and the
|
|
35
|
+
`unauthenticated()` provider.
|
|
36
|
+
- Management wrappers: policies (versions, diff, tests incl. `PUT` replace, deploy with 412 deploy
|
|
37
|
+
reports returned as results, rollback, simulate), agents and credentials, secrets (write-only values),
|
|
38
|
+
connectors and connections (OAuth, client-credentials and JWT-bearer installs, health), audit
|
|
39
|
+
(search with `afterSeq` tailing, export, verify), approvals (details, decide with snapshot hash),
|
|
40
|
+
alerts, traces and session replay.
|
|
41
|
+
- Typed models for all of the above (generated from the OpenAPI documents + `sdks/spec/overlay.json`).
|
|
42
|
+
- Examples: `inspect-and-trace.ts`, `policy-as-code.ts`.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- Retry classification follows the HTTP method: `PUT`/`DELETE` are idempotent (except `updatePolicy`,
|
|
46
|
+
which appends a version); `PATCH` and other `POST`s retry on 5xx/network errors only with an
|
|
47
|
+
idempotency key.
|
|
48
|
+
|
|
49
|
+
## [0.1.0] - 2026-09-30
|
|
50
|
+
|
|
51
|
+
Compatible with GebSecure API `v1` (gateway/api OpenAPI 0.1.0). Conformance suite: fixtures v1.
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
- `GebSecure` client: `authorize`, `authorizeBatch`, `guard`, `execute`, `getExecution`,
|
|
55
|
+
`listExecutions`, `cancelExecution`, `getApproval`, `waitForApproval`, `executeWithApproval`,
|
|
56
|
+
`listAgents`, `getAgent`, `listPolicies`, `listApprovals`, `createDelegation`, `withDelegation`,
|
|
57
|
+
`getAccessToken`.
|
|
58
|
+
- Authentication: API keys, static tokens, client secret, `private_key_jwt` (EdDSA/ES256/RS256 via
|
|
59
|
+
WebCrypto; PEM, JWK, CryptoKey or custom signer), delegation token exchange; cached single-flight
|
|
60
|
+
tokens with early refresh and one-shot 401 re-authentication.
|
|
61
|
+
- Retries with equal-jitter exponential backoff, `Retry-After`, idempotency rules and automatic
|
|
62
|
+
idempotency keys for `execute`; AbortSignal cancellation; per-attempt timeouts.
|
|
63
|
+
- Typed errors mapped from RFC 9457 problem+json; W3C `traceparent` propagation.
|
|
64
|
+
- Models generated from `docs/openapi` + `sdks/spec/overlay.json`.
|
package/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# @gebsecure01/sdk — GebSecure TypeScript / JavaScript SDK
|
|
2
|
+
|
|
3
|
+
Official client for the GebSecure AI Agent Security & Governance Platform: authorize agent actions,
|
|
4
|
+
execute them through the secure runtime, handle human approvals and manage agents — with typed models,
|
|
5
|
+
automatic authentication, retries and typed errors.
|
|
6
|
+
|
|
7
|
+
- Runs on Node.js ≥ 20, Deno, Bun, Cloudflare Workers and other runtimes with `fetch` + WebCrypto.
|
|
8
|
+
- ESM and CommonJS builds with bundled type declarations; zero runtime dependencies.
|
|
9
|
+
- Behaviour is specified by the cross-SDK [conformance plan](../conformance/README.md) and identical to
|
|
10
|
+
the Python, Go, Java and .NET SDKs.
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install @gebsecure01/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { GebSecure } from '@gebsecure01/sdk';
|
|
20
|
+
|
|
21
|
+
const gs = new GebSecure({ apiKey: process.env.GEBSECURE_API_KEY });
|
|
22
|
+
|
|
23
|
+
const { allowed, decision } = await gs.guard('refunds:create', 'stripe:charge/ch_123', { amount: 250 });
|
|
24
|
+
if (allowed) {
|
|
25
|
+
// perform the action
|
|
26
|
+
} else if (decision.decision === 'APPROVAL_REQUIRED') {
|
|
27
|
+
console.log('Needs approval:', decision.approval?.url);
|
|
28
|
+
} else {
|
|
29
|
+
console.log('Denied:', decision.reason);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
| Option | Default | Notes |
|
|
36
|
+
| ------ | ------- | ----- |
|
|
37
|
+
| `gatewayUrl` | `GEBSECURE_GATEWAY_URL` or `https://gateway.gebsecure.dev` | Data plane: authorize, execute, executions, approval polling |
|
|
38
|
+
| `apiUrl` | `GEBSECURE_API_URL` or `https://api.gebsecure.dev` | Control plane and token endpoint |
|
|
39
|
+
| `auth` / `apiKey` | `GEBSECURE_API_KEY`, then `GEBSECURE_CLIENT_SECRET` | See below |
|
|
40
|
+
| `maxRetries` | `3` | `0` disables retries and automatic idempotency keys |
|
|
41
|
+
| `timeoutMs` | `30000` | Per attempt |
|
|
42
|
+
| `baseDelayMs` / `maxDelayMs` | `500` / `8000` | Equal-jitter exponential backoff |
|
|
43
|
+
| `maxRetryAfterMs` | `60000` | Longer `Retry-After` values are raised immediately |
|
|
44
|
+
| `fetch`, `clock`, `random` | globals | Injection points for tests and custom transports |
|
|
45
|
+
|
|
46
|
+
Every method takes `RequestOptions`: `{ signal, traceparent, timeoutMs, maxRetries, headers, idempotencyKey }`.
|
|
47
|
+
|
|
48
|
+
## Authentication
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { GebSecure, apiKey, clientSecret, privateKeyJwt, delegation, staticToken } from '@gebsecure01/sdk';
|
|
52
|
+
|
|
53
|
+
new GebSecure({ auth: apiKey('gsk_…') }); // server-side automation
|
|
54
|
+
new GebSecure({ auth: clientSecret({ clientSecret: 'gsa_…', scope: 'authorize execute' }) });
|
|
55
|
+
new GebSecure({ auth: privateKeyJwt({ credentialId: 'cred_…', privateKey: pemOrJwk }) }); // Ed25519, ES256, RS256
|
|
56
|
+
new GebSecure({ auth: delegation({ subjectToken: 'gsd_…', actor: clientSecret({ clientSecret: 'gsa_…' }) }) });
|
|
57
|
+
new GebSecure({ auth: staticToken(accessToken) });
|
|
58
|
+
new GebSecure({ auth: unauthenticated() }); // only login() / refreshSession()
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- OAuth tokens are cached and refreshed `min(60 s, expires_in/2)` before expiry; concurrent calls share a
|
|
62
|
+
single token request. A `401` with a cached token triggers one transparent re-authentication.
|
|
63
|
+
- `private_key_jwt` assertions (RFC 7523) are signed with WebCrypto: `iss = sub = kid = credentialId`,
|
|
64
|
+
`aud = {apiUrl}/v1/auth/token` (override with `audience`), 60 s lifetime (≤ 300), unique `jti` per
|
|
65
|
+
attempt. Keys: PKCS#8 PEM, private JWK, a `CryptoKey`, or a custom `signer` (KMS/HSM).
|
|
66
|
+
- `gs.withDelegation(gsdToken)` returns a client that exchanges the delegation token using the current
|
|
67
|
+
client's credentials as the actor.
|
|
68
|
+
|
|
69
|
+
### User sessions (CLIs, CI)
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const session = await new GebSecure({ auth: unauthenticated() }).login({ email, password });
|
|
73
|
+
// session.refreshToken is returned in the body (refreshTokenDelivery: 'body'); store it securely.
|
|
74
|
+
const gs = new GebSecure({ auth: staticToken(session.accessToken) });
|
|
75
|
+
const me = await gs.me();
|
|
76
|
+
const next = await new GebSecure({ auth: unauthenticated() }).refreshSession(session.refreshToken!); // rotates: store next.refreshToken
|
|
77
|
+
await gs.logout();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`refreshSession` is never retried on 5xx/network errors (a replayed refresh token revokes the session
|
|
81
|
+
family). Passwords, refresh tokens and secret values are never logged or included in error messages.
|
|
82
|
+
|
|
83
|
+
## Operations
|
|
84
|
+
|
|
85
|
+
| Method | Endpoint |
|
|
86
|
+
| ------ | -------- |
|
|
87
|
+
| `authorize(req)` / `authorizeBatch(req)` | `POST {gateway}/v1/authorize[/batch]` |
|
|
88
|
+
| `guard(action, resource, context?)` | `authorize` → `{ allowed, decision }` |
|
|
89
|
+
| `execute(req)` | `POST {gateway}/v1/execute` → `ExecuteResult` (denied/failed are results) |
|
|
90
|
+
| `getExecution(id)` / `listExecutions()` / `cancelExecution(id)` | `{gateway}/v1/executions…` |
|
|
91
|
+
| `getApproval(id)` / `waitForApproval(id, { timeoutMs, pollIntervalMs })` | `GET {gateway}/v1/approvals/{id}` |
|
|
92
|
+
| `executeWithApproval(req, { timeoutMs, pollIntervalMs })` | execute → wait for approval → poll the execution the server resumes (never re-executes) |
|
|
93
|
+
| `listAgents()` / `getAgent(id)` / `listPolicies()` / `listApprovals()` | `{api}/v1/…` |
|
|
94
|
+
| `createDelegation(req)` | `POST {api}/v1/delegations` |
|
|
95
|
+
| `getAccessToken()` | current access token for APIs not wrapped by the SDK |
|
|
96
|
+
|
|
97
|
+
### Runtime protection (agents)
|
|
98
|
+
|
|
99
|
+
| Method | Endpoint |
|
|
100
|
+
| ------ | -------- |
|
|
101
|
+
| `inspect({ content, source, origin?, dlp? })` | `POST {gateway}/v1/inspect` → `InspectResult`: injection `score`/`level`/`action`/`findings`, sanitized `content` (null when blocked), inbound `dlp` |
|
|
102
|
+
| `dlpScan({ content, direction, dryRun? })` | `POST {gateway}/v1/dlp/scan` → `DlpScanResult` (masked findings, transformed content) |
|
|
103
|
+
| `reportSpans(spans)` + `buildSpan()` / `traceparentOf()` | `POST {gateway}/v1/traces/spans` — agent spans joined to the platform trace |
|
|
104
|
+
| `runSimulation(req)` | `POST {api}/v1/simulations/run` → `SimulationRun`; `failOnMismatch: true` throws `SimulationFailedError` with `run` |
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const traceparent = '00-<trace id>-<span id>-01'; // your current trace
|
|
108
|
+
const r = await gs.inspect({ content: webPage, source: 'web', origin: url }, { traceparent });
|
|
109
|
+
if (r.action === 'BLOCK') throw new Error(`injection ${r.injection.level}`);
|
|
110
|
+
const span = buildSpan('llm.plan', startedAt, Date.now(), { traceparent, attributes: { model: 'x' } });
|
|
111
|
+
await gs.authorize({ action, resource }, { traceparent: traceparentOf(span) }); // child of the agent span
|
|
112
|
+
await gs.reportSpans([span]);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Management (control plane)
|
|
116
|
+
|
|
117
|
+
| Area | Methods |
|
|
118
|
+
| ---- | ------- |
|
|
119
|
+
| Session | `login`, `refreshSession`, `logout`, `me` |
|
|
120
|
+
| Policies | `listPolicies`, `getPolicy`, `createPolicy`, `updatePolicy` (PUT, new version), `deletePolicy`, `validatePolicy`, `getPolicyVersion`, `diffPolicyVersions`, `listPolicyDeployments`, `deployPolicy` (a 412 deploy report returns `deployed: false`), `rollbackPolicy`, `addPolicyTest`, `replacePolicyTests` (PUT), `deletePolicyTest`, `runPolicyTests`, `simulatePolicies` |
|
|
121
|
+
| Agents | `createAgent`, `listAgents`, `getAgent`, `updateAgent`, `setAgentStatus`, `deleteAgent`, `listAgentCredentials`, `createAgentCredential`, `rotateCredential`, `revokeCredential` |
|
|
122
|
+
| Secrets | `createSecret`, `listSecrets`, `getSecret`, `updateSecret`, `rotateSecret`, `revokeSecret`, `deleteSecret` — values are write-only |
|
|
123
|
+
| Connectors | `listConnectors`, `getConnector`, `listConnections`, `getConnection`, `createConnection`, `updateConnection`, `deleteConnection`, `checkConnectionHealth`, `startConnectionOAuth`, `completeConnectionOAuth`, `installClientCredentials`, `installJwtBearer` |
|
|
124
|
+
| Audit | `searchAudit` (`afterSeq` tails new events oldest-first), `getAuditEvent`, `exportAudit` (raw ndjson/csv/json), `verifyAudit` |
|
|
125
|
+
| Approvals | `listApprovals`, `getApprovalDetails`, `decideApproval` (with the reviewed `snapshotHash`) |
|
|
126
|
+
| Alerts | `listAlerts`, `getAlert`, `updateAlert` |
|
|
127
|
+
| Traces | `searchTraces`, `getTrace`, `replaySession` |
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
// Tail the audit log
|
|
131
|
+
let after = (await gs.searchAudit({ limit: 1 })).data[0]?.seq ?? 0;
|
|
132
|
+
for (;;) {
|
|
133
|
+
const page = await gs.searchAudit({ afterSeq: after, limit: 500 });
|
|
134
|
+
for (const e of page.data) console.log(e.seq, e.action, e.outcome);
|
|
135
|
+
after = page.data.at(-1)?.seq ?? after;
|
|
136
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Retries and idempotency
|
|
141
|
+
|
|
142
|
+
- `429` is retried for every request (honouring `Retry-After`); `502/503/504`, network errors and
|
|
143
|
+
timeouts are retried only for idempotent requests: GETs, PUTs and DELETEs (except `updatePolicy`, which
|
|
144
|
+
appends a version), token requests, `dryRun` authorizations and DLP scans, span reports, cancels,
|
|
145
|
+
evaluation-only calls (validate/simulate/test runs/audit verify/health checks), and `execute` with an
|
|
146
|
+
`idempotencyKey`.
|
|
147
|
+
- PATCH and other POSTs are retried on 5xx/network errors only when you pass
|
|
148
|
+
`{ idempotencyKey }` (sent as the `Idempotency-Key` header) — you assert the call is safe to repeat.
|
|
149
|
+
- With retries enabled, `execute()` adds an `idempotencyKey` (`sdk-<uuid>`) when you don't pass one, so
|
|
150
|
+
a retried execution never runs twice. `executeWithApproval()` always uses one.
|
|
151
|
+
- A `502/504` whose body is an `ExecuteResult` (the connector failed) is returned, not retried.
|
|
152
|
+
- Cancel any call with an `AbortSignal`; in-flight requests and backoff sleeps stop immediately.
|
|
153
|
+
|
|
154
|
+
## Errors
|
|
155
|
+
|
|
156
|
+
All errors extend `GebSecureError` and expose `status`, `code`, `detail`, `requestId`, `traceId`,
|
|
157
|
+
`details` and `type`:
|
|
158
|
+
|
|
159
|
+
`AuthenticationError`, `PermissionDeniedError`, `PolicyDeniedError`, `ApprovalRequiredError`,
|
|
160
|
+
`ValidationError`, `RateLimitError` (`retryAfterMs`), `NotFoundError`, `ConflictError`, `UpstreamError`,
|
|
161
|
+
`TimeoutError`, `UnavailableError`, `InternalError`, `ApiError` (other codes), `ConnectionError`,
|
|
162
|
+
`ApprovalTimeoutError`, `ApprovalNotGrantedError`, `SimulationFailedError` (`run`), `ConfigurationError`.
|
|
163
|
+
|
|
164
|
+
## Tracing
|
|
165
|
+
|
|
166
|
+
Each call sends a W3C `traceparent`; pass `{ traceparent }` to join your current trace. Retries keep the
|
|
167
|
+
trace id. Errors carry the server's `requestId` and `traceId`. Agents report their own spans with
|
|
168
|
+
`reportSpans()`; `buildSpan(name, start, end, { traceparent })` creates a child of the current span and
|
|
169
|
+
`traceparentOf(span)` propagates it to subsequent calls.
|
|
170
|
+
|
|
171
|
+
## Examples
|
|
172
|
+
|
|
173
|
+
See [`examples/`](./examples): authorize-then-act, execute with approval, private_key_jwt,
|
|
174
|
+
delegation exchange, inspect-and-trace (inspection + agent spans), policy-as-code (session login, tests,
|
|
175
|
+
simulation gate, deploy).
|
|
176
|
+
|
|
177
|
+
## Development
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
npm install # from the repository root
|
|
181
|
+
npm run test -w @gebsecure01/sdk # unit + conformance tests (vitest)
|
|
182
|
+
npm run build -w @gebsecure01/sdk # dist/: ESM, CJS, .d.ts
|
|
183
|
+
GEBSECURE_LIVE_TEST=1 GEBSECURE_CLIENT_SECRET=gsa_… GEBSECURE_ENVIRONMENT_ID=env_… \
|
|
184
|
+
GEBSECURE_LIVE_EMAIL=… GEBSECURE_LIVE_PASSWORD=… npm run test -w @gebsecure01/sdk # optional live tests (conformance §9)
|
|
185
|
+
node sdks/scripts/generate-models.mjs # regenerate src/generated/models.ts from the OpenAPI specs
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Versioning and releases: see [`../VERSIONING.md`](../VERSIONING.md) and [`CHANGELOG.md`](./CHANGELOG.md).
|