Reference
Submit, track, cancel, and verify — the safe public contract.
@wisent-ai/weles-client is the public Node.js ESM library for forming authorized workflow requests and verifying signed receipts. It never runs a browser and never establishes permission for a target.
Install#
The package provides the JavaScript library and two credential executables: weles-skarbiec-acquire for hosted tasks and weles-skarbiec-acquire-admission for self-hosted credential operations. Node.js must support ESM and Fetch. Pin the exact source revision or immutable package archive used by a deployment.
git clone https://github.com/wisent-ai/weles-client
npm install --global ./weles-clientConstruct a client#
import { WelesClient } from '@wisent-ai/weles-client';
const client = new WelesClient({
endpoint: process.env.WELES_API_BASE,
bearer: process.env.WELES_TOKEN,
organizationId: process.env.WISENT_ORGANIZATION_ID,
allowedOrigins: ['https://console.example.com'],
allowedActions: ['export-approved-report'],
receiptKeys: {
'current-signing-key': process.env.WELES_RECEIPT_PUBLIC_KEY,
},
});| Option | Requirement |
|---|---|
endpoint | HTTPS URL; plaintext http is accepted only on a loopback host: localhost or the IPv4 or IPv6 loopback address. |
bearer | Organization-scoped token carrying only the required task create, read, and cancel scopes; kept in the calling backend. |
organizationId | Organization UUID; it must match the token's organization or the hosted API rejects the call. |
allowedOrigins | Non-empty exact origin allowlist. |
allowedActions | Non-empty exact action allowlist. |
receiptKeys | Map of trusted receipt key IDs to PEM public keys, distributed out-of-band. |
fetch | Optional Fetch implementation override. |
Submit, read, cancel#
- submit sends schema weles.task.current with organization ID, normalized origin, exact action, non-secret input, opaque credential refs, evidence policy, justification, Idempotency-Key, and bearer headers. If no key is supplied, the client generates a UUID.
- get performs an exact task-status read; there is no list or search surface.
- cancel submits one explicit cancellation with a required reason; the library never retries, and ambiguous transport outcomes surface as transport-failed.
const accepted = await client.submit({
origin: 'https://console.example.com',
action: 'export-approved-report',
input: { report: 'monthly' },
credentialRefs: ['customer-console-account'],
evidencePolicy: 'receipt',
justification: 'Export authorized by the account owner.',
}, { idempotencyKey: 'caller-retained-operation-id' });
const current = await client.get(accepted.taskId);
const cancelled = await client.cancel(taskId, {
reason: 'The account owner withdrew approval.',
idempotencyKey: 'caller-retained-cancellation-id',
});Verify a receipt offline#
Verification binds taskId, organizationId, origin, action, outcome, evidenceDigest, and the trusted keyId. Store the signed payload, signature, key ID, verified claims, and key-set version together. Obtain keys through a separately authenticated channel — never from the receipt itself.
import { verifyReceipt } from '@wisent-ai/weles-client';
const claims = verifyReceipt(receipt, {
'current-signing-key': process.env.WELES_RECEIPT_PUBLIC_KEY,
});Errors and redaction#
Every validation, transport, response, and receipt failure throws WelesClientError with a stable code. Non-2xx bodies are recursively redacted where object keys look sensitive; redaction inspects key names only, not free-form strings, so treat all service errors as potentially sensitive. The library never logs on its own.
Skarbiec credential bridge#
The hosted weles-skarbiec-acquire bridge uses organization authentication and its fixed provider contracts. The self-hosted weles-skarbiec-acquire-admission bridge uses a separate Skarbiec workload bearer and POST /api/v1/credential-operations. These authorities are not interchangeable.
- The API base resolves only from the Stado forward directory (STADO_FORWARDS_DIR, default ~/.stado/forwards), file weles-admission.local — exactly one line holding the URL. WELES_URL is removed: a missing file, symlink, loosened mode, foreign owner, extra lines, or non-loopback plaintext URL fails as needs_configuration with code WELES_ENDPOINT_UNRESOLVED, phase admission.
- Requests must use the fixed skarbiec.credential-operation.v3 schema; v1 and v2 are rejected with no alias.
- The hosted bridge supports submit, status, and approval-bound resume. The self-hosted bridge posts submit and status to the credential-operation service; status reads the persisted caller-bound request, not a fabricated queue response. Self-hosted resume is explicitly refused as WELES_CREDENTIAL_MODE_REFUSED.
- Skarbiec supplies each sealed directory identity. Both bridges reject inconsistent provider, directory presence or Entra password field with ENTRA_IDENTITY_CONTRACT_MISMATCH before contacting Weles. The client contains no account or tenant allowlist; task and receipt identities must still match the exact requested directory, and the executor's private declaration and grants authorize the account.
- The self-hosted caller requires audience weles and call:weles#credential-operations. Its owner-only bearer file defaults to ~/.stado/skarbiec-weles-credential-client-token; WELES_TOKEN_FILE selects another explicit file. Weles verifies each call with its own weles-credential-admission consumer and introspect:tokens grant.
- The hosted bridge requires explicit WELES_TOKEN and WISENT_ORGANIZATION_ID. Missing or invalid caller configuration returns WELES_CALLER_IDENTITY_UNRESOLVED in phase admission with providerEffect none, before any workflow submission. The hosted password writer must be exactly <item>-writer; a reader cannot substitute for it.
- The service checks the exact provider, item, field, writer and signup origin before queueing the existing acquisition workflow. Each provider writer has only its declared stage:item#field grant. This route does not use the Spis task bearer.
- Repeated request IDs cannot change their caller or operation. Interrupted execution is not replayed. Missing configuration names the failed operation and cause; ambiguous transport or execution keeps providerEffect unknown. A child exit code alone does not prove acquisition: Weles checks the matching capture acknowledgement, and Skarbiec separately checks the managed write.
- A run states what it did to the credential in one place: the credential_operation object of its service_action_result.json, carrying status, message and providerEffect (the Entra and Microsoft password runs write it). Weles answers with that statement and reads no other file or printed line for it; a statement without one of those members is refused as credential_operation_incomplete naming the file and member, and a file that is not JSON as credential_operation_unreadable. A run that states nothing is answered from what Weles observed: operation_completed with WELES_CREDENTIAL_CAPTURED only when the run exited cleanly and Skarbiec acknowledged the capture this request asked for, otherwise operation_failed with WELES_CREDENTIAL_RESULT_UNSTATED, whose message gives the exit and what the capture showed. A Microsoft password run that meets an identity approval it cannot resume states operation_failed with MICROSOFT_IDENTITY_APPROVAL_REQUIRED and keeps the page in pending_review.json.
- The bridge never accepts credential material on stdin nor returns credential or task payload material on stdout.
Deployment-owned password declarations#
A public Weles release contains no operator account catalog. The executor, and any local acquisition planner, read WELES_MANAGED_PASSWORD_CONTRACTS_FILE when resolving a managed password. Set it through the normal process environment to an absolute regular file owned by that process user, with no group or other permissions. It contains declarations, never credential values, and does not enable WELES_CREDENTIALS_FILE or bypass Skarbiec.
The file uses schema weles.managed-passwords.v1 and an accounts array. Each entry has exactly item and provider. Item identifiers are case-sensitive, contain 1–128 ASCII letters, digits, dots, underscores or hyphens, and begin with a letter or digit. Duplicate items, unknown properties, unsupported providers, unsafe files and collisions with an existing service credential contract are refused with the selected input and cause.
Use microsoft for a password owned by a consumer Microsoft account, including an account that is only a guest in a directory. Use microsoft_entra for a directory-owned password. These choices pin https://account.live.com and https://login.microsoftonline.com respectively. Neither the item name nor the requested provider can replace that declaration. A conflicting provider or an undeclared managed password is refused before queueing; an undeclared password never becomes a generic api_key acquisition.
- For item I, the contract permits field password, writer I-writer, writer token file I-writer-skarbiec-token and reader base I-reader. Existing owner-only token checks, exact stage:I#password authority, account binding, sealed directory coordinates and fresh-login verification still apply. A declaration grants no authority.
- The deployment's acquisition catalog must declare the exact reader row I-reader-password|I|password and its registered workload key. SKARBIEC_WELES_ACQUISITION_SCOPES_FILE selects the complete catalog, not an overlay; keep the required generic service and startup grants in it. Bootstrap, JavaScript and TypeScript readers all honor this selection. Tenant-specific reader catalogs keep their existing namespace; an Entra directory ID is not a Weles Skarbiec tenant ID.
- The shipped scope catalog contains generic service contracts only. Private account grants and account-holder identities belong to the deployment. Subscription sign-in continues to resolve the requested identity from Skarbiec; retired display-name aliases do not select another account.
- The authenticated credential-operation API applies these same checks to every caller, including graphical clients. No GUI or CLI caller can override a declared provider, field or writer. WELES_CREDENTIAL_CONTRACT_MISMATCH identifies an absent or conflicting declaration; an absent declaration reports whether WELES_MANAGED_PASSWORD_CONTRACTS_FILE is selected. Reader-field disagreement names the actual scope catalog and granted fields.
{
"schema": "weles.managed-passwords.v1",
"accounts": [
{"item": "example-consumer", "provider": "microsoft"},
{"item": "example-directory", "provider": "microsoft_entra"}
]
}Qualify declared passwords against real providers#
Use the existing canonical Skarbiec command, for example skarbiec credential verify example-consumer --consumer example-consumer-writer --as qualification-caller --token-file /absolute/owner-only-token. Then use skarbiec credential status example-consumer with the same --as and --token-file. The canonical vault supplies the account and provider; no password is passed in argv. A queued result, a grant, a valid declaration or a healthy executor is not successful provider verification.
The reusable Weles journey is node tests/credentials/managed-passwords.mjs --fixture /absolute/checkout/build/managed-password-fixture.json. The owner-only fixture designates dedicated real managed accounts and a Stado-selected dedicated Weles host. It contains dedicated: true, execution_host, skarbiec_binary (absolute), skarbiec_caller, skarbiec_token_file, weles_bearer_file and accounts. Include both providers with distinct item identifiers. Each account supplies item and provider; a consumer account supplies email, while an Entra account supplies directory with tenant_id, principal_object_id and account_upn. Bearer files are owner-only and carry the separate canonical Skarbiec and Weles credential-operation authorities.
The normal Stado service-directory connection and operator credential selector must already reach that dedicated worker. Its observed source revision must equal the committed checkout. The journey checks wrong writers, wrong origins and undeclared items against the real authenticated API, verifies that refused requests have no persisted admission, and confirms that those refusals leave the real credential revision and request unchanged.
Positive verification goes through the real Skarbiec CLI and provider, then reads persisted status, the matching Weles capture acknowledgement, its password field and origin, the execution host, and sealed Entra identity when applicable. Reports and supported recordings remain under build/real-tests/managed-passwords. The journey changes no password, declaration, grant, host configuration or operator account; it verifies only the dedicated fixture credentials and retains their managed verification state.
A pending provider operation is awaiting_observation, not passed. Continue with the same --fixture and --admission-report pointing to its retained report; this reads the admitted request without resubmitting it. Refused dependencies, unconfirmed capture, changed source or fixture, an unrelated request, or missing recordings cannot pass. No local browser, mock provider or local credential fallback qualifies this path.
Qualify both installed credential bridges#
In the weles-client checkout, run node tests/credentials/journey.mjs --fixture /absolute/checkout/.build/credentials.json on the real vault owner. Use a clean committed checkout and the normal Stado forward to a dedicated worker. The journey invokes each candidate bridge through SKARBIEC_WELES_CREDENTIAL_COMMAND only in its Skarbiec child process; real local credential verify creates the operation journal before provider work.
The owner-only fixture contains dedicated: true, vault_served_to_worker: true, vault_file, skarbiec_binary, execution_host, worker_revision, organization_id, hosted_bearer_file, admission_bearer_file, diagnostics_bearer_file and accounts. All file paths are absolute; vault and bearer inputs are owned regular owner-only files. The fixture vault must be the actual isolated vault served to the worker's Skarbiec authority, not a copy. Supply exactly two distinct managed items: a microsoft account with item, provider and email, and a microsoft_entra account with item, provider and directory containing tenant_id, principal_object_id and account_upn.
Both providers must complete through both bridges. Directory, password-field and writer refusals must leave the stored operation unchanged; a status request cannot claim another request's task. The journey checks actual provider capture, item, origin, execution host, persisted verification and sealed Entra receipt identity. It retains exact revisions, executable hashes, commands, exits, native responses and supported recordings privately under .build/credentials. It changes no password, grant, account declaration or host configuration.
Unsettled provider work exits 1 as awaiting_observation. Continue with the same fixture and --admission-report pointing to its retained report; no repeated submission is used. Missing evidence or refused dependencies cannot pass. Investigate a failed report before starting another run; an unfinished managed operation is never replaced.