Kessel SDK for Go
The official Go SDK for the Kessel inventory and authorization services. This SDK provides a type-safe gRPC client for managing resources, checking permissions, and interacting with RBAC workspaces.
Features
- gRPC client support -- High-performance gRPC communication via the unified
KesselInventoryService
- Type-safe API -- Generated from protobuf definitions at buf.build/project-kessel/inventory-api
- Fluent ClientBuilder -- Construct clients with a chainable builder pattern supporting insecure, TLS, and OAuth2 modes
- RBAC utilities -- REST workspace client and helper functions for RBAC resource/subject references
- OIDC discovery -- Built-in OAuth2 client credentials flow with automatic token caching
Installation
go get github.com/project-kessel/kessel-sdk-go
Quick Start
Insecure (local development)
package main
import (
"context"
"fmt"
"log"
"github.com/project-kessel/kessel-sdk-go/kessel/inventory/v1beta2"
)
func main() {
ctx := context.Background()
inventoryClient, conn, err := v1beta2.NewClientBuilder("localhost:9000").
Insecure().
Build()
if err != nil {
log.Fatal("Failed to create gRPC client:", err)
}
defer conn.Close()
response, err := inventoryClient.Check(ctx, &v1beta2.CheckRequest{
Object: &v1beta2.ResourceReference{
ResourceType: "host",
ResourceId: "server-123",
Reporter: &v1beta2.ReporterReference{Type: "HBI"},
},
Relation: "member",
Subject: &v1beta2.SubjectReference{
Resource: &v1beta2.ResourceReference{
ResourceType: "user",
ResourceId: "alice",
},
},
})
if err != nil {
log.Fatal("Check failed:", err)
}
fmt.Printf("Check result: %v\n", response.Allowed)
}
With OAuth2 authentication
inventoryClient, conn, err := v1beta2.NewClientBuilder(endpoint).
OAuth2ClientAuthenticated(&oauthCredentials, nil).
Build()
Or bring your own PerRPCCredentials:
inventoryClient, conn, err := v1beta2.NewClientBuilder(endpoint).
Authenticated(kesselgrpc.OAuth2CallCredentials(&oauthCredentials), nil).
Build()
See the examples section for complete working code.
ClientBuilder modes
| Method |
Transport |
Auth |
Use case |
.Insecure() |
Plaintext |
None |
Local development |
.Unauthenticated(tlsCreds) |
TLS |
None |
TLS without auth |
.Authenticated(perRPC, tlsCreds) |
TLS |
Custom PerRPCCredentials |
Bring-your-own auth |
.OAuth2ClientAuthenticated(creds, tlsCreds) |
TLS |
Built-in OAuth2 |
Client credentials flow |
Pass nil for tlsCreds to use the default TLS configuration.
Error Handling
The SDK uses standard gRPC status codes:
response, err := inventoryClient.Check(ctx, checkRequest)
if err != nil {
if st, ok := status.FromError(err); ok {
switch st.Code() {
case codes.Unavailable:
log.Fatal("Service unavailable:", err)
case codes.PermissionDenied:
log.Fatal("Permission denied:", err)
default:
log.Fatal("gRPC error:", err)
}
} else {
log.Fatal("Unknown error:", err)
}
}
Listing Workspaces
The ListWorkspaces helper automatically paginates through all workspaces
a subject can access. Continuation tokens are handled internally.
import (
v1beta2 "github.com/project-kessel/kessel-sdk-go/kessel/inventory/v1beta2"
v2 "github.com/project-kessel/kessel-sdk-go/kessel/rbac/v2"
)
// Lazy iteration (constant memory)
for resp, err := range v2.ListWorkspaces(ctx, client, subject, "viewer", "") {
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Object.GetResourceId())
}
// Materialise into a slice
var all []*v1beta2.StreamedListObjectsResponse
for resp, err := range v2.ListWorkspaces(ctx, client, subject, "viewer", "") {
if err != nil {
log.Fatal(err)
}
all = append(all, resp)
}
See examples/rbac/list_workspaces.go for a complete working example.
Project Structure
kessel/
auth/ # OAuth2 client credentials, OIDC discovery, AuthRequest interface
config/ # CompatibilityConfig with functional options (legacy)
grpc/ # OAuth2 PerRPCCredentials wrapper for gRPC
inventory/
internal/builder/ # Generic ClientBuilder[C] (Go generics)
v1/ # Generated: health service only (stable)
v1beta1/ # Generated: legacy per-resource-type services
v1beta2/ # Generated: unified API + hand-written client_builder.go
rbac/v2/ # Hand-written: REST workspace client + v1beta2 utility constructors
examples/
grpc/ # gRPC client examples (6 standalone binaries)
rbac/ # RBAC workspace examples (2 standalone binaries)
console/ # Console identity examples
.github/workflows/ # CI: lint, build-test, buf-generate
Generated vs. hand-written code: All *.pb.go and *_grpc.pb.go files under kessel/inventory/ are generated by buf generate and must not be edited. Hand-written logic lives in kessel/auth/, kessel/config/, kessel/grpc/, kessel/inventory/internal/builder/, kessel/inventory/v1beta2/client_builder.go, kessel/rbac/v2/, and examples/.
API Version
Always use v1beta2 for new code. It provides the unified KesselInventoryService with Check, CheckBulk, ReportResource, DeleteResource, and more. The v1beta1 package is legacy and v1 contains only health endpoints.
Development
Prerequisites
- Go 1.25 or later
- Docker or Podman (for linting)
- buf (for protobuf code generation)
Build, Test, and Lint
# Install dependencies
go mod download
# Run tests
make test
# Run tests with coverage report
make test-coverage
# Run linting (via Docker/Podman)
make lint
# Build all example binaries
make build
# Format code
make fmt
# Tidy modules
make mod-tidy
# Regenerate protobuf files from buf.build
make generate
Available Make Targets
| Target |
Description |
make test |
Run all tests (go test -v ./kessel/...) |
make test-coverage |
Run tests and generate coverage.html |
make lint |
Run golangci-lint via Docker/Podman |
make build |
Compile example binaries into bin/ |
make generate |
Regenerate protobuf files with buf generate |
make fmt |
Format Go code |
make mod-tidy |
Run go mod tidy |
make clean |
Remove build artifacts |
make help |
Display all available targets |
Examples
All examples are standalone package main binaries. Copy the .env.sample file to .env and fill in your values before running.
Inventory (gRPC)
RBAC (REST + gRPC)
Running examples
# Build all examples
make build
# Run an example
./bin/insecure-example
./bin/authenticated-example
./bin/oauth2client-authenticated-example
./bin/report-resource-example
./bin/delete-resource-example
./bin/check_bulk_example
./bin/fetch_workspace
./bin/list_workspaces
Further Documentation
| Document |
Description |
AGENTS.md |
Onboarding guide for AI agents -- architecture, conventions, and pitfalls |
kessel/auth/GUIDELINES.md |
OAuth2 client credentials, token caching, OIDC discovery |
kessel/rbac/v2/GUIDELINES.md |
REST workspace client, gRPC iterator, utility constructors |
kessel/inventory/internal/builder/GUIDELINES.md |
Generic ClientBuilder, auth modes, three-value return |
examples/GUIDELINES.md |
Example binary conventions, env config, error handling |
Release Instructions
This section provides step-by-step instructions for maintainers to release a new version of the Kessel SDK for Go.
Version Management
This project follows Semantic Versioning 2.0.0. Version numbers use the format MAJOR.MINOR.PATCH:
- MAJOR: Increment for incompatible API changes
- MINOR: Increment for backward-compatible functionality additions
- PATCH: Increment for backward-compatible bug fixes
Note: SDK versions across different languages (Ruby, Python, Go, etc.) do not need to be synchronized. Each language SDK can evolve independently based on its specific requirements and release schedule.
Prerequisites for Release
Release Process
- Determine the version
Check existing tags (e.g. on GitHub or locally after git fetch --tags), choose the next version using semantic versioning (see Version Management above), then set VERSION for the steps below:
export VERSION=X.Y.Z
echo "Releasing version: v${VERSION}"
- Update Dependencies (if needed)
# Regenerate gRPC code if there are updates to the Kessel Inventory API
make generate
- Run Quality Checks
# Run linting
make lint
# Run tests
make test
# Build examples
make build
- Commit and push (if needed)
If make generate or other changes produced diffs, commit and push them before tagging:
git add .
git commit -m "chore: regenerate protobuf code"
git push origin main
- Tag the Release
git tag -a v${VERSION} -m "Release version ${VERSION}"
git push origin v${VERSION}
- Create GitHub Release
gh release create v${VERSION} --title "v${VERSION}" --generate-notes
Or manually:
- Go to the GitHub Releases page
- Click "Create a new release"
- Select the tag you just created
- Add release notes describing the changes
- Publish the release
After the tag is published, users can install that version with:
go get github.com/project-kessel/kessel-sdk-go@v${VERSION}
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.