actor

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2024 License: Apache-2.0 Imports: 23 Imported by: 0

README

NuActor: Secure Actor Programming in Decentralized Systems

NuActor is a framework designed for secure actor oriented programming in decentralized systems. The framework utilizes zero trust interactions, whereby every message is authenticated individually at the point of interaction. The system supports fine-grained capabilities, anchored in decentralized identifiers (see DID) and effected with user controlled authorization networks (see UCAN).

Secure Interactions in Decentralized Systems

Decentralized systems are distributed systems where there are different stake holders and controlling entities who are mutually distrustful. Actors are ideally suited for modeling and programming such systems, as they are able to express concurrency, distribution, and agency on behalf of their controllers.

However, given the open ended computing nature of decentralized systems, there is a fundamental problem in securing interactions. Because the system is open, there is effectively no perimeter; the messages are coming from the Internet, and can potentially originate in malicious or hostile actors.

NuActor takes the following approach:

  • The only entity an actor can fully trust is itself and its controller.
  • All messages invoking a behavior carry with them capability tokens that authorize them to perform the invocation.
  • Invocations are checked at dispatch so that it is always verified whether an invocation is allowed, anchored on the entities the actor trusts for the required capabilities.
  • There is no central authority; every entity (identified by a DID) can issue their own capability tokens and anchor trust wherever they want.
  • There are certain entities in the open public networks that may be marginally trusted to vet users (KYC) for invoking public behaviors. The set of such entities is open, and everyone is free to trust whoever they want. The creators of the network at bootstrap are good candidates for such entities.
  • Trust is ephemeral and can be revoked at all times.
  • In effect, users are in control of authorization in the network (UCAN!)

Capabilities

Behaviors and the Capability Namespace

Capabilities are defined in a hierarchical namespace, akin to the UNIX file system structure. The root capability, which implicitly has all other capabilities, is /. Every other capability extends this path, separating the namespace with additional /s. A capability is narrower than another if it is a subpath in the UNIX sense. So /A imples /A/B and so on, but /A does not imply /B.

Behaviors have names that directly map to capabilities. So the behavior namespace is also hierarchical, allowing for easy automated matching of behaviors to capabilities.

Capability Tokens

Capabilities are expressed with a token, which is a structured object signed by the private key of the issuer. The issuer is in the token as a DID, which allows any entity inspecting the token to verify by retrieving the public key associated with the DID. Typically these are key DIDs, which embed the public key directly.

The structure of the token is as following:

type Token struct {
	// DMS tokens
	DMS *DMSToken `json:"dms,omitempty"`
}

type DMSToken struct {
	Action     Action       `json:"act"`
	Issuer     did.DID      `json:"iss"`
	Subject    did.DID      `json:"sub"`
	Audience   did.DID      `json:"aud"`
	Topic      []Capability `json:"topic,omitempty"`
	Capability []Capability `json:"cap"`
	Nonce      []byte       `json:"nonce"`
	Expire     uint64       `json:"exp"`
	Depth      uint64       `json:"depth,omitempty"`
	Chain      *Token       `json:"chain,omitempty"`
	Signature  []byte       `json:"sig,omitempty"`
}

The Subject is the DID of the entity to which the Issuer grants (if the chain is empty) or delegates the capabilities listed in the Capability field and the broadcast topics listed in the Topic field. The audience may be empty, but when present it restricts the receiver of invocations to a specified entity.

The Action can be any of Delegate, Invoke or Broadcast, with revocations to be added in the very near future.

If the Action is Delegate then the Issuer confers to the Subject the ability to further create new tokens, chained on this one.

If the Action is Invoke or Broadcast, then the token confers to the Subject the capability to make an invocation or broadcast to a behavior. Such tokens are terminal and cannot be chained further.

The Chain field of the token inlines the chain of tokens (could be a single one) on which the capability transfer is anchored on.

Note that the delegation spread can be restricted by the issuer of a token using the Depth field. If set, it is the maximum chain depth at which a token can appear. If it appears deeper in the chain, the token chain fails verification.

Finally, all capabilities have an expiration time (in UNIX nanoseconds). An expired token cannot be used any more and fails verification.

Anchors of Trust

In order to sign and verify token chains, the receiver needs to install some trust anchors. Specifically, we distinguish 3 types of anchors:

  • root anchors which are DIDs that are fully trusted for input with implicit root capability. Any valid chain anchored on one of our roots will be admissible.
  • require anchors which are tokens that act as side chains for marginal input trust. These tokens admit a chain anchored in their subject, as long as the capability and depth constraints are satisfied.
  • provide anchors which are tokens that anchour the actor's output invocation and broadcast tokens. These are delegations which the actor can use to prove that it has the required capabilities, beside self-signing.
Token Chain Verification

The token chain is verified with strict rules:

  • The entire chain must not have expired.
  • Each token in the chain cannot expire before its chain.
  • Each token must match the Issuer with the Subject of its chain.
  • Each token in the chain can only narrow (attenuate) the capabilities of its chain.
  • Each token in the chain can only narrow the audience; an empty audience ("to whom it may concern") can only be narrowed once to an audience DID and all chains build on top must concern the same audience.
  • The chain of a token can only delegate.
  • The signature must verify.
  • The whole chain must recursively verify.

Programming NuActors

The actor package

The Go implementation of NuActor lives in the actor package of DMS.

To use it:

import "gitlab.com/nunet/device-management-service/actor"

The network substrate for NuActor is currently implemented with libp2p, with broadcast using gossipsub.

The Security Context

Each actor has a key pair for signing its messages; the actor's id is the public key itself and is embedded in every message it sends. The private key for the actor lives inside the actor's SecurityContext.

In general:

  • each actor has its own SecurityContext; however, if the actor wants to create multiple subactors and act as an ensemble, it can share it.
  • the key pair is ephemeral; however, the root actor in the process has a persistent key pair, which matches the libp2p key and Peer ID. This makes the actor reachable by default given its Peer ID or DID.
  • every actor in the process shares a DID, which is the ID of the root actor.

Each Security Context is anchored in a process wide CapabilityContext, which stores anchors of trust and ephemeral tokes consumed during actor interactions.

The CapabilityContext itself is anchored on a TrustCotext, which contains the private key for the root actor and the process itself.

The following diagram depicts this relathionship: Actor Security Context

Actor Handles
type Handle struct {
	ID      ID      `json:"id"`
	DID     DID     `json:"did"`
	Address Address `json:"addr"`
}

type Address struct {
	HostID       string `json:"host,omitempty"`
	InboxAddress string `json:"inbox,omitempty"`
}

Messages
type Envelope struct {
	To         Handle          `json:"to"`
	Behavior   string          `json:"be"`
	From       Handle          `json:"from"`
	Nonce      uint64          `json:"nonce"`
	Options    EnvelopeOptions `json:"opt"`
	Message    []byte          `json:"msg"`
	Capability []byte          `json:"cap,omitempty"`
	Signature  []byte          `json:"sig,omitempty"`

	Discard func() `json:"-"`
}

type EnvelopeOptions struct {
	Expire  uint64 `json:"exp"`
	ReplyTo string `json:"cont,omitempty"`
	Topic   string `json:"topic,omitempty"`
}

The Actor Interfaces
type Actor interface {
	Context() context.Context
	Handle() Handle
	Security() SecurityContext

	AddBehavior(behavior string, continuation Behavior, opt ...BehaviorOption) error
	RemoveBehavior(behavior string)

	Receive(msg Envelope) error
	Send(msg Envelope) error
	Invoke(msg Envelope) (<-chan Envelope, error)

	Publish(msg Envelope) error
	Subscribe(topic string, setup ...BroadcastSetup) error

	Start() error
	Stop() error

	Limiter() RateLimiter
}
Sending Messages

The following code shows how to send a message at the call site:

	msg, _ := actor.Message(
		myActor.Handle(),
		destinationHandle,
		"/some/behavior",
		MyMessage{ /*...*/ },
	)
	_ = myActor.Send(msg)

At the receiver this is how we can react to the message:

	_ = myActor.AddBehavior("/some/behavior", func(msg Envelope) {
		defer msg.Discard()
		// process message
	})

Notice the _ for errors, please don't do this in production.

Interactive Invocations

Interactive invocations are a combinations of a synchronous send and wait for a reply.

At the call site:

	msg, _ := actor.Message(
		myActor.Handle(),
		destinationHandle,
		"/some/behavior",
		MyMessage{ /*...*/ },
	)
	replyChan, _ := myActorInvoke(msg)
	reply := <-replyChan
	defer reply.Discard()
	// process reply ...

At the receiver this is how we can create an interactive behavior:

	_ = myActor.AddBehavior("/some/behavior", func(msg Envelope) {
		defer msg.Discard()
		reply, _ := actor.ReplyTo(
			msg
			MyReply{ /*...*/ },
		)
		_ = mayActor.Send(MyReply)
	})

Again, notice the _ for errors, please don't do this in production.

Broadcast

We can easily broadcast messages to all interested parties in a topic.

At the broadcast site:

	msg, _ := actor.Message(
		myActor.Handle(),
		destinationHandle,
		"/some/broadcast/behavior",
		MyMessage{ /*...*/ },
		actor.WithMessageTopic("/some/topic"),
	)
	_ = actor.Publish(msg)

At the receiver:

	_ = myActor.Subscribe("/some/topic")
	_ = myActor.AddBehavior("/some/broadcast/behavior", func(msg Envelope) {
		defer msg.Discard()
		// process the message
	}, actor.WithBehaviorTopic("/some/topic"),
	)
Discarding Capability Tokens

Notice all these defer msg.Discard() in the examples above; this is necessary to ensure deterministic cleanup of tokens exchanged during the interaction. Please do not forget that.

Behind the Scenes

Sending a Message

Send a Message

Invoking a Behavior

Behavior Invocation

Verifying Capabilities

Invocation Token Chain

Documentation

Index

Constants

View Source
const (
	HealthCheckBehavior = "/dms/actor/healthcheck"

	HealthCheckInterval      = 30 * time.Second
	HealthCheckGrantDuration = 2 * time.Hour
)

Variables

View Source
var (
	DefaultDispatchGCInterval = 120 * time.Second
	DefaultDispatchWorkers    = 1
)
View Source
var (
	ErrInvalidMessage         = errors.New("invalid message")
	ErrMissingOption          = errors.New("missing option")
	ErrSignatureVerification  = errors.New("signature verification failed")
	ErrInvalidSecurityContext = errors.New("invalid security context")
	ErrMessageExpired         = errors.New("message expired")
	ErrBadSender              = errors.New("bad sender")
	ErrRateLimitExceeded      = errors.New("rate limited exceeded")

	ErrTODO = errors.New("TODO")
)

Functions

func AllowBroadcast

func AllowBroadcast(t *testing.T, actor1, actor2 ucan.CapabilityContext, root1, root2 did.TrustContext, root1DID, root2DID did.DID, topic string, actorCap ...Capability)

func AllowReciprocal

func AllowReciprocal(t *testing.T, actorCap ucan.CapabilityContext, rootTrust did.TrustContext, rootDID, otherRootDID did.DID, cap string)

func MakeCapabilityContext

func MakeCapabilityContext(t *testing.T, actorDID, rootDID did.DID, trust, root did.TrustContext) ucan.CapabilityContext

func MakeExpiry

func MakeExpiry(d time.Duration) uint64

func MakeRootTrustContext

func MakeRootTrustContext(t *testing.T) (did.DID, did.TrustContext)

func MakeTrustContext

func MakeTrustContext(t *testing.T, privk crypto.PrivKey) (did.DID, did.TrustContext)

func NewLibp2pNetwork

func NewLibp2pNetwork(t *testing.T, bootstrap []multiaddr.Multiaddr) ([]multiaddr.Multiaddr, crypto.PrivKey, *libp2p.Libp2p)

Types

type Actor

type Actor interface {
	Context() context.Context
	Handle() Handle
	Security() SecurityContext

	AddBehavior(behavior string, continuation Behavior, opt ...BehaviorOption) error
	RemoveBehavior(behavior string)

	Receive(msg Envelope) error
	Send(msg Envelope) error
	Invoke(msg Envelope) (<-chan Envelope, error)

	Publish(msg Envelope) error
	Subscribe(topic string, setup ...BroadcastSetup) error

	Start() error
	Stop() error

	CreateChild(super Handle, params BasicActorParams) (*BasicActor, error)

	Limiter() RateLimiter
}

Actor is the local interface to the actor system

type Address

type Address struct {
	HostID       string `json:"host,omitempty"`
	InboxAddress string `json:"inbox,omitempty"`
}

ActorAddress is a raw actor address representation

func AddressFromString

func AddressFromString(_ string) (Address, error)

func (*Address) Empty

func (a *Address) Empty() bool

func (*Address) String

func (a *Address) String() string

type BasicActor

type BasicActor struct {
	// contains filtered or unexported fields
}

func CreateActor

func CreateActor(t *testing.T, peer *libp2p.Libp2p, cap ucan.CapabilityContext) *BasicActor

func New

func New(
	supervisor Handle,
	net network.Network,
	security *BasicSecurityContext,
	limiter RateLimiter,
	params BasicActorParams,
	self Handle,
	opt ...DispatchOption,
) (*BasicActor, error)

New creates a new basic actor.

func (*BasicActor) AddBehavior

func (a *BasicActor) AddBehavior(behavior string, continuation Behavior, opt ...BehaviorOption) error

func (*BasicActor) Context

func (a *BasicActor) Context() context.Context

func (*BasicActor) CreateChild

func (a *BasicActor) CreateChild(
	super Handle,
	params BasicActorParams,
) (*BasicActor, error)

func (*BasicActor) Handle

func (a *BasicActor) Handle() Handle

func (*BasicActor) Invoke

func (a *BasicActor) Invoke(msg Envelope) (<-chan Envelope, error)

func (*BasicActor) Limiter

func (a *BasicActor) Limiter() RateLimiter

func (*BasicActor) Publish

func (a *BasicActor) Publish(msg Envelope) error

func (*BasicActor) Receive

func (a *BasicActor) Receive(msg Envelope) error

func (*BasicActor) RemoveBehavior

func (a *BasicActor) RemoveBehavior(behavior string)

func (*BasicActor) Security

func (a *BasicActor) Security() SecurityContext

func (*BasicActor) Send

func (a *BasicActor) Send(msg Envelope) error

func (*BasicActor) Start

func (a *BasicActor) Start() error

func (*BasicActor) Stop

func (a *BasicActor) Stop() error

func (*BasicActor) Subscribe

func (a *BasicActor) Subscribe(topic string, setup ...BroadcastSetup) error

type BasicActorParams

type BasicActorParams struct{}

type BasicRateLimiter

type BasicRateLimiter struct {
	// contains filtered or unexported fields
}

func (*BasicRateLimiter) Acquire

func (l *BasicRateLimiter) Acquire(msg Envelope) error

func (*BasicRateLimiter) Allow

func (l *BasicRateLimiter) Allow(msg Envelope) bool

func (*BasicRateLimiter) Config

func (l *BasicRateLimiter) Config() RateLimiterConfig

func (*BasicRateLimiter) Release

func (l *BasicRateLimiter) Release(msg Envelope)

func (*BasicRateLimiter) SetConfig

func (l *BasicRateLimiter) SetConfig(cfg RateLimiterConfig)

type BasicSecurityContext

type BasicSecurityContext struct {
	// contains filtered or unexported fields
}

func NewBasicSecurityContext

func NewBasicSecurityContext(pubk crypto.PubKey, privk crypto.PrivKey, cap ucan.CapabilityContext) (*BasicSecurityContext, error)

func (*BasicSecurityContext) Capability

func (*BasicSecurityContext) DID

func (s *BasicSecurityContext) DID() DID

func (*BasicSecurityContext) Discard

func (s *BasicSecurityContext) Discard(msg Envelope)

func (*BasicSecurityContext) ID

func (s *BasicSecurityContext) ID() ID

func (*BasicSecurityContext) Nonce

func (s *BasicSecurityContext) Nonce() uint64

func (*BasicSecurityContext) PrivKey

func (s *BasicSecurityContext) PrivKey() crypto.PrivKey

func (*BasicSecurityContext) Provide

func (s *BasicSecurityContext) Provide(msg *Envelope, invoke []Capability, delegate []Capability) error

func (*BasicSecurityContext) ProvideBroadcast

func (s *BasicSecurityContext) ProvideBroadcast(msg *Envelope, topic string, broadcast []Capability) error

func (*BasicSecurityContext) Require

func (s *BasicSecurityContext) Require(msg Envelope, cap []Capability) error

func (*BasicSecurityContext) RequireBroadcast

func (s *BasicSecurityContext) RequireBroadcast(msg Envelope, topic string, broadcast []Capability) error

func (*BasicSecurityContext) Sign

func (s *BasicSecurityContext) Sign(msg *Envelope) error

func (*BasicSecurityContext) Verify

func (s *BasicSecurityContext) Verify(msg Envelope) error

type Behavior

type Behavior func(msg Envelope)

type BehaviorOption

type BehaviorOption func(opt *BehaviorOptions) error

func WithBehaviorCapability

func WithBehaviorCapability(require ...Capability) BehaviorOption

func WithBehaviorExpiry

func WithBehaviorExpiry(expire uint64) BehaviorOption

func WithBehaviorOneShot

func WithBehaviorOneShot(oneShot bool) BehaviorOption

func WithBehaviorTopic

func WithBehaviorTopic(topic string) BehaviorOption

type BehaviorOptions

type BehaviorOptions struct {
	Capability []Capability
	Expire     uint64
	OneShot    bool
	Topic      string
}

type BehaviorState

type BehaviorState struct {
	// contains filtered or unexported fields
}

func (*BehaviorState) Expired

func (b *BehaviorState) Expired(now time.Time) bool

type BroadcastSetup

type BroadcastSetup func(topic string) error

type Capability

type Capability = ucan.Capability

type DID

type DID = did.DID

type Dispatch

type Dispatch struct {
	// contains filtered or unexported fields
}

Dispatch provides a reaction kernel with multithreaded dispatch and oneshot continuations.

func NewDispatch

func NewDispatch(sctx SecurityContext, opt ...DispatchOption) *Dispatch

func (*Dispatch) AddBehavior

func (k *Dispatch) AddBehavior(behavior string, continuation Behavior, opt ...BehaviorOption) error

func (*Dispatch) Context

func (k *Dispatch) Context() context.Context

func (*Dispatch) Receive

func (k *Dispatch) Receive(msg Envelope) error

func (*Dispatch) RemoveBehavior

func (k *Dispatch) RemoveBehavior(behavior string)

func (*Dispatch) Start

func (k *Dispatch) Start()

func (*Dispatch) Stop

func (k *Dispatch) Stop()

type DispatchOption

type DispatchOption func(o *DispatchOptions)

func WithDispatchGCInterval

func WithDispatchGCInterval(dt time.Duration) DispatchOption

func WithDispatchWorkers

func WithDispatchWorkers(count int) DispatchOption

func WithRateLimiter

func WithRateLimiter(limiter RateLimiter) DispatchOption

type DispatchOptions

type DispatchOptions struct {
	Limiter    RateLimiter
	GCInterval time.Duration
	Workers    int
}

type Envelope

type Envelope struct {
	To         Handle          `json:"to"`
	Behavior   string          `json:"be"`
	From       Handle          `json:"from"`
	Nonce      uint64          `json:"nonce"`
	Options    EnvelopeOptions `json:"opt"`
	Message    []byte          `json:"msg"`
	Capability []byte          `json:"cap,omitempty"`
	Signature  []byte          `json:"sig,omitempty"`

	Discard func() `json:"-"`
}

Envelope is the envelope for messages in the actor system

func Message

func Message(src Handle, dest Handle, behavior string, payload interface{}, opt ...MessageOption) (Envelope, error)

Message constructs a new message envelope and applies the options

func ReplyTo

func ReplyTo(msg Envelope, payload interface{}, opt ...MessageOption) (Envelope, error)

func (*Envelope) Expired

func (msg *Envelope) Expired() bool

func (*Envelope) Expiry

func (msg *Envelope) Expiry() time.Time

convert the expiration to a time.Time object

func (*Envelope) IsBroadcast

func (msg *Envelope) IsBroadcast() bool

func (*Envelope) SignatureData

func (msg *Envelope) SignatureData() ([]byte, error)

type EnvelopeOptions

type EnvelopeOptions struct {
	Expire  uint64 `json:"exp"`
	ReplyTo string `json:"cont,omitempty"`
	Topic   string `json:"topic,omitempty"`
}

EnvelopeOptions are sender specified options for processing an envelope

type Handle

type Handle struct {
	ID      ID      `json:"id"`
	DID     DID     `json:"did"`
	Address Address `json:"addr"`
}

ActorHandle is a handle for naming an actor reachable in the network

func HandleFromDID

func HandleFromDID(dest string) (Handle, error)

func HandleFromPeerID

func HandleFromPeerID(dest string) (Handle, error)

func HandleFromString

func HandleFromString(_ string) (Handle, error)

func (*Handle) Empty

func (h *Handle) Empty() bool

func (Handle) Equal

func (h Handle) Equal(other Handle) bool

func (*Handle) String

func (h *Handle) String() string

type HealthCheckResponse

type HealthCheckResponse struct {
	OK    bool
	Error string
}

type ID

type ID = crypto.ID

type Info

type Info struct {
	Addr     Handle
	Parent   Handle
	Children []Handle
}

type MessageOption

type MessageOption func(msg *Envelope) error

func WithMessageExpiry

func WithMessageExpiry(expiry uint64) MessageOption

WithMessageExpiry sets the message expiry

NOTE: created with Message message have an implicit timeout of DefaultMessageTimeout

func WithMessageExpiryTime

func WithMessageExpiryTime(t time.Time) MessageOption

WithMessageExpiry TODO

func WithMessageReplyTo

func WithMessageReplyTo(replyto string) MessageOption

WithMessageReplyTo sets the message replyto behavior

NOTE: ReplyTo is set implicitly in Invoke and the appropriate capability

tokens are delegated by Provide.

func WithMessageSignature

func WithMessageSignature(sctx SecurityContext, invoke []Capability, delegate []Capability) MessageOption

WithMessageContext provides the necessary envelope and signs it.

NOTE: If this option must be passed last, otherwise the signature will be invalidated by further modifications.

NOTE: Signing is implicit in Send.

func WithMessageSource

func WithMessageSource(source Handle) MessageOption

WithMessageSource sets the message source

func WithMessageTimeout

func WithMessageTimeout(timeo time.Duration) MessageOption

WithMessageTimeout sets the message expiration from a relative timeout

NOTE: messages created with Message have an implicit timeout of DefaultMessageTimeout

func WithMessageTopic

func WithMessageTopic(topic string) MessageOption

WithMessageTopic sets the broadcast topic

type NoRateLimiter

type NoRateLimiter struct{}

NoRateLimiter is the null limiter, that does not rate limit

func (NoRateLimiter) Acquire

func (l NoRateLimiter) Acquire(_ Envelope) error

func (NoRateLimiter) Allow

func (l NoRateLimiter) Allow(_ Envelope) bool

implementation

func (NoRateLimiter) Config

func (l NoRateLimiter) Config() RateLimiterConfig

func (NoRateLimiter) Release

func (l NoRateLimiter) Release(_ Envelope)

func (NoRateLimiter) SetConfig

func (l NoRateLimiter) SetConfig(_ RateLimiterConfig)

type RateLimiter

type RateLimiter interface {
	Allow(msg Envelope) bool
	Acquire(msg Envelope) error
	Release(msg Envelope)

	Config() RateLimiterConfig
	SetConfig(cfg RateLimiterConfig)
}

RateLimiter implements a stateful resource access limiter This is necessary to combat spam attacks and ensure that our system does not become overloaded with too many goroutines.

func NewRateLimiter

func NewRateLimiter(cfg RateLimiterConfig) RateLimiter

type RateLimiterConfig

type RateLimiterConfig struct {
	PublicLimitAllow      int
	PublicLimitAcquire    int
	BroadcastLimitAllow   int
	BroadcastLimitAcquire int
	TopicDefaultLimit     int
	TopicLimit            map[string]int
}

func DefaultRateLimiterConfig

func DefaultRateLimiterConfig() RateLimiterConfig

func (*RateLimiterConfig) Valid

func (cfg *RateLimiterConfig) Valid() bool

type Registry

type Registry interface {
	Actors() map[string]Info
	Add(a Handle, parent Handle, children []Handle) error
	Get(a Handle) (Info, bool)
	SetParent(a Handle, parent Handle) error
	GetParent(a Handle) (Handle, bool)
}

type SecurityContext

type SecurityContext interface {
	ID() ID
	DID() DID
	Nonce() uint64
	PrivKey() crypto.PrivKey

	// Require checks the capability token(s).
	// It succeeds if and only if
	// - the signature is valid
	// - the capability token(s) in the envelope grants the origin actor ID/DID
	//   any of the specified capabilities.
	Require(msg Envelope, invoke []Capability) error

	// Provide populates the envelope with necessary capability tokens and signs it.
	// the envelope is modified in place
	Provide(msg *Envelope, invoke []Capability, delegate []Capability) error

	// Require verifies the envelope and checks the capability tokens
	// for a broadcast topic
	RequireBroadcast(msg Envelope, topic string, broadcast []Capability) error

	// ProvideBroadcast populates the envelope with the necessary capability tokens
	// for broadcast in the topic and signs it
	ProvideBroadcast(msg *Envelope, topic string, broadcast []Capability) error

	// Verify verifies the message signature in an envelope
	Verify(msg Envelope) error
	// Sign signs an envelope; the envelope is modified in place.
	Sign(msg *Envelope) error

	// Disparcrd discards unwanted tokens from a consumed envelope
	Discard(msg Envelope)

	// Return the capability context
	Capability() ucan.CapabilityContext
}

ActorSecurityContext provides a context for which to perform cryptographic operations for an actor. This includes: - signing messages - verifying message signatures - requiring capabilities - granting capabilities

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
JackTT - Gopher 🇻🇳