Documentation
¶
Index ¶
- Constants
- Variables
- type AuthResult
- type CachedToken
- type Client
- func (c *Client) Close() error
- func (c *Client) CreateSync(ctx context.Context, remoteURL string, cids []string) (string, error)
- func (c *Client) Delete(ctx context.Context, recordRef *corev1.RecordRef) error
- func (c *Client) DeleteBatch(ctx context.Context, recordRefs []*corev1.RecordRef) error
- func (c *Client) DeleteReferrer(ctx context.Context, req *storev1.DeleteReferrerRequest) (*storev1.DeleteReferrerResponse, error)
- func (c *Client) DeleteStream(ctx context.Context, refsCh <-chan *corev1.RecordRef) (streaming.StreamResult[emptypb.Empty], error)
- func (c *Client) DeleteSync(ctx context.Context, syncID string) error
- func (c *Client) GetSync(ctx context.Context, syncID string) (*storev1.GetSyncResponse, error)
- func (c *Client) GetVerificationInfo(ctx context.Context, cid string) (*namingv1.GetVerificationInfoResponse, error)
- func (c *Client) GetVerificationInfoByName(ctx context.Context, name string, version string) (*namingv1.GetVerificationInfoResponse, error)
- func (c *Client) GetWorkload(ctx context.Context, workloadID string) (*runtimev1.Workload, error)
- func (c *Client) List(ctx context.Context, req *routingv1.ListRequest) (<-chan *routingv1.ListResponse, error)
- func (c *Client) ListSyncs(ctx context.Context, req *storev1.ListSyncsRequest) (<-chan *storev1.ListSyncsItem, error)
- func (c *Client) ListWorkloads(ctx context.Context, labels map[string]string) ([]*runtimev1.Workload, error)
- func (c *Client) ListWorkloadsStream(ctx context.Context, labels map[string]string) (streaming.StreamResult[runtimev1.Workload], error)
- func (c *Client) ListenStream(ctx context.Context, req *eventsv1.ListenRequest) (streaming.StreamResult[eventsv1.ListenResponse], error)
- func (c *Client) Lookup(ctx context.Context, recordRef *corev1.RecordRef) (*corev1.RecordMeta, error)
- func (c *Client) LookupBatch(ctx context.Context, recordRefs []*corev1.RecordRef) ([]*corev1.RecordMeta, error)
- func (c *Client) LookupStream(ctx context.Context, refsCh <-chan *corev1.RecordRef) (streaming.StreamResult[corev1.RecordMeta], error)
- func (c *Client) Publish(ctx context.Context, req *routingv1.PublishRequest) error
- func (c *Client) Pull(ctx context.Context, recordRef *corev1.RecordRef) (*corev1.Record, error)
- func (c *Client) PullBatch(ctx context.Context, recordRefs []*corev1.RecordRef) ([]*corev1.Record, error)
- func (c *Client) PullPublicKeys(ctx context.Context, recordRef *corev1.RecordRef) ([]string, error)
- func (c *Client) PullReferrer(ctx context.Context, req *storev1.PullReferrerRequest) ([]*storev1.PullReferrerResponse, error)
- func (c *Client) PullSignatures(ctx context.Context, recordRef *corev1.RecordRef) ([]*signv1.Signature, error)
- func (c *Client) PullStream(ctx context.Context, refsCh <-chan *corev1.RecordRef) (streaming.StreamResult[corev1.Record], error)
- func (c *Client) Push(ctx context.Context, record *corev1.Record) (*corev1.RecordRef, error)
- func (c *Client) PushBatch(ctx context.Context, records []*corev1.Record) ([]*corev1.RecordRef, error)
- func (c *Client) PushReferrer(ctx context.Context, req *storev1.PushReferrerRequest) (*storev1.PushReferrerResponse, error)
- func (c *Client) PushStream(ctx context.Context, recordsCh <-chan *corev1.Record) (streaming.StreamResult[corev1.RecordRef], error)
- func (c *Client) Resolve(ctx context.Context, name string, version string) (*namingv1.ResolveResponse, error)
- func (c *Client) SearchCIDs(ctx context.Context, req *searchv1.SearchCIDsRequest) (streaming.StreamResult[searchv1.SearchCIDsResponse], error)
- func (c *Client) SearchRecords(ctx context.Context, req *searchv1.SearchRecordsRequest) (streaming.StreamResult[searchv1.SearchRecordsResponse], error)
- func (c *Client) SearchRouting(ctx context.Context, req *routingv1.SearchRequest) (<-chan *routingv1.SearchResponse, error)
- func (c *Client) Sign(ctx context.Context, req *signv1.SignRequest) (*signv1.SignResponse, error)
- func (c *Client) Unpublish(ctx context.Context, req *routingv1.UnpublishRequest) error
- func (c *Client) Verify(ctx context.Context, req *signv1.VerifyRequest) (*signv1.VerifyResponse, error)
- type Config
- type DeviceFlowConfig
- type OIDCProvider
- type Option
- type PKCEConfig
- type TokenCache
- type TokenCacheEntry
Constants ¶
const ( DefaultEnvPrefix = "DIRECTORY_CLIENT" DefaultServerAddress = "0.0.0.0:8888" DefaultTlsSkipVerify = false DefaultCallbackPort = 8484 DefaultOAuthTimeout = 5 * time.Minute )
const ( // DefaultTokenCacheDir is the default directory for storing cached tokens (relative to home directory). // When XDG_CONFIG_HOME is set, tokens are stored at $XDG_CONFIG_HOME/dirctl instead. //nolint:gosec // G101: This is a directory path, not a credential DefaultTokenCacheDir = ".config/dirctl" // TokenCacheFile is the filename for the cached token. //nolint:gosec // G101: This is a filename, not a credential TokenCacheFile = "auth-token.json" // DefaultTokenValidityDuration is how long a token is considered valid if no expiry is set. DefaultTokenValidityDuration = 8 * time.Hour // TokenExpiryBuffer is how much time before actual expiry we consider a token expired. TokenExpiryBuffer = 5 * time.Minute )
const DefaultOIDCScopes = "openid email profile"
DefaultOIDCScopes are the OIDC scopes requested for interactive login.
Variables ¶
var DefaultConfig = Config{ ServerAddress: DefaultServerAddress, }
var OIDC = &OIDCProvider{}
OIDC provides OIDC authentication flows.
Functions ¶
This section is empty.
Types ¶
type AuthResult ¶ added in v1.2.0
type AuthResult struct {
AccessToken string
RefreshToken string
TokenType string
ExpiresAt time.Time
IDToken string
Subject string
Email string
Name string
}
AuthResult is the unified result from any OIDC authentication flow (PKCE or device).
type CachedToken ¶ added in v1.0.0
type CachedToken struct {
// AccessToken is the authentication token.
AccessToken string `json:"access_token"` // #nosec G117: intentional field - for cached token
// TokenType is the token type (usually "bearer").
TokenType string `json:"token_type,omitempty"`
// Provider is the authentication provider (oidc, github, google, azure, etc.)
Provider string `json:"provider,omitempty"`
// Issuer is the OIDC issuer URL (for Provider=oidc). Enables multi-issuer support.
Issuer string `json:"issuer,omitempty"`
// RefreshToken is the refresh token, if the IdP returned one (for token refresh).
RefreshToken string `json:"refresh_token,omitempty"` // #nosec G101: intentional field - for cached token
// ExpiresAt is when the token expires.
ExpiresAt time.Time `json:"expires_at,omitzero"`
// User is the authenticated username (e.g. preferred_username or name for OIDC).
User string `json:"user,omitempty"`
// UserID is the provider-specific user ID (e.g. sub for OIDC).
UserID string `json:"user_id,omitempty"`
// Email is the user's email address.
Email string `json:"email,omitempty"`
// CreatedAt is when the token was cached.
CreatedAt time.Time `json:"created_at"`
}
CachedToken represents a cached authentication token from any provider.
type Client ¶
type Client struct {
storev1.StoreServiceClient
routingv1.RoutingServiceClient
searchv1.SearchServiceClient
storev1.SyncServiceClient
signv1.SignServiceClient
eventsv1.EventServiceClient
namingv1.NamingServiceClient
runtimev1.DiscoveryServiceClient
// contains filtered or unexported fields
}
func (*Client) CreateSync ¶
func (*Client) DeleteBatch ¶
DeleteBatch removes multiple records from the store in a single stream for efficiency.
func (*Client) DeleteReferrer ¶ added in v1.2.0
func (c *Client) DeleteReferrer( ctx context.Context, req *storev1.DeleteReferrerRequest, ) (*storev1.DeleteReferrerResponse, error)
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) GetVerificationInfo ¶ added in v1.0.0
func (c *Client) GetVerificationInfo(ctx context.Context, cid string) (*namingv1.GetVerificationInfoResponse, error)
GetVerificationInfo retrieves the verification info for a record by CID.
func (*Client) GetVerificationInfoByName ¶ added in v1.0.0
func (c *Client) GetVerificationInfoByName(ctx context.Context, name string, version string) (*namingv1.GetVerificationInfoResponse, error)
GetVerificationInfoByName retrieves the verification info for a record by name. If version is empty, the latest version is used.
func (*Client) GetWorkload ¶ added in v1.2.0
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) ListWorkloads ¶ added in v1.2.0
func (*Client) ListWorkloadsStream ¶ added in v1.2.0
func (*Client) ListenStream ¶
func (c *Client) ListenStream(ctx context.Context, req *eventsv1.ListenRequest) (streaming.StreamResult[eventsv1.ListenResponse], error)
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) Pull ¶
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) PullPublicKeys ¶ added in v1.1.0
PullPublicKeys fetches all public key referrers for a record.
func (*Client) PullReferrer ¶
func (c *Client) PullReferrer(ctx context.Context, req *storev1.PullReferrerRequest) ([]*storev1.PullReferrerResponse, error)
PullReferrer retrieves all referrers using the PullReferrer RPC.
func (*Client) PullSignatures ¶ added in v1.1.0
func (c *Client) PullSignatures(ctx context.Context, recordRef *corev1.RecordRef) ([]*signv1.Signature, error)
PullSignatures fetches all signature referrers for a record.
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 ¶
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) (*storev1.PushReferrerResponse, 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) Resolve ¶ added in v1.0.0
func (c *Client) Resolve(ctx context.Context, name string, version string) (*namingv1.ResolveResponse, error)
Resolve resolves a record reference (name with optional version) to CIDs. Returns all matching records sorted by created_at descending (newest first). If version is empty, returns all versions; otherwise returns matches for the specific version.
func (*Client) SearchCIDs ¶ added in v0.5.6
func (c *Client) SearchCIDs(ctx context.Context, req *searchv1.SearchCIDsRequest) (streaming.StreamResult[searchv1.SearchCIDsResponse], error)
SearchCIDs searches for record CIDs matching the given request.
func (*Client) SearchRecords ¶ added in v0.5.6
func (c *Client) SearchRecords(ctx context.Context, req *searchv1.SearchRecordsRequest) (streaming.StreamResult[searchv1.SearchRecordsResponse], error)
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 ¶
func (c *Client) Sign(ctx context.Context, req *signv1.SignRequest) (*signv1.SignResponse, error)
Sign routes to the appropriate signing method based on provider type. This is the main entry point for signing operations.
func (*Client) Verify ¶
func (c *Client) Verify(ctx context.Context, req *signv1.VerifyRequest) (*signv1.VerifyResponse, error)
Verify verifies signatures for a record. When from_server is true, the result is the server's cached verification; when false, verification is performed locally.
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"`
// OIDC configuration (for interactive login)
OIDCIssuer string `json:"oidc_issuer,omitempty" mapstructure:"oidc_issuer"`
OIDCClientID string `json:"oidc_client_id,omitempty" mapstructure:"oidc_client_id"`
// Pre-issued Bearer token for CI/scripts (skips interactive login)
AuthToken string `json:"auth_token,omitempty" mapstructure:"auth_token"`
}
func LoadConfig ¶
type DeviceFlowConfig ¶ added in v1.0.0
type DeviceFlowConfig struct {
Issuer string
ClientID string
Scopes []string
PollInterval time.Duration
Timeout time.Duration
Output io.Writer
}
DeviceFlowConfig holds configuration for the OAuth 2.0 Device Authorization Grant (RFC 8628).
type OIDCProvider ¶ added in v1.2.0
type OIDCProvider struct{}
OIDCProvider groups OIDC-related methods.
func (*OIDCProvider) RunDeviceFlow ¶ added in v1.2.0
func (*OIDCProvider) RunDeviceFlow(ctx context.Context, cfg *DeviceFlowConfig) (*AuthResult, error)
RunDeviceFlow performs the OAuth 2.0 Device Authorization Grant (RFC 8628).
func (*OIDCProvider) RunPKCEFlow ¶ added in v1.2.0
func (*OIDCProvider) RunPKCEFlow(ctx context.Context, cfg *PKCEConfig) (*AuthResult, error)
RunPKCEFlow performs the OIDC Authorization Code flow with PKCE.
type Option ¶
type Option func(*options) error
func WithConfig ¶
func WithEnvConfig ¶
func WithEnvConfig() Option
type PKCEConfig ¶ added in v1.2.0
type PKCEConfig struct {
Issuer string
ClientID string
RedirectURI string
Scopes []string
CallbackPort int
SkipBrowserOpen bool
Timeout time.Duration
Output io.Writer
}
PKCEConfig holds configuration for the OIDC PKCE flow.
type TokenCache ¶ added in v1.0.0
type TokenCache struct {
// CacheDir is the directory where tokens are stored.
CacheDir string
}
TokenCache manages cached authentication tokens from any provider.
func NewTokenCache ¶ added in v1.0.0
func NewTokenCache() *TokenCache
NewTokenCache creates a new token cache with the default directory. Respects XDG_CONFIG_HOME environment variable for config directory location.
func NewTokenCacheWithDir ¶ added in v1.0.0
func NewTokenCacheWithDir(dir string) *TokenCache
NewTokenCacheWithDir creates a new token cache with a custom directory.
func (*TokenCache) Clear ¶ added in v1.0.0
func (c *TokenCache) Clear() error
Clear removes the cached token.
func (*TokenCache) GetCachePath ¶ added in v1.0.0
func (c *TokenCache) GetCachePath() string
GetCachePath returns the full path to the token cache file.
func (*TokenCache) GetValidToken ¶ added in v1.0.0
func (c *TokenCache) GetValidToken() (*CachedToken, error)
GetValidToken returns a valid cached token or nil if none exists.
func (*TokenCache) IsValid ¶ added in v1.0.0
func (c *TokenCache) IsValid(token *CachedToken) bool
IsValid checks if a cached token is still valid. A token is considered valid if it exists and hasn't expired.
func (*TokenCache) Load ¶ added in v1.0.0
func (c *TokenCache) Load() (*CachedToken, error)
Load loads the cached token from disk. Returns nil if no valid token is found.
func (*TokenCache) Save ¶ added in v1.0.0
func (c *TokenCache) Save(token *CachedToken) error
Save saves a token to the cache.
type TokenCacheEntry ¶ added in v1.0.0
type TokenCacheEntry = CachedToken
TokenCacheEntry is an alias for CachedToken (for compatibility).