🐛 Current behavior
Starting in v1.0.0, readStream and readAll were moved to the Rust native bridge (@kurrent/bridge) for performance. However, the bridge's credential interface (RustReadStreamOptions.credentials / RustReadAllOptions.credentials) only accepts { username: string; password: string }:
// @kurrent/bridge v0.1.3 — lib/index.d.ts
export type RustReadStreamOptions = {
// ...
credentials?: {
username: string;
password: string;
};
};
All other operations (append, delete, subscribe, persistent subscriptions) go through the gRPC path via callArguments(), which invokes createCredentialsMetadataGenerator. This allows consumers to override the credential generator for custom auth schemes (e.g., Bearer tokens via Azure RBAC / DefaultAzureCredential).
Read operations bypass this entirely, because they go through the Rust bridge which has no concept of Bearer tokens or custom metadata generators.
Any consumer using token-based auth (OAuth2 Bearer, Azure RBAC, custom metadata generators) cannot use readStream or readAll without workarounds. This affects:
- Azure-hosted KurrentDB deployments using Managed Identity /
DefaultAzureCredential
- Any integration using
createCredentialsMetadataGenerator override for custom auth
🔍 Steps to reproduce
import { KurrentDBClient } from '@kurrent/kurrentdb-client';
import { Metadata } from '@grpc/grpc-js';
import { DefaultAzureCredential } from '@azure/identity';
const client = KurrentDBClient.connectionString`kurrentdb+discover://host:2113?tls=true`;
const credential = new DefaultAzureCredential();
// Override credential generator for Bearer token auth
(client as any).createCredentialsMetadataGenerator = () => (_, cb) => {
credential.getToken('api://<app-id>/.default').then(({ token }) => {
const metadata = new Metadata();
metadata.add('authorization', `Bearer ${token}`);
cb(null, metadata);
});
};
// ✅ This works — goes through gRPC callArguments()
await client.appendToStream('my-stream', [event]);
// ❌ This FAILS with auth error — goes through Rust bridge, ignores Bearer token
for await (const event of client.readStream('my-stream')) {
console.log(event);
}
Reproducible link
https://gist.github.com/kochai/a9d13566e2c03d1452023bbe65e6718f
💭 Expected behavior
One of the following (in order of preference):
-
Add Bearer/token credential support to @kurrent/bridge — extend RustReadStreamOptions.credentials and RustReadAllOptions.credentials to accept a token or bearer field, and pass it as an Authorization: Bearer <token> header in the Rust gRPC calls.
-
Route reads through callArguments() when custom credentials are detected — if createCredentialsMetadataGenerator has been overridden on the client instance, fall back to the gRPC path for reads instead of the Rust bridge, so the custom metadata generator is invoked.
-
Expose a public API for custom credential providers — e.g., a credentialProvider option on the client that is respected by both the gRPC and Rust bridge paths.
Package version
@kurrent/kurrentdb-client: 1.1.0, @kurrent/bridge: 0.1.3
KurrentDB Version
KurrentDB 25.1.4
Connection string
kurrentdb+discover://:2113?tls=true
☁️ Deployment Environment
Managed KurrentDB Cloud
Other Deployment Details
3-node StatefulSet on AKS, managed via KurrentDB Operator
Operating system
Linux (RHEL 8 for server, Debian container for client), Node.js 22.x
🐛 Current behavior
Starting in v1.0.0,
readStreamandreadAllwere moved to the Rust native bridge (@kurrent/bridge) for performance. However, the bridge's credential interface (RustReadStreamOptions.credentials/RustReadAllOptions.credentials) only accepts{ username: string; password: string }:All other operations (append, delete, subscribe, persistent subscriptions) go through the gRPC path via
callArguments(), which invokescreateCredentialsMetadataGenerator. This allows consumers to override the credential generator for custom auth schemes (e.g., Bearer tokens via Azure RBAC /DefaultAzureCredential).Read operations bypass this entirely, because they go through the Rust bridge which has no concept of Bearer tokens or custom metadata generators.
Any consumer using token-based auth (OAuth2 Bearer, Azure RBAC, custom metadata generators) cannot use
readStreamorreadAllwithout workarounds. This affects:DefaultAzureCredentialcreateCredentialsMetadataGeneratoroverride for custom auth🔍 Steps to reproduce
Reproducible link
https://gist.github.com/kochai/a9d13566e2c03d1452023bbe65e6718f
💭 Expected behavior
One of the following (in order of preference):
Add Bearer/token credential support to
@kurrent/bridge— extendRustReadStreamOptions.credentialsandRustReadAllOptions.credentialsto accept atokenorbearerfield, and pass it as anAuthorization: Bearer <token>header in the Rust gRPC calls.Route reads through
callArguments()when custom credentials are detected — ifcreateCredentialsMetadataGeneratorhas been overridden on the client instance, fall back to the gRPC path for reads instead of the Rust bridge, so the custom metadata generator is invoked.Expose a public API for custom credential providers — e.g., a
credentialProvideroption on the client that is respected by both the gRPC and Rust bridge paths.Package version
@kurrent/kurrentdb-client: 1.1.0, @kurrent/bridge: 0.1.3
KurrentDB Version
KurrentDB 25.1.4
Connection string
kurrentdb+discover://:2113?tls=true
☁️ Deployment Environment
Managed KurrentDB Cloud
Other Deployment Details
3-node StatefulSet on AKS, managed via KurrentDB Operator
Operating system
Linux (RHEL 8 for server, Debian container for client), Node.js 22.x