Skip to content

[All] Support CallerOrg in Go SDK to identify callers in x-zerobus-sdk header #194

@zuckerberg-db

Description

@zuckerberg-db

SDK

All

Description

The ZeroBus Go SDK provides no way for callers to identify themselves in the x-zerobus-sdk gRPC metadata header without abandoning the built-in OAuth authentication flow.

Today, the x-zerobus-sdk header is hardcoded to zerobus-sdk-rs/<version> inside OAuthHeadersProvider. The only way to inject a custom identifier is to implement HeadersProvider manually via CreateStreamWithHeadersProvider, which requires the caller to re-implement OAuth token acquisition — a significant burden for a simple identification need.

This makes it difficult for platform teams to track which applications or organizations are sending data through ZeroBus.

Proposed Solution

Add a CallerOrg field to StreamConfigurationOptions (and ArrowStreamConfigurationOptions) that gets appended to the x-zerobus-sdk header value as a callerOrg-<value> segment. When CallerOrg is empty (default), behavior is unchanged.

This follows the same pattern used in the Delta Sharing SDK, which added a callerOrg option that threads through config layers and is appended to the User-Agent HTTP header.

Resulting header format:

x-zerobus-sdk: zerobus-sdk-rs/0.5.0 callerOrg-<organization>

Go SDK usage:

options := zerobus.DefaultStreamConfigurationOptions()
options.CallerOrg = "<organization>"

stream, err := sdk.CreateStream(tableProps, clientID, clientSecret, options)
// x-zerobus-sdk header now includes: "zerobus-sdk-rs/0.5.0 callerOrg-<organization>"

Implementation approach:

  • Add CallerOrg string to Go's StreamConfigurationOptions and ArrowStreamConfigurationOptions in go/types.go
  • Thread it through the C FFI struct (go/ffi.go, go/arrow_ffi.go) and the Rust FFI #[repr(C)] struct (rust/ffi/src/lib.rs)
  • In the Rust FFI layer, wrap the headers provider with a CallerOrgHeadersProvider decorator that appends callerOrg-<value> to the x-zerobus-sdk header
  • No Rust SDK core changes needed — the wrapper lives entirely in the FFI crate
struct CallerOrgHeadersProvider {
    inner: Arc<dyn HeadersProvider>,
    caller_org: String,
}

#[async_trait]
impl HeadersProvider for CallerOrgHeadersProvider {
    async fn get_headers(&self) -> ZerobusResult<HashMap<&'static str, String>> {
        let mut headers = self.inner.get_headers().await?;
        if let Some(existing) = headers.get("x-zerobus-sdk") {
            headers.insert("x-zerobus-sdk", format!("{} callerOrg-{}", existing, self.caller_org));
        } else {
            headers.insert("x-zerobus-sdk", format!("callerOrg-{}", self.caller_org));
        }
        Ok(headers)
    }
}

Additional Context

  • Backward compatibleCallerOrg defaults to empty string, preserving existing behavior
  • All stream types — covers both standard streams and Arrow Flight streams
  • Both auth paths — works with OAuth (CreateStream) and custom auth (CreateStreamWithHeadersProvider)
  • Precedent — Delta Sharing SDK implemented the identical pattern: delta-io/delta-sharing@d205144
  • The x-zerobus-sdk header is defined in rust/sdk/src/headers_provider.rs and was renamed from user-agent for clearer SDK identification in gRPC metadata

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions