Documentation
¶
Index ¶
- Constants
- Variables
- func AllowApp(ctx context.Context, appName string) bool
- func AppAccessError(ctx context.Context, appName string) error
- func BoundApp(ctx context.Context) string
- func CanBe[T, I any]() bool
- func ContextWithConnectionInfo(ctx context.Context, info *CurrentConnectionInfo) context.Context
- func ContextWithIdentity(ctx context.Context, identity *Identity) context.Context
- func NewResolveDecodeError(err error) error
- func NewResolveError(kind ResolveErrorKind, err error, msg string) error
- func NewResolveHTTPError(err error, format string, args ...interface{}) error
- func NewResolveLookupError(msg string) error
- func NewResolveStatusError(statusCode int) error
- func Propagator() propagation.TextMapPropagator
- func RegisterInterface[T any](fn any) bool
- func SetupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, err error)
- func SetupTracing(ctx context.Context, attrs ...attribute.KeyValue) (shutdown func(context.Context) error, err error)
- func Tracer() otrace.Tracer
- func WithRequireClientCerts(o *stateOptions)
- func WithSkipVerify(o *stateOptions)
- func Zero[T any]() T
- type ActorCall
- type ActorClient
- func (a *ActorClient) Call(ctx context.Context, name string, arg, ret any) error
- func (a *ActorClient) CallWithCaps(ctx context.Context, method string, args, result any, ...) error
- func (a *ActorClient) Close() error
- func (a *ActorClient) NewClient(capa *Capability) Client
- func (a *ActorClient) NewInlineCapability(i *Interface, lower any) (*InlineCapability, OID, *Capability)
- type ActorRegistry
- type ActorResolver
- type AuthMethod
- type Authenticator
- type Authorizer
- type Call
- type Capability
- type Client
- type CurrentConnectionInfo
- type DebugAuthResponse
- type DescField
- type DescFile
- type DescInterface
- type DescMethods
- type DescParamater
- type DescType
- type Dispatcher
- type ErrorCategory
- type ErrorCode
- type ErrorMessage
- type ForbidRestore
- type Generator
- type HasReconstructFromState
- type HasRestoreState
- type Identity
- type IfaceReg
- type Import
- type InlineCapability
- type Interface
- type InterfaceCreators
- type InterfaceDescriptor
- type InterfaceState
- type LocalActorRegistry
- type LocalOnlyAuthenticator
- type Method
- type NetworkCall
- func (c *NetworkCall) Args(v any)
- func (c *NetworkCall) IsAuthenticated() bool
- func (c *NetworkCall) NewCapability(i *Interface) *Capability
- func (c *NetworkCall) NewClient(capa *Capability) Client
- func (c *NetworkCall) RemoteAddr() string
- func (c *NetworkCall) Results(v any)
- func (c *NetworkCall) SkipArgs()
- func (c *NetworkCall) String() string
- type NetworkClient
- func (c *NetworkClient) Call(ctx context.Context, method string, args, result any) error
- func (c *NetworkClient) CallWithCaps(ctx context.Context, method string, args, result any, ...) error
- func (c *NetworkClient) Close() error
- func (c *NetworkClient) HasMethod(ctx context.Context, method string) bool
- func (c *NetworkClient) HasMethodParam(ctx context.Context, method, param string) bool
- func (c *NetworkClient) ListMethods(ctx context.Context) ([]string, error)
- func (c *NetworkClient) NewCapability(i *Interface, lower any) *Capability
- func (c *NetworkClient) NewClient(capa *Capability) Client
- func (c *NetworkClient) NewInlineCapability(i *Interface, lower any) (*InlineCapability, OID, *Capability)
- func (c *NetworkClient) String() string
- type NoOpAuthenticator
- type NoRestore
- type OID
- type ResolveError
- type ResolveErrorKind
- type ResolverFunc
- type Server
- type ServiceID
- type State
- type StateCommon
- type StateOption
- func WithAuthenticator(auth Authenticator) StateOption
- func WithAuthorizer(authz Authorizer) StateOption
- func WithBearerToken(token string) StateOption
- func WithBindAddr(addr string) StateOption
- func WithCert(certPath, keyPath string) StateOption
- func WithCertPEMs(certData, keyData []byte) StateOption
- func WithCertificateVerification(caCert []byte) StateOption
- func WithEndpoint(endpoint string) StateOption
- func WithLocalConnect(addr string) StateOption
- func WithLocalServer(addr string) StateOption
- func WithLogLevel(level slog.Level) StateOption
- func WithLogger(log *slog.Logger) StateOption
- type UnionField
Constants ¶
const ( TypeRW = iota TypeR TypeW )
const BootstrapOID = "!bootstrap"
Variables ¶
var ( ErrResolveHTTP = &ResolveError{Kind: ResolveHTTPError, Msg: "http request error"} ErrResolveStatus = &ResolveError{Kind: ResolveStatusError, Msg: "unexpected status code"} ErrResolveDecode = &ResolveError{Kind: ResolveDecodeError, Msg: "decode error"} ErrResolveLookup = &ResolveError{Kind: ResolveLookupError, Msg: "lookup error"} )
Exported sentinel errors for common resolve error kinds
var ( DefaultTransport http3.Transport DefaultQUICConfig quic.Config DefaultLogLevel = slog.LevelInfo )
ErrUnauthorized is returned when an app-scoped caller attempts to operate on an app they are not bound to.
Functions ¶
func AllowApp ¶ added in v0.5.0
AllowApp checks whether the current caller is permitted to operate on the named app. Callers that are not app-scoped (cert, JWT, anonymous) are always allowed. OIDC callers are restricted to the app their binding is for.
func AppAccessError ¶ added in v0.5.0
AppAccessError returns a descriptive error for an app-scoping denial.
func BoundApp ¶ added in v0.5.0
BoundApp returns the app name that the current OIDC caller is bound to, or empty string if the caller is not app-scoped.
func ContextWithConnectionInfo ¶ added in v0.10.0
func ContextWithConnectionInfo(ctx context.Context, info *CurrentConnectionInfo) context.Context
ContextWithConnectionInfo returns a copy of ctx carrying the given connection info, as observed by ConnectionInfo. The server populates this from the mTLS handshake; tests use it to exercise handlers that authorize on the peer cert.
func ContextWithIdentity ¶ added in v0.3.1
ContextWithIdentity returns a new context with the Identity stored
func NewResolveDecodeError ¶
NewResolveDecodeError creates a decode error
func NewResolveError ¶
func NewResolveError(kind ResolveErrorKind, err error, msg string) error
NewResolveError creates a new ResolveError with the specified kind and underlying error
func NewResolveHTTPError ¶
NewResolveHTTPError creates an HTTP request error
func NewResolveLookupError ¶
NewResolveLookupError creates a lookup error
func NewResolveStatusError ¶
NewResolveStatusError creates a status code error
func Propagator ¶
func Propagator() propagation.TextMapPropagator
func RegisterInterface ¶
func SetupOTelSDK ¶
setupOTelSDK bootstraps the OpenTelemetry pipeline. If it does not return an error, make sure to call shutdown for proper cleanup.
func SetupTracing ¶ added in v0.4.0
func SetupTracing(ctx context.Context, attrs ...attribute.KeyValue) (shutdown func(context.Context) error, err error)
SetupTracing configures OpenTelemetry tracing with an OTLP HTTP exporter. The exporter reads standard OTel env vars (OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, etc.) so no explicit configuration is needed. Extra resource attributes (e.g. cluster identity) can be passed in. Returns a shutdown function that flushes pending spans.
func WithRequireClientCerts ¶
func WithRequireClientCerts(o *stateOptions)
func WithSkipVerify ¶
func WithSkipVerify(o *stateOptions)
Types ¶
type ActorCall ¶
type ActorCall struct {
// contains filtered or unexported fields
}
func (*ActorCall) IsAuthenticated ¶ added in v0.3.1
IsAuthenticated returns true for actor calls since they are local and implicitly trusted.
func (*ActorCall) NewCapability ¶
func (a *ActorCall) NewCapability(i *Interface) *Capability
func (*ActorCall) NewClient ¶
func (a *ActorCall) NewClient(capa *Capability) Client
type ActorClient ¶
type ActorClient struct {
// contains filtered or unexported fields
}
func (*ActorClient) CallWithCaps ¶
func (a *ActorClient) CallWithCaps(ctx context.Context, method string, args, result any, caps map[OID]*InlineCapability) error
func (*ActorClient) Close ¶
func (a *ActorClient) Close() error
func (*ActorClient) NewClient ¶
func (a *ActorClient) NewClient(capa *Capability) Client
func (*ActorClient) NewInlineCapability ¶
func (a *ActorClient) NewInlineCapability(i *Interface, lower any) (*InlineCapability, OID, *Capability)
type ActorRegistry ¶
type ActorRegistry interface {
Register(ctx context.Context, name string, iface *Interface) error
Client(ctx context.Context, name string) (Client, error)
Close(ctx context.Context) error
}
func NewLocalActorRegistry ¶
func NewLocalActorRegistry() ActorRegistry
type ActorResolver ¶
type AuthMethod ¶ added in v0.3.1
type AuthMethod string
AuthMethod indicates how a caller was authenticated
const ( AuthMethodCert AuthMethod = "cert" // TLS client certificate AuthMethodJWT AuthMethod = "jwt" // JWT token (e.g., from Miren Cloud) AuthMethodAnonymous AuthMethod = "anonymous" // No authentication (public methods) AuthMethodToken AuthMethod = "token" // Bearer token (e.g., outboard) AuthMethodOIDC AuthMethod = "oidc" // External OIDC token (e.g., GitHub Actions) )
type Authenticator ¶
type Authenticator interface {
// Authenticate validates the request's credentials and returns the caller's identity.
// Returns:
// - (*Identity, nil) if credentials are valid
// - (nil, nil) if no credentials present or credentials are invalid
// - (nil, error) if an error occurred during authentication
Authenticate(ctx context.Context, r *http.Request) (*Identity, error)
}
Authenticator validates credentials and returns caller identity
type Authorizer ¶ added in v0.3.1
type Authorizer interface {
// Authorize checks if the identity is allowed to perform the action on the resource.
// For RPC methods, resource is typically the interface name (lowercase) and
// action is the method name (lowercase).
// Returns nil if allowed, or an error describing why access was denied.
Authorize(ctx context.Context, identity *Identity, resource, action string) error
}
Authorizer checks if an identity is allowed to perform an action on a resource
type Call ¶
type Call interface {
NewClient(capa *Capability) Client
Args(v any)
Results(v any)
NewCapability(i *Interface) *Capability
// IsAuthenticated returns true if the caller presented a valid TLS client certificate.
// This is used by methods that need to distinguish between authenticated and
// unauthenticated callers (e.g., runner registration allows unauthenticated Join
// but requires authentication for admin operations like CreateInvite).
IsAuthenticated() bool
}
type Capability ¶
type Capability struct {
OID OID `cbor:"0,keyasint" json:"oid"`
Address string `cbor:"1,keyasint" json:"address"`
User []byte `cbor:"2,keyasint" json:"owner"`
Issuer []byte `cbor:"3,keyasint" json:"issue"`
RestoreState *InterfaceState `cbor:"4,keyasint" json:"restore-state"`
Inline bool `cbor:"5,keyasint" json:"inline"`
}
type Client ¶
type Client interface {
CallWithCaps(ctx context.Context, method string, args, result any, caps map[OID]*InlineCapability) error
Call(ctx context.Context, method string, args, result any) error
NewInlineCapability(i *Interface, lower any) (*InlineCapability, OID, *Capability)
NewClient(capa *Capability) Client
Close() error
}
type CurrentConnectionInfo ¶
type CurrentConnectionInfo struct {
PeerSubject string
// PeerCertificate is the client certificate presented during the mTLS
// handshake, if any. When a CA is configured the server uses
// tls.VerifyClientCertIfGiven, so any cert present here has already been
// verified to chain to the cluster CA (r.TLS.VerifiedChains is non-empty).
PeerCertificate *x509.Certificate
}
func ConnectionInfo ¶
func ConnectionInfo(ctx context.Context) *CurrentConnectionInfo
type DebugAuthResponse ¶
type DebugAuthResponse struct {
Success bool `json:"success"`
ServerVersion string `json:"server_version,omitempty"`
AuthMethod string `json:"auth_method,omitempty"`
Identity string `json:"identity,omitempty"`
UserInfo map[string]string `json:"user_info,omitempty"`
Message string `json:"message,omitempty"`
}
DebugAuthResponse represents the response from the debug-auth endpoint
type DescFile ¶
type DescFile struct {
Imports map[string]Import `yaml:"imports"`
Types []*DescType `yaml:"types"`
Interfaces []*DescInterface `yaml:"interfaces"`
}
type DescInterface ¶
type DescInterface struct {
Name string `yaml:"name"`
Method []*DescMethods `yaml:"methods"`
Generic []string `yaml:"generic,omitempty"`
Constraints []string `yaml:"constraints,omitempty"`
}
type DescMethods ¶
type DescMethods struct {
Name string `yaml:"name"`
Index int `yaml:"index"`
Parameters []*DescParamater `yaml:"parameters"`
Results []*DescParamater `yaml:"results"`
// Public marks this method as accessible without TLS client certificate authentication.
// Public methods still require capability-level auth (Ed25519 signatures) but allow
// unauthenticated callers (e.g., for registration flows where the client doesn't have certs yet).
Public bool `yaml:"public,omitempty"`
}
type DescParamater ¶
type DescType ¶
type DescType struct {
Type string `yaml:"type"`
Fields []*DescField `yaml:"fields"`
Compact bool `yaml:"compact,omitempty"`
Generic []string `yaml:"generic,omitempty"`
Constraints []string `yaml:"constraints,omitempty"`
// contains filtered or unexported fields
}
func (*DescType) CalculateOffsets ¶
type Dispatcher ¶
type ErrorCategory ¶
type ErrorCategory interface {
ErrorCategory() string
}
type ErrorMessage ¶
type ErrorMessage interface {
ErrorMessage() string
}
type ForbidRestore ¶
type ForbidRestore interface {
// contains filtered or unexported methods
}
type Generator ¶
type Generator struct {
Imports map[string]Import
Types []*DescType
Interfaces []*DescInterface
// contains filtered or unexported fields
}
func NewGenerator ¶
type HasReconstructFromState ¶
type HasReconstructFromState interface {
ReconstructFromState(is *InterfaceState) (*Interface, error)
}
type HasRestoreState ¶
type Identity ¶ added in v0.3.1
type Identity struct {
// Subject is the primary identifier (cert CN, JWT subject, etc.)
Subject string
// Groups contains group memberships (from JWT claims, etc.)
Groups []string
// Method indicates how the caller was authenticated
Method AuthMethod
// Metadata holds auth-method-specific data (e.g., OrganizationID for cloud auth)
Metadata map[string]any
}
Identity represents an authenticated caller
func IdentityFromContext ¶ added in v0.3.1
IdentityFromContext retrieves the Identity from the context, if present
type IfaceReg ¶
type IfaceReg struct {
// contains filtered or unexported fields
}
func NewIfaceReg ¶
func NewIfaceReg() *IfaceReg
type InlineCapability ¶
type InlineCapability struct {
*Capability
*Interface
}
type Interface ¶
type Interface struct {
// contains filtered or unexported fields
}
func NewInterface ¶
func (*Interface) SetAroundContext ¶
type InterfaceCreators ¶
type InterfaceCreators struct {
// contains filtered or unexported fields
}
func NewInterfaceCreators ¶
func NewInterfaceCreators() *InterfaceCreators
type InterfaceDescriptor ¶
type InterfaceDescriptor struct {
}
type InterfaceState ¶
type InterfaceState struct {
Category string `cbor:"0,keyasint" json:"category"`
Interface string `cbor:"1,keyasint" json:"interface"`
Data any `cbor:"2,keyasint" json:"data"`
}
func (*InterfaceState) Decode ¶
func (i *InterfaceState) Decode(v any) error
type LocalActorRegistry ¶
type LocalActorRegistry struct {
// contains filtered or unexported fields
}
type LocalOnlyAuthenticator ¶ added in v0.2.0
type LocalOnlyAuthenticator struct{}
LocalOnlyAuthenticator requires a valid TLS client certificate. Used when cloud authentication is not enabled.
func (*LocalOnlyAuthenticator) Authenticate ¶ added in v0.3.1
type Method ¶
type Method struct {
Name string
InterfaceName string
Index int
Handler func(ctx context.Context, call Call) error
// Public marks this method as accessible without TLS client certificate authentication.
// The RPC layer will reject unauthenticated calls to non-public methods automatically.
Public bool
// Params lists the method's parameter names in schema order. It powers
// parameter-level capability detection: a client can ask whether a server
// understands a specific parameter (e.g. one added after the method first
// shipped) instead of only whether the method exists. See HasMethodParam.
Params []string
}
type NetworkCall ¶
type NetworkCall struct {
// contains filtered or unexported fields
}
func Local ¶
func Local(args ...any) *NetworkCall
func (*NetworkCall) Args ¶
func (c *NetworkCall) Args(v any)
func (*NetworkCall) IsAuthenticated ¶ added in v0.3.1
func (c *NetworkCall) IsAuthenticated() bool
IsAuthenticated returns true if the caller presented a valid TLS client certificate, or if this is a local call (used in tests).
func (*NetworkCall) NewCapability ¶
func (c *NetworkCall) NewCapability(i *Interface) *Capability
func (*NetworkCall) NewClient ¶
func (c *NetworkCall) NewClient(capa *Capability) Client
func (*NetworkCall) RemoteAddr ¶
func (c *NetworkCall) RemoteAddr() string
func (*NetworkCall) Results ¶
func (c *NetworkCall) Results(v any)
func (*NetworkCall) SkipArgs ¶ added in v0.2.0
func (c *NetworkCall) SkipArgs()
SkipArgs consumes and discards args if they haven't been consumed yet. This prevents leftover args data from being misinterpreted as the next request.
func (*NetworkCall) String ¶
func (c *NetworkCall) String() string
type NetworkClient ¶
type NetworkClient struct {
State *State
// contains filtered or unexported fields
}
func LocalClient ¶
func LocalClient(iface *Interface) *NetworkClient
func (*NetworkClient) CallWithCaps ¶
func (c *NetworkClient) CallWithCaps(ctx context.Context, method string, args, result any, caps map[OID]*InlineCapability) error
func (*NetworkClient) Close ¶
func (c *NetworkClient) Close() error
func (*NetworkClient) HasMethod ¶
func (c *NetworkClient) HasMethod(ctx context.Context, method string) bool
HasMethod checks if the remote interface supports a given method. Returns false if the method doesn't exist or if the server doesn't support introspection.
func (*NetworkClient) HasMethodParam ¶ added in v0.11.1
func (c *NetworkClient) HasMethodParam(ctx context.Context, method, param string) bool
HasMethodParam reports whether the remote interface's method accepts a given parameter. This distinguishes servers that have a method from servers that have a newer revision of it with an added parameter. Returns false if the method or parameter is absent, or if the server is too old to report parameters at all (introspection predates this, or the method itself).
func (*NetworkClient) ListMethods ¶
func (c *NetworkClient) ListMethods(ctx context.Context) ([]string, error)
ListMethods returns the list of methods available on this capability. Returns an error if the server doesn't support method introspection (old servers).
func (*NetworkClient) NewCapability ¶
func (c *NetworkClient) NewCapability(i *Interface, lower any) *Capability
func (*NetworkClient) NewClient ¶
func (c *NetworkClient) NewClient(capa *Capability) Client
func (*NetworkClient) NewInlineCapability ¶
func (c *NetworkClient) NewInlineCapability(i *Interface, lower any) (*InlineCapability, OID, *Capability)
func (*NetworkClient) String ¶
func (c *NetworkClient) String() string
type NoOpAuthenticator ¶
type NoOpAuthenticator struct{}
NoOpAuthenticator allows all requests without checking credentials. Used for testing only.
func (*NoOpAuthenticator) Authenticate ¶ added in v0.3.1
type ResolveError ¶
type ResolveError struct {
Kind ResolveErrorKind
Err error
Msg string
StatusCode int // HTTP status code for ResolveStatusError
}
ResolveError represents an error that occurred during capability resolution
func (*ResolveError) Error ¶
func (e *ResolveError) Error() string
func (*ResolveError) Is ¶
func (e *ResolveError) Is(target error) bool
func (*ResolveError) Unwrap ¶
func (e *ResolveError) Unwrap() error
type ResolveErrorKind ¶
type ResolveErrorKind int
ResolveErrorKind represents different kinds of capability resolution errors
const ( ResolveHTTPError ResolveErrorKind = iota ResolveStatusError ResolveDecodeError ResolveLookupError )
type ResolverFunc ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) ExposeValue ¶
type ServiceID ¶ added in v0.3.1
type ServiceID = string
ServiceID represents an RPC service identifier. These are used with RPCClient() and server.ExposeValue() to identify services.
Currently a type alias for incremental adoption. When all call sites use constants, this can become a distinct type (type ServiceID string) and function signatures can be updated for full type safety.
const (
ServiceRunner ServiceID = "dev.miren.runtime/runner"
)
Runtime service identifiers. Add new services here to maintain type safety and avoid string typos.
type State ¶
type State struct {
*StateCommon
// contains filtered or unexported fields
}
func (*State) ListenAddr ¶
func (*State) LoopbackAddr ¶
type StateCommon ¶
type StateCommon struct {
// contains filtered or unexported fields
}
type StateOption ¶
type StateOption func(*stateOptions)
func WithAuthenticator ¶
func WithAuthenticator(auth Authenticator) StateOption
func WithAuthorizer ¶ added in v0.3.1
func WithAuthorizer(authz Authorizer) StateOption
func WithBearerToken ¶
func WithBearerToken(token string) StateOption
func WithBindAddr ¶
func WithBindAddr(addr string) StateOption
func WithCert ¶
func WithCert(certPath, keyPath string) StateOption
func WithCertPEMs ¶
func WithCertPEMs(certData, keyData []byte) StateOption
func WithCertificateVerification ¶
func WithCertificateVerification(caCert []byte) StateOption
func WithEndpoint ¶
func WithEndpoint(endpoint string) StateOption
func WithLocalConnect ¶
func WithLocalConnect(addr string) StateOption
func WithLocalServer ¶
func WithLocalServer(addr string) StateOption
func WithLogLevel ¶
func WithLogLevel(level slog.Level) StateOption
func WithLogger ¶
func WithLogger(log *slog.Logger) StateOption