Documentation
¶
Overview ¶
pkg/ociplugins/client.go
pkg/ociplugins/config.go
pkg/ociplugins/errors.go
pkg/ociplugins/fetcher.go
pkg/ociplugins/parser.go
pkg/ociplugins/storage.go
pkg/ociplugins/verifier.go
Index ¶
- Constants
- func LoadPublicKeysFromEnv() []string
- func LoadRegistryAuthFromEnv() map[string]RegistryAuth
- func ParseOCICommand(command string) (*OCIReference, *OCIPluginParams, error)
- func ValidateOCIReference(ref *OCIReference, config *OCIConfig) error
- type ContentStorage
- func (s *ContentStorage) CalculateSize() (int64, error)
- func (s *ContentStorage) CreateActiveLink(name, digest, arch string) error
- func (s *ContentStorage) GarbageCollect(keepVersions int) error
- func (s *ContentStorage) GetActivePath(name string) (string, error)
- func (s *ContentStorage) GetBlob(digest string) ([]byte, error)
- func (s *ContentStorage) GetExecutablePath(digest, arch string) string
- func (s *ContentStorage) HasExecutable(digest, arch string) bool
- func (s *ContentStorage) HasMetadata(digest, arch string) bool
- func (s *ContentStorage) ListAllMetadata() ([]*PluginMetadata, error)
- func (s *ContentStorage) LoadMetadata(digest, arch string) (*PluginMetadata, error)
- func (s *ContentStorage) StoreBlob(data []byte) (string, error)
- func (s *ContentStorage) StoreExecutable(digest, arch string, data []byte) (string, error)
- func (s *ContentStorage) StoreMetadata(digest, arch string, metadata *PluginMetadata) error
- func (s *ContentStorage) UpdateLastAccessed(digest, arch string) error
- type ErrCacheCorrupted
- type ErrIncompatibleArchitecture
- type ErrInvalidOCIReference
- type ErrNetworkTimeout
- type ErrPluginNotFound
- type ErrRegistryNotAllowed
- type ErrSignatureVerificationFailed
- type LocalPlugin
- type OCIConfig
- type OCIPluginClient
- func (c *OCIPluginClient) Close() error
- func (c *OCIPluginClient) FetchPlugin(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (*LocalPlugin, error)
- func (c *OCIPluginClient) GarbageCollect(ctx context.Context, keepVersions int) error
- func (c *OCIPluginClient) GetActivePlugin(name string) (string, error)
- func (c *OCIPluginClient) GetCacheSize() (int64, error)
- func (c *OCIPluginClient) GetPlugin(ref *OCIReference, params *OCIPluginParams) (*LocalPlugin, error)
- func (c *OCIPluginClient) HasPlugin(digest, arch string) bool
- func (c *OCIPluginClient) ListCached() ([]*LocalPlugin, error)
- func (c *OCIPluginClient) ListCachedByArchitecture(arch string) ([]*LocalPlugin, error)
- func (c *OCIPluginClient) ListCachedByRegistry(registry string) ([]*LocalPlugin, error)
- func (c *OCIPluginClient) SetActivePlugin(name string, ref *OCIReference, params *OCIPluginParams) error
- func (c *OCIPluginClient) SetSecurityService(service SecurityService)
- type OCIPluginParams
- type OCIReference
- type ORASFetcher
- func (f *ORASFetcher) CheckExists(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (bool, error)
- func (f *ORASFetcher) Pull(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (*ocispec.Descriptor, *PluginConfig, []byte, error)
- func (f *ORASFetcher) PullManifest(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (*ocispec.Descriptor, *ocispec.Manifest, error)
- type PluginConfig
- type PluginMetadata
- type RegistryAuth
- type SecurityService
- type SignatureVerifier
- func (v *SignatureVerifier) LoadPublicKeysFromDirectory(dir string) ([]string, error)
- func (v *SignatureVerifier) ValidatePublicKey(keyPath string) error
- func (v *SignatureVerifier) Verify(ctx context.Context, ref *OCIReference, pubKeyID string) error
- func (v *SignatureVerifier) VerifyBundle(ctx context.Context, ref *OCIReference, issuer, subject string) error
- func (v *SignatureVerifier) VerifyWithPolicy(ctx context.Context, ref *OCIReference, policyPath string) error
Examples ¶
Constants ¶
const DefaultMaxPluginSize = 512 * 1024 * 1024 // 512MB
DefaultMaxPluginSize bounds a single plugin binary when the configuration does not set MaxPluginSize. Plugin binaries are statically linked Go executables and routinely run to tens of megabytes.
const DefaultTykPublicKey = `` /* 177-byte string literal not displayed */
DefaultTykPublicKey is the official Tyk plugin signing public key (ECDSA P-256). This key is always included in the trusted keys list and cannot be disabled via environment variables. Additional keys can be added via OCI_PLUGINS_PUBKEY_* env vars.
Variables ¶
This section is empty.
Functions ¶
func LoadPublicKeysFromEnv ¶
func LoadPublicKeysFromEnv() []string
LoadPublicKeysFromEnv loads public keys from environment variables Supports multiple formats: - OCI_PLUGINS_PUBKEY_<NUMBER> - Numbered keys with PEM content - OCI_PLUGINS_PUBKEY_<NAME> - Named keys with PEM content - OCI_PLUGINS_PUBKEY_FILE_<NAME> - File path references
func LoadRegistryAuthFromEnv ¶
func LoadRegistryAuthFromEnv() map[string]RegistryAuth
LoadRegistryAuthFromEnv loads registry authentication configuration from environment variables Environment variables pattern: OCI_PLUGINS_REGISTRY_<NAME>_USERNAME OCI_PLUGINS_REGISTRY_<NAME>_PASSWORD_ENV OCI_PLUGINS_REGISTRY_<NAME>_TOKEN_ENV
func ParseOCICommand ¶
func ParseOCICommand(command string) (*OCIReference, *OCIPluginParams, error)
ParseOCICommand parses an OCI command string and returns the reference and parameters
Example ¶
ExampleParseOCICommand demonstrates how to parse OCI plugin commands
// Basic OCI reference with digest and explicit architecture
ref, params, err := ParseOCICommand("oci://nexus.example.com/plugins/ner@sha256:0123deadbeef456?arch=linux/amd64")
if err != nil {
panic(err)
}
fmt.Printf("Registry: %s\n", ref.Registry)
fmt.Printf("Repository: %s\n", ref.Repository)
fmt.Printf("Digest: %s\n", ref.Digest)
fmt.Printf("Architecture: %s\n", params.Architecture)
// OCI reference with parameters
_, params2, err := ParseOCICommand("oci://registry.com/plugins/test@sha256:abc123?arch=linux/arm64&pubkey=test.pub")
if err != nil {
panic(err)
}
fmt.Printf("Architecture: %s\n", params2.Architecture)
fmt.Printf("Public Key: %s\n", params2.PublicKey)
Output: Registry: nexus.example.com Repository: plugins/ner Digest: sha256:0123deadbeef456 Architecture: linux/amd64 Architecture: linux/arm64 Public Key: test.pub
func ValidateOCIReference ¶
func ValidateOCIReference(ref *OCIReference, config *OCIConfig) error
ValidateOCIReference performs additional validation on an OCI reference
Types ¶
type ContentStorage ¶
type ContentStorage struct {
// contains filtered or unexported fields
}
ContentStorage manages content-addressed storage for plugins
func NewContentStorage ¶
func NewContentStorage(baseDir string, maxSize int64, gcInterval time.Duration) (*ContentStorage, error)
NewContentStorage creates a new content storage instance
func (*ContentStorage) CalculateSize ¶
func (s *ContentStorage) CalculateSize() (int64, error)
CalculateSize returns the total size of the cache in bytes
func (*ContentStorage) CreateActiveLink ¶
func (s *ContentStorage) CreateActiveLink(name, digest, arch string) error
CreateActiveLink creates or updates a symlink to mark a plugin as active
func (*ContentStorage) GarbageCollect ¶
func (s *ContentStorage) GarbageCollect(keepVersions int) error
GarbageCollect removes old plugin versions, keeping the specified number
func (*ContentStorage) GetActivePath ¶
func (s *ContentStorage) GetActivePath(name string) (string, error)
GetActivePath returns the path to the active version of a plugin
func (*ContentStorage) GetBlob ¶
func (s *ContentStorage) GetBlob(digest string) ([]byte, error)
GetBlob retrieves blob data by digest
func (*ContentStorage) GetExecutablePath ¶
func (s *ContentStorage) GetExecutablePath(digest, arch string) string
GetExecutablePath returns the path to an executable by digest and architecture, or "" if either is not a valid path component.
func (*ContentStorage) HasExecutable ¶
func (s *ContentStorage) HasExecutable(digest, arch string) bool
HasExecutable checks if an executable exists for the given digest and architecture
func (*ContentStorage) HasMetadata ¶
func (s *ContentStorage) HasMetadata(digest, arch string) bool
HasMetadata checks if metadata exists for a plugin
func (*ContentStorage) ListAllMetadata ¶
func (s *ContentStorage) ListAllMetadata() ([]*PluginMetadata, error)
ListAllMetadata returns metadata for all cached plugins
func (*ContentStorage) LoadMetadata ¶
func (s *ContentStorage) LoadMetadata(digest, arch string) (*PluginMetadata, error)
LoadMetadata loads plugin metadata by digest and architecture
func (*ContentStorage) StoreBlob ¶
func (s *ContentStorage) StoreBlob(data []byte) (string, error)
StoreBlob stores raw blob data and returns the digest
func (*ContentStorage) StoreExecutable ¶
func (s *ContentStorage) StoreExecutable(digest, arch string, data []byte) (string, error)
StoreExecutable stores a plugin binary and returns the executable path
func (*ContentStorage) StoreMetadata ¶
func (s *ContentStorage) StoreMetadata(digest, arch string, metadata *PluginMetadata) error
StoreMetadata stores plugin metadata
func (*ContentStorage) UpdateLastAccessed ¶
func (s *ContentStorage) UpdateLastAccessed(digest, arch string) error
UpdateLastAccessed updates the last accessed time for a plugin
type ErrCacheCorrupted ¶
ErrCacheCorrupted indicates the plugin cache is corrupted
func (*ErrCacheCorrupted) Error ¶
func (e *ErrCacheCorrupted) Error() string
type ErrIncompatibleArchitecture ¶
ErrIncompatibleArchitecture indicates the plugin is not compatible with the current architecture
func (*ErrIncompatibleArchitecture) Error ¶
func (e *ErrIncompatibleArchitecture) Error() string
type ErrInvalidOCIReference ¶
ErrInvalidOCIReference indicates an invalid OCI reference format
func (*ErrInvalidOCIReference) Error ¶
func (e *ErrInvalidOCIReference) Error() string
type ErrNetworkTimeout ¶
ErrNetworkTimeout indicates a network operation timed out
func (*ErrNetworkTimeout) Error ¶
func (e *ErrNetworkTimeout) Error() string
type ErrPluginNotFound ¶
type ErrPluginNotFound struct {
Reference string
}
ErrPluginNotFound indicates the plugin was not found in the registry
func (*ErrPluginNotFound) Error ¶
func (e *ErrPluginNotFound) Error() string
type ErrRegistryNotAllowed ¶
ErrRegistryNotAllowed indicates the registry is not in the allowlist
func (*ErrRegistryNotAllowed) Error ¶
func (e *ErrRegistryNotAllowed) Error() string
type ErrSignatureVerificationFailed ¶
ErrSignatureVerificationFailed indicates cosign signature verification failed
func (*ErrSignatureVerificationFailed) Error ¶
func (e *ErrSignatureVerificationFailed) Error() string
type LocalPlugin ¶
type LocalPlugin struct {
Reference *OCIReference `json:"reference"`
Params *OCIPluginParams `json:"params"`
ExecutablePath string `json:"executable_path"` // Path to executable binary
ConfigPath string `json:"config_path"` // Optional config JSON path
CacheDir string `json:"cache_dir"` // Storage location
Verified bool `json:"verified"` // Cosign verification status
FetchTime time.Time `json:"fetch_time"` // When downloaded
Config *PluginConfig `json:"config"` // Parsed from OCI config layer
}
LocalPlugin represents a plugin that has been fetched and is available locally
type OCIConfig ¶
type OCIConfig struct {
// Cache settings
CacheDir string `yaml:"cache_dir" json:"cache_dir"`
MaxCacheSize int64 `yaml:"max_cache_size" json:"max_cache_size"`
// MaxPluginSize bounds a single plugin binary. Layer sizes come from
// registry-supplied descriptors, so the binary is streamed against this
// limit rather than trusting the descriptor.
MaxPluginSize int64 `yaml:"max_plugin_size" json:"max_plugin_size"`
// Default security settings
DefaultPublicKeys []string `yaml:"default_public_keys" json:"default_public_keys"`
AllowedRegistries []string `yaml:"allowed_registries" json:"allowed_registries"`
// Authentication
RegistryAuth map[string]RegistryAuth `yaml:"registry_auth" json:"registry_auth"`
// Network settings
Timeout time.Duration `yaml:"timeout" json:"timeout"`
RetryAttempts int `yaml:"retry_attempts" json:"retry_attempts"`
// Security settings
RequireSignature bool `yaml:"require_signature" json:"require_signature"`
// Registry connection settings
InsecureRegistries []string `yaml:"insecure_registries" json:"insecure_registries"`
// Garbage collection
GCInterval time.Duration `yaml:"gc_interval" json:"gc_interval"`
KeepVersions int `yaml:"keep_versions" json:"keep_versions"`
}
OCIConfig holds the configuration for OCI plugin operations
func DefaultOCIConfig ¶
func DefaultOCIConfig() *OCIConfig
DefaultOCIConfig returns a configuration with sensible defaults
type OCIPluginClient ¶
type OCIPluginClient struct {
// contains filtered or unexported fields
}
OCIPluginClient handles OCI-based plugin operations
func NewOCIPluginClient ¶
func NewOCIPluginClient(config *OCIConfig) (*OCIPluginClient, error)
NewOCIPluginClient creates a new OCI plugin client
func (*OCIPluginClient) Close ¶
func (c *OCIPluginClient) Close() error
Close shuts down the OCI client and cleans up resources
func (*OCIPluginClient) FetchPlugin ¶
func (c *OCIPluginClient) FetchPlugin(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (*LocalPlugin, error)
FetchPlugin fetches a plugin by OCI reference, verifies it, and returns local information
Example ¶
ExampleOCIPluginClient_FetchPlugin demonstrates how to fetch a plugin from an OCI registry
// NOTE: This is a demonstration example - it won't work without a real registry
// Create client configuration
config := &OCIConfig{
CacheDir: "/tmp/plugin-cache",
RequireSignature: false, // Disable for demo
AllowedRegistries: []string{"nexus.example.com"},
Timeout: 30,
RetryAttempts: 3,
}
// Create client
_, err := NewOCIPluginClient(config)
if err != nil {
panic(err)
}
// Parse OCI reference with explicit architecture
ref, params, err := ParseOCICommand("oci://nexus.example.com/plugins/ner@sha256:0123deadbeef456?arch=linux/amd64")
if err != nil {
panic(err)
}
// This would fetch from the registry in a real scenario
fmt.Printf("Would fetch plugin: %s\n", ref.FullReference())
fmt.Printf("Target architecture: %s\n", params.Architecture)
Output: Would fetch plugin: nexus.example.com/plugins/ner@sha256:0123deadbeef456 Target architecture: linux/amd64
func (*OCIPluginClient) GarbageCollect ¶
func (c *OCIPluginClient) GarbageCollect(ctx context.Context, keepVersions int) error
GarbageCollect removes old plugin versions from cache
func (*OCIPluginClient) GetActivePlugin ¶
func (c *OCIPluginClient) GetActivePlugin(name string) (string, error)
GetActivePlugin returns the path to the active version of a plugin
func (*OCIPluginClient) GetCacheSize ¶
func (c *OCIPluginClient) GetCacheSize() (int64, error)
GetCacheSize returns the current size of the plugin cache
func (*OCIPluginClient) GetPlugin ¶
func (c *OCIPluginClient) GetPlugin(ref *OCIReference, params *OCIPluginParams) (*LocalPlugin, error)
GetPlugin returns a local plugin if it exists in cache
func (*OCIPluginClient) HasPlugin ¶
func (c *OCIPluginClient) HasPlugin(digest, arch string) bool
HasPlugin checks if a plugin exists in the cache
func (*OCIPluginClient) ListCached ¶
func (c *OCIPluginClient) ListCached() ([]*LocalPlugin, error)
ListCached returns information about all cached plugins
func (*OCIPluginClient) ListCachedByArchitecture ¶
func (c *OCIPluginClient) ListCachedByArchitecture(arch string) ([]*LocalPlugin, error)
ListCachedByArchitecture returns cached plugins filtered by architecture
func (*OCIPluginClient) ListCachedByRegistry ¶
func (c *OCIPluginClient) ListCachedByRegistry(registry string) ([]*LocalPlugin, error)
ListCachedByRegistry returns cached plugins filtered by registry
func (*OCIPluginClient) SetActivePlugin ¶
func (c *OCIPluginClient) SetActivePlugin(name string, ref *OCIReference, params *OCIPluginParams) error
SetActivePlugin creates a symlink to mark a plugin as the active version
func (*OCIPluginClient) SetSecurityService ¶
func (c *OCIPluginClient) SetSecurityService(service SecurityService)
SetSecurityService sets the enterprise security service for signature verification If not set, falls back to the built-in verifier (CE mode)
type OCIPluginParams ¶
type OCIPluginParams struct {
Architecture string `json:"architecture"` // linux/amd64, linux/arm64
PublicKey string `json:"public_key"` // Key identifier or path
AuthConfig string `json:"auth_config"` // Auth configuration name
}
OCIPluginParams represents parsed parameters from OCI command
type OCIReference ¶
type OCIReference struct {
Registry string `json:"registry"` // nexus.example.com
Repository string `json:"repository"` // plugins/ner
Digest string `json:"digest"` // sha256:...
Tag string `json:"tag"` // optional, mainly for development
Params map[string]string `json:"params"` // Query parameters
}
OCIReference represents a parsed OCI reference
func NormalizeOCIReference ¶
func NormalizeOCIReference(ref *OCIReference) *OCIReference
NormalizeOCIReference ensures consistent formatting of OCI references
func (*OCIReference) FullReference ¶
func (r *OCIReference) FullReference() string
FullReference returns the complete OCI reference
Example ¶
ExampleOCIReference_FullReference demonstrates reference formatting
// Reference with digest
ref1 := &OCIReference{
Registry: "registry.com",
Repository: "plugins/test",
Digest: "sha256:abc123",
}
fmt.Printf("With digest: %s\n", ref1.FullReference())
// Reference with tag
ref2 := &OCIReference{
Registry: "registry.com",
Repository: "plugins/test",
Tag: "v1.0.0",
}
fmt.Printf("With tag: %s\n", ref2.FullReference())
// Reference without digest or tag (defaults to latest)
ref3 := &OCIReference{
Registry: "registry.com",
Repository: "plugins/test",
}
fmt.Printf("Default: %s\n", ref3.FullReference())
Output: With digest: registry.com/plugins/test@sha256:abc123 With tag: registry.com/plugins/test:v1.0.0 Default: registry.com/plugins/test:latest
func (*OCIReference) FullRepo ¶
func (r *OCIReference) FullRepo() string
FullRepo returns the full repository path (registry/repository)
type ORASFetcher ¶
type ORASFetcher struct {
// contains filtered or unexported fields
}
ORASFetcher handles OCI artifact fetching using oras-go
func NewORASFetcher ¶
func NewORASFetcher(config *OCIConfig) (*ORASFetcher, error)
NewORASFetcher creates a new ORAS fetcher
func (*ORASFetcher) CheckExists ¶
func (f *ORASFetcher) CheckExists(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (bool, error)
CheckExists verifies if an artifact exists in the registry without downloading
func (*ORASFetcher) Pull ¶
func (f *ORASFetcher) Pull(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (*ocispec.Descriptor, *PluginConfig, []byte, error)
Pull fetches a plugin from an OCI registry and returns the manifest, config, and binary data
func (*ORASFetcher) PullManifest ¶
func (f *ORASFetcher) PullManifest(ctx context.Context, ref *OCIReference, params *OCIPluginParams) (*ocispec.Descriptor, *ocispec.Manifest, error)
PullManifest fetches just the manifest without downloading layers
type PluginConfig ¶
type PluginConfig struct {
Name string `json:"name"`
Version string `json:"version"`
PluginAPI string `json:"plugin_api"`
OS string `json:"os"`
Arch string `json:"arch"`
LibC string `json:"libc,omitempty"`
HostMinVersion string `json:"host_min_version,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
Notes string `json:"notes,omitempty"`
}
PluginConfig represents the configuration metadata stored in the OCI artifact
type PluginMetadata ¶
type PluginMetadata struct {
Reference *OCIReference `json:"reference"`
Params *OCIPluginParams `json:"params"`
FetchTime time.Time `json:"fetch_time"`
Config *PluginConfig `json:"config"`
Verified bool `json:"verified"`
Size int64 `json:"size"`
LastAccessed time.Time `json:"last_accessed"`
Version string `json:"version"` // From plugin config
}
PluginMetadata represents cached metadata about a plugin
type RegistryAuth ¶
type RegistryAuth struct {
Username string `yaml:"username" json:"username"`
PasswordEnv string `yaml:"password_env" json:"password_env"` // Environment variable name
Token string `yaml:"token" json:"token"` // Direct token (less secure)
TokenEnv string `yaml:"token_env" json:"token_env"` // Token from environment
Entitlement string `yaml:"entitlement" json:"entitlement"` // Direct entitlement/bearer token
EntitlementEnv string `yaml:"entitlement_env" json:"entitlement_env"` // Entitlement token from environment
EntitlementUsername string `yaml:"entitlement_username" json:"entitlement_username"` // Username for entitlement auth (default: "token")
}
RegistryAuth holds authentication configuration for a specific registry
func LoadRegistryAuthForRegistry ¶
func LoadRegistryAuthForRegistry(registryName string) *RegistryAuth
LoadRegistryAuthForRegistry loads authentication for a specific registry
type SecurityService ¶
type SecurityService interface {
VerifySignature(ctx context.Context, ref *OCIReference, pubKeyID string) error
VerifyBundle(ctx context.Context, ref *OCIReference, issuer, subject string) error
VerifyWithPolicy(ctx context.Context, ref *OCIReference, policyPath string) error
}
SecurityService defines the interface for signature verification This allows the OCI client to use enterprise security features when available
type SignatureVerifier ¶
type SignatureVerifier struct {
// contains filtered or unexported fields
}
SignatureVerifier handles cosign signature verification
func NewSignatureVerifier ¶
func NewSignatureVerifier(config *OCIConfig) (*SignatureVerifier, error)
NewSignatureVerifier creates a new signature verifier
func (*SignatureVerifier) LoadPublicKeysFromDirectory ¶
func (v *SignatureVerifier) LoadPublicKeysFromDirectory(dir string) ([]string, error)
LoadPublicKeysFromDirectory loads all public keys from a directory
func (*SignatureVerifier) ValidatePublicKey ¶
func (v *SignatureVerifier) ValidatePublicKey(keyPath string) error
ValidatePublicKey checks if a public key file exists and is accessible
func (*SignatureVerifier) Verify ¶
func (v *SignatureVerifier) Verify(ctx context.Context, ref *OCIReference, pubKeyID string) error
Verify checks the cosign signature of an OCI artifact using cosign CLI
func (*SignatureVerifier) VerifyBundle ¶
func (v *SignatureVerifier) VerifyBundle(ctx context.Context, ref *OCIReference, issuer, subject string) error
VerifyBundle verifies a signature bundle for keyless signing
func (*SignatureVerifier) VerifyWithPolicy ¶
func (v *SignatureVerifier) VerifyWithPolicy(ctx context.Context, ref *OCIReference, policyPath string) error
VerifyWithPolicy verifies a signature using a policy file