client

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 19, 2025 License: Apache-2.0 Imports: 34 Imported by: 5

README

Directory Golang SDK

Overview

Dir Golang SDK provides a simple way to interact with the Directory API. It allows developers to integrate and use Directory functionality from their applications with ease.

Features

The Directory SDK provides comprehensive access to all Directory APIs with a simple, intuitive interface:

Store API
  • Record Management: Push records to the store and pull them by reference
  • Metadata Operations: Look up record metadata without downloading full content
  • Data Lifecycle: Delete records permanently from the store
  • Referrer Support: Push and pull artifacts for existing records
  • Sync Management: Manage storage synchronization policies between Directory servers
Search API
  • Flexible Search: Search stored records using text, semantic, and structured queries
  • Advanced Filtering: Filter results by metadata, content type, and other criteria
Routing API
  • Network Publishing: Publish records to make them discoverable across the network
  • Content Discovery: List and query published records across the network
  • Network Management: Unpublish records to remove them from network discovery
Signing and Verification
  • Local Signing: Sign records locally using private keys or OIDC-based authentication.
  • Remote Verification: Verify record signatures using the Directory gRPC API
Developer Experience
  • Async Support: Non-blocking operations with streaming responses for large datasets
  • Error Handling: Comprehensive gRPC error handling with detailed error messages
  • Configuration: Flexible configuration via environment variables or direct instantiation

Installation

  1. Initialize the project:
go mod init example.com/myapp
  1. Add the SDK to your project:
go get github.com/agntcy/dir/client

Configuration

The SDK can be configured via environment variables or direct instantiation.

Environment Variables
Variable Description Default
DIRECTORY_CLIENT_SERVER_ADDRESS Directory server address 0.0.0.0:8888
DIRECTORY_CLIENT_AUTH_MODE Authentication mode: x509, jwt, or empty for insecure "" (insecure)
DIRECTORY_CLIENT_SPIFFE_SOCKET_PATH SPIFFE Workload API socket path ""
DIRECTORY_CLIENT_JWT_AUDIENCE JWT audience for JWT authentication ""
Authentication

The SDK supports three authentication modes:

1. Insecure (No Authentication)

For local development only. Not recommended for production.

Environment Variables:

export DIRECTORY_CLIENT_SERVER_ADDRESS="localhost:8888"
# AUTH_MODE is empty or not set

Code Example:

import (
    "context"
    "github.com/agntcy/dir/client"
)

ctx := context.Background()
config := &client.Config{
    ServerAddress: "localhost:8888",
    // AuthMode is empty - insecure connection
}
c, err := client.New(ctx, client.WithConfig(config))
if err != nil {
    // handle error
}
defer c.Close() // Always close to cleanup resources
2. X509 (X.509-SVID)

Recommended for production. Requires SPIRE agent.

Environment Variables:

export DIRECTORY_CLIENT_SERVER_ADDRESS="localhost:8888"
export DIRECTORY_CLIENT_AUTH_MODE="x509"
export DIRECTORY_CLIENT_SPIFFE_SOCKET_PATH="unix:///run/spire/agent-sockets/api.sock"

Code Example:

import (
    "context"
    "github.com/agntcy/dir/client"
)

ctx := context.Background()
config := &client.Config{
    ServerAddress:    "localhost:8888",
    AuthMode:         "x509",
    SpiffeSocketPath: "unix:///run/spire/agent-sockets/api.sock",
}
c, err := client.New(ctx, client.WithConfig(config))
if err != nil {
    // handle error
}
defer c.Close() // Always close to cleanup resources
3. JWT (JWT-SVID)

Alternative to X.509 for client authentication. Requires SPIRE agent.

Note: In JWT mode, the server presents its X.509-SVID via TLS for server authentication and encryption, while the client authenticates using a JWT-SVID. This provides both transport security and client authentication, following the official SPIFFE JWT pattern.

Environment Variables:

export DIRECTORY_CLIENT_SERVER_ADDRESS="localhost:8888"
export DIRECTORY_CLIENT_AUTH_MODE="jwt"
export DIRECTORY_CLIENT_SPIFFE_SOCKET_PATH="unix:///run/spire/agent-sockets/api.sock"
export DIRECTORY_CLIENT_JWT_AUDIENCE="spiffe://example.org/dir-server"

Code Example:

import (
    "context"
    "github.com/agntcy/dir/client"
)

ctx := context.Background()
config := &client.Config{
    ServerAddress:    "localhost:8888",
    AuthMode:         "jwt",
    SpiffeSocketPath: "unix:///run/spire/agent-sockets/api.sock",
    JWTAudience:      "spiffe://example.org/dir-server",
}
c, err := client.New(ctx, client.WithConfig(config))
if err != nil {
    // handle error
}
defer c.Close() // Always close to cleanup resources

Getting Started

Prerequisites
  • Golang - Go programming language
1. Server Setup

Option A: Local Development Server

# Clone the repository and start the server using Taskfile
task server:start

Option B: Custom Server

# Set your Directory server address
export DIRECTORY_CLIENT_SERVER_ADDRESS="your-server:8888"
2. SDK Installation
# Add the Directory SDK
go get github.com/agntcy/dir/client

Documentation

Index

Constants

View Source
const (
	DefaultEnvPrefix = "DIRECTORY_CLIENT"

	DefaultServerAddress = "0.0.0.0:8888"
	DefaultTlsSkipVerify = false
)

Variables

View Source
var DefaultConfig = Config{
	ServerAddress: DefaultServerAddress,
}

Functions

This section is empty.

Types

type Client

func New

func New(ctx context.Context, opts ...Option) (*Client, error)

func (*Client) Close

func (c *Client) Close() error

func (*Client) CreateSync

func (c *Client) CreateSync(ctx context.Context, remoteURL string, cids []string) (string, error)

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, recordRef *corev1.RecordRef) error

Delete removes a record from the store using its reference.

func (*Client) DeleteBatch

func (c *Client) DeleteBatch(ctx context.Context, recordRefs []*corev1.RecordRef) error

DeleteBatch removes multiple records from the store in a single stream for efficiency.

func (*Client) DeleteStream

func (c *Client) DeleteStream(ctx context.Context, refsCh <-chan *corev1.RecordRef) (streaming.StreamResult[emptypb.Empty], error)

DeleteStream provides efficient streaming delete operations using channels. Record references are sent as they become available and delete confirmations are returned as they're processed. This method maintains a single gRPC stream for all operations, dramatically improving efficiency.

func (*Client) DeleteSync

func (c *Client) DeleteSync(ctx context.Context, syncID string) error

func (*Client) GetSync

func (c *Client) GetSync(ctx context.Context, syncID string) (*storev1.GetSyncResponse, error)

func (*Client) List

func (c *Client) List(ctx context.Context, req *routingv1.ListRequest) (<-chan *routingv1.ListResponse, error)

func (*Client) ListSyncs

func (c *Client) ListSyncs(ctx context.Context, req *storev1.ListSyncsRequest) (<-chan *storev1.ListSyncsItem, error)

func (*Client) ListenStream

ListenStream streams events from the server with the specified filters.

Returns a StreamResult that provides structured channels for receiving events, errors, and completion signals.

Example - Listen to all events:

result, err := client.ListenStream(ctx, &eventsv1.ListenRequest{})
if err != nil {
    return err
}

for {
    select {
    case resp := <-result.ResCh():
        event := resp.GetEvent()
        fmt.Printf("Event: %s - %s\n", event.Type, event.ResourceId)
    case err := <-result.ErrCh():
        return fmt.Errorf("stream error: %w", err)
    case <-result.DoneCh():
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

Example - Filter by event type:

result, err := client.ListenStream(ctx, &eventsv1.ListenRequest{
    EventTypes: []eventsv1.EventType{
        eventsv1.EventType_EVENT_TYPE_RECORD_PUSHED,
        eventsv1.EventType_EVENT_TYPE_RECORD_PUBLISHED,
    },
})

Example - Filter by labels:

result, err := client.ListenStream(ctx, &eventsv1.ListenRequest{
    LabelFilters: []string{"/skills/AI"},
})

func (*Client) Lookup

func (c *Client) Lookup(ctx context.Context, recordRef *corev1.RecordRef) (*corev1.RecordMeta, error)

Lookup retrieves metadata for a record using its reference.

func (*Client) LookupBatch

func (c *Client) LookupBatch(ctx context.Context, recordRefs []*corev1.RecordRef) ([]*corev1.RecordMeta, error)

LookupBatch retrieves metadata for multiple records in a single stream for efficiency.

func (*Client) LookupStream

func (c *Client) LookupStream(ctx context.Context, refsCh <-chan *corev1.RecordRef) (streaming.StreamResult[corev1.RecordMeta], error)

LookupStream provides efficient streaming lookup operations using channels. Record references are sent as they become available and metadata is returned as it's processed. This method maintains a single gRPC stream for all operations, dramatically improving efficiency.

Uses sequential streaming pattern (Send → Recv → Send → Recv) which ensures strict ordering of request-response pairs.

func (*Client) Publish

func (c *Client) Publish(ctx context.Context, req *routingv1.PublishRequest) error

func (*Client) Pull

func (c *Client) Pull(ctx context.Context, recordRef *corev1.RecordRef) (*corev1.Record, error)

Pull retrieves a single record from the store using its reference. This is a convenience wrapper around PullBatch for single-record operations.

func (*Client) PullBatch

func (c *Client) PullBatch(ctx context.Context, recordRefs []*corev1.RecordRef) ([]*corev1.Record, error)

PullBatch retrieves multiple records in a single stream for efficiency. This is a convenience method that accepts a slice and returns a slice, built on top of the streaming implementation for consistency.

func (*Client) PullReferrer

func (c *Client) PullReferrer(ctx context.Context, req *storev1.PullReferrerRequest) (<-chan *storev1.PullReferrerResponse, error)

PullReferrer retrieves all referrers using the PullReferrer RPC.

func (*Client) PullStream

func (c *Client) PullStream(ctx context.Context, refsCh <-chan *corev1.RecordRef) (streaming.StreamResult[corev1.Record], error)

PullStream retrieves multiple records efficiently using a single bidirectional stream. This method is ideal for batch operations and takes full advantage of gRPC streaming. The input channel allows you to send record refs as they become available.

func (*Client) Push

func (c *Client) Push(ctx context.Context, record *corev1.Record) (*corev1.RecordRef, error)

Push sends a complete record to the store and returns a record reference. This is a convenience wrapper around PushBatch for single-record operations. The record must be ≤4MB as per the v1 store service specification.

func (*Client) PushBatch

func (c *Client) PushBatch(ctx context.Context, records []*corev1.Record) ([]*corev1.RecordRef, error)

PushBatch sends multiple records in a single stream for efficiency. This is a convenience method that accepts a slice and returns a slice, built on top of the streaming implementation for consistency.

func (*Client) PushReferrer

func (c *Client) PushReferrer(ctx context.Context, req *storev1.PushReferrerRequest) error

PushReferrer stores a signature using the PushReferrer RPC.

func (*Client) PushStream

func (c *Client) PushStream(ctx context.Context, recordsCh <-chan *corev1.Record) (streaming.StreamResult[corev1.RecordRef], error)

PushStream uploads multiple records efficiently using a single bidirectional stream. This method is ideal for batch operations and takes full advantage of gRPC streaming. The input channel allows you to send records as they become available.

func (*Client) SearchCIDs added in v0.5.6

SearchCIDs searches for record CIDs matching the given request.

func (*Client) SearchRecords added in v0.5.6

SearchRecords searches for full records matching the given request.

func (*Client) SearchRouting

func (c *Client) SearchRouting(ctx context.Context, req *routingv1.SearchRequest) (<-chan *routingv1.SearchResponse, error)

func (*Client) Sign

Sign routes to the appropriate signing method based on provider type. This is the main entry point for signing operations.

func (*Client) SignWithKey

func (c *Client) SignWithKey(ctx context.Context, req *signv1.SignRequest) (*signv1.SignResponse, error)

func (*Client) SignWithOIDC

func (c *Client) SignWithOIDC(ctx context.Context, req *signv1.SignRequest) (*signv1.SignResponse, error)

SignWithOIDC signs the record using keyless OIDC service-based signing. The OIDC ID Token can be provided by the caller, or cosign will handle interactive OIDC flow. This implementation uses cosign sign-blob command for OIDC signing.

func (*Client) Unpublish

func (c *Client) Unpublish(ctx context.Context, req *routingv1.UnpublishRequest) error

func (*Client) Verify

Verify verifies the signature of the record.

type Config

type Config struct {
	ServerAddress    string `json:"server_address,omitempty"     mapstructure:"server_address"`
	TlsSkipVerify    bool   `json:"tls_skip_verify,omitempty"    mapstructure:"tls_skip_verify"`
	TlsCertFile      string `json:"tls_cert_file,omitempty"      mapstructure:"tls_cert_file"`
	TlsKeyFile       string `json:"tls_key_file,omitempty"       mapstructure:"tls_key_file"`
	TlsCAFile        string `json:"tls_ca_file,omitempty"        mapstructure:"tls_ca_file"`
	SpiffeSocketPath string `json:"spiffe_socket_path,omitempty" mapstructure:"spiffe_socket_path"`
	SpiffeToken      string `json:"spiffe_token,omitempty"       mapstructure:"spiffe_token"`
	AuthMode         string `json:"auth_mode,omitempty"          mapstructure:"auth_mode"`
	JWTAudience      string `json:"jwt_audience,omitempty"       mapstructure:"jwt_audience"`
}

func LoadConfig

func LoadConfig() (*Config, error)

type Option

type Option func(*options) error

func WithConfig

func WithConfig(config *Config) Option

func WithEnvConfig

func WithEnvConfig() Option

type SignOpts

type SignOpts struct {
	FulcioURL       string
	RekorURL        string
	TimestampURL    string
	OIDCProviderURL string
	OIDCClientID    string
	OIDCToken       string
	Key             string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL