@project-kessel/kessel-sdk
v3.8.0
Published
This is the official Node.js SDK for [Project Kessel](https://github.com/project-kessel), a system for unifying APIs and experiences with fine-grained authorization, common inventory, and CloudEvents.
Readme
Kessel SDK for Node.js
A TypeScript/JavaScript SDK for connecting to Kessel services using gRPC with a fluent client builder API.
Table of Contents
Installation
npm install @project-kessel/kessel-sdkIf you need OAuth 2.0 authentication (recommended for production), also install the optional peer dependency:
npm install oauth4webapiQuick Start
import { ClientBuilder } from "@project-kessel/kessel-sdk/kessel/inventory/v1beta2";
import { CheckRequest } from "@project-kessel/kessel-sdk/kessel/inventory/v1beta2/check_request";
import { SubjectReference } from "@project-kessel/kessel-sdk/kessel/inventory/v1beta2/subject_reference";
import { ResourceReference } from "@project-kessel/kessel-sdk/kessel/inventory/v1beta2/resource_reference";
// 1. Create a client using the builder
const client = new ClientBuilder("localhost:9000")
.insecure() // for local development only
.buildAsync(); // returns a promisified client (use .build() for callback-style)
// 2. Build your request
const request: CheckRequest = {
subject: {
resource: {
reporter: { type: "rbac" },
resourceId: "foobar",
resourceType: "principal",
},
},
object: {
reporter: { type: "rbac" },
resourceId: "1234",
resourceType: "workspace",
},
relation: "inventory_host_view",
};
// 3. Make the call
const response = await client.check(request);
console.log(response);Authentication
The SDK supports multiple authentication modes via the ClientBuilder fluent API:
Insecure (local development only)
const client = new ClientBuilder(target).insecure().buildAsync();No TLS, no auth. Cannot be combined with call credentials.
OAuth 2.0 Client Credentials (production)
import {
fetchOIDCDiscovery,
OAuth2ClientCredentials,
} from "@project-kessel/kessel-sdk/kessel/auth";
import { ClientBuilder } from "@project-kessel/kessel-sdk/kessel/inventory/v1beta2";
// Discover the token endpoint via OIDC
const discovery = await fetchOIDCDiscovery(
"https://sso.example.com/auth/realms/my-realm",
);
// Create OAuth credentials (tokens are cached and auto-refreshed)
const auth = new OAuth2ClientCredentials({
clientId: "my-client-id",
clientSecret: "my-client-secret",
tokenEndpoint: discovery.tokenEndpoint,
});
// Build the client
const client = new ClientBuilder("kessel.example.com:443")
.oauth2ClientAuthenticated(auth)
.buildAsync();Requires the oauth4webapi optional dependency. See the auth GUIDELINES.md for details on credential handling and TLS.
Custom / Unauthenticated
// TLS without auth
new ClientBuilder(target).unauthenticated().buildAsync();
// Custom call credentials
new ClientBuilder(target)
.authenticated(callCredentials, channelCredentials)
.buildAsync();Listing Workspaces
The listWorkspaces helper automatically paginates through all workspaces
a subject can access. Continuation tokens are handled internally.
import {
listWorkspaces,
principalSubject,
} from "@project-kessel/kessel-sdk/kessel/rbac/v2";
import type { StreamedListObjectsResponse } from "@project-kessel/kessel-sdk/kessel/inventory/v1beta2/streamed_list_objects_response";
// Lazy iteration (constant memory)
for await (const response of listWorkspaces(
client,
principalSubject("alice", "redhat"),
"viewer",
)) {
console.log(response.object?.resourceId);
}
// With consistency
for await (const response of listWorkspaces(
client,
principalSubject("alice", "redhat"),
"viewer",
{ consistency: { minimizeLatency: true } },
)) {
console.log(response.object?.resourceId);
}
// Materialise into an array
const all: StreamedListObjectsResponse[] = [];
for await (const response of listWorkspaces(
client,
principalSubject("alice", "redhat"),
"viewer",
)) {
all.push(response);
}See examples/rbac/list_workspaces.ts for a complete working example.
Examples
Check out the examples directory for working code samples. Scripts are defined in examples/package.json.
- Builder examples: Modern async/await patterns with the client builder API
- Vanilla examples: Traditional callback-style patterns
- Authentication examples: OAuth 2.0 client credentials setup and usage
- Streaming examples: Working with streaming APIs
- RBAC examples: Workspace listing and fetching
- Console examples: Red Hat identity principal helpers
Setup
cd examples
npm installRunning Examples
# Builder-style examples (async/await)
npm run builder:check
npm run builder:check_bulk
npm run builder:check_for_update
npm run builder:report_resource
npm run builder:delete_resource
npm run builder:streamed_list_objects
npm run builder:auth
# Vanilla examples (callback-style)
npm run vanilla:check
npm run vanilla:check_bulk
npm run vanilla:check_for_update
npm run vanilla:report_resource
npm run vanilla:delete_resource
npm run vanilla:streamed_list_objects
npm run vanilla:promisify
npm run vanilla:auth
# RBAC examples
npm run rbac:list_workspaces
npm run rbac:fetch_workspace
# Console examples
npm run console:console_principalNote: If you've made changes to the SDK source, run
npm run buildin the root directory before running examples, as the examples reference the local build.
Project Structure
src/
kessel/
auth/ # OAuth2 client credentials, OIDC discovery
grpc/ # gRPC call credentials helper
inventory/ # ClientBuilder base + per-version wiring
v1/ # Health service
v1beta2/ # Primary inventory API (generated stubs + hand-written index)
rbac/ # REST workspace helpers, resource/subject factories
promisify.ts # Proxy-based gRPC client promisification
examples/ # Integration examples (require a live server)Most .ts files in the inventory directories are auto-generated from upstream protobuf definitions and should not be hand-edited. See AGENTS.md for the full project structure, the distinction between generated and hand-written code, and directory-local GUIDELINES.md files for detailed conventions.
Development
Commands
| Command | Description |
| ------------------------ | ------------------------------------------------ |
| npm run build | Build CJS, ESM, and type declarations (parallel) |
| npm test | Run tests with Jest |
| npm run lint | Lint with ESLint (auto-fix) |
| npm run lint:check | Lint without auto-fix (CI) |
| npm run prettier | Format with Prettier (auto-fix) |
| npm run prettier:check | Format check without auto-fix (CI) |
CI
CI runs on every push/PR to main, testing Node 20, 22, and 24. All four checks must pass: lint, prettier, build, and test.
Releases
Releases are fully automated using semantic-release. Every push to main triggers a workflow that analyzes commit messages and publishes to npm if warranted. Release notes appear on the GitHub Release.
Commit Message Format
Use Conventional Commits to automatically trigger releases:
<type>(<scope>): <subject>
<body>
<footer>Types and version bumps:
feat:→ minor version (new feature)fix:→ patch version (bug fix)perf:/docs:/refactor:→ patch versionBREAKING CHANGE:in footer → major version
Examples:
# Patch: 3.7.1 → 3.7.2
git commit -m "fix: handle expired tokens in OAuth2 refresh flow"
# Minor: 3.7.1 → 3.8.0
git commit -m "feat: add support for bulk relationship queries"
# Major: 3.7.1 → 4.0.0
git commit -m "feat!: remove deprecated v1beta1 API
BREAKING CHANGE: The v1beta1 API has been removed. Migrate to v1beta2."When you merge a PR with conventional commits to main, the release workflow:
- Runs quality checks (lint, prettier, build, and test on Node 20/22/24)
- Determines the next version from commits
- Publishes to npm with provenance attestation
- Creates a GitHub release with notes and package tarball
The published package version is set at release time. package.json on main is not bumped by the release job (avoids pushing to the protected branch).
Need Help?
- Check the GitHub Issues
- Look at the examples directory
License
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
