gateway

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package gateway implements the fenced Tool Gateway boundary that runtime workers call on behalf of an Attempt. The gateway enforces policy, approval binding, budget hard-stop and durable side-effect receipts outside the LLM; it is a separate process in production (tech baseline §5) because it sits on the credential and external-side-effect security boundary.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DevExecutor

type DevExecutor struct {
	MaxOutputBytes int64
}

DevExecutor is the v0.1 development tool executor: it echoes the normalized invocation for any registered tool and enforces nothing beyond the gateway decision chain. It is not a sandbox and must never be deployed with real credentials or untrusted workloads.

func (*DevExecutor) Execute

type DevSecretBroker

type DevSecretBroker struct {
	Handle tool.SecretHandle
}

DevSecretBroker issues a fixed handle for development. It is not a real secret broker; the gateway redacts the handle from results, which is what exercises the sanitizer in dev.

func (*DevSecretBroker) Issue

type IPCService

type IPCService struct {
	ipcv1.UnimplementedIPCGatewayServiceServer
	// contains filtered or unexported fields
}

IPCService is the fenced agent-to-agent mailbox boundary. Agents reach their mailbox through this service rather than through the Control API, so they cannot choose a tenant, and can never address a mailbox outside their own run.

Authorization is two layers, checked in the order the tool and model path uses (service-layer capability first, then Rego):

  • capability: the sending AgentVersion must grant the receiving one in capabilities.peers. Grants are per immutable version, so republishing a version is what changes them.
  • tenant policy: the tenant must list the receiving AgentVersion in allowed_peers. This is per tenant and denies by default, so a tenant that has not opted in cannot message anyone regardless of its versions' grants.

Two things it deliberately still does not do:

  • It does not notify a receiver. The platform cannot push into a running agent: fenced.runtime.v1 exposes seven pull RPCs, its HeartbeatResponse carries no payload, and nothing in the repository resembles a wake path. A receiver drains its mailbox on its own schedule.
  • It does not check the *receiver's* willingness. The grant answers "may I write to you", never "may you write to me", so a sender that knows a run id can reach it. A receiving-side allowlist is a separate design.

func NewIPCService

func NewIPCService(
	mailbox store.IPCStore,
	scopes MailboxScope,
	fences RuntimeFence,
	allowedTenant string,
	capabilities PeerAuthorizer,
	peerPolicy PeerPolicy,
) *IPCService

func (*IPCService) AcknowledgeMessage

AcknowledgeMessage records the caller's receipts for a batch it has drained.

func (*IPCService) ReceiveMessages

ReceiveMessages drains the caller's own mailbox. The request carries no address on purpose: the only mailbox a caller may drain is the one owned by its fenced run, so the address is derived from the fenced assignment rather than from anything the caller sent.

func (*IPCService) SendMessage

SendMessage stores one message in the mailbox its address names.

type MailboxScope

type MailboxScope interface {
	GetRunMailboxScope(context.Context, string, uuid.UUID) (store.RunMailboxScope, error)
}

MailboxScope resolves the mailbox a run id names.

type MemoryInvoker

type MemoryInvoker interface {
	Put(context.Context, memory.PutInput) (store.MemoryRecord, bool, error)
	Search(context.Context, memory.SearchInput) ([]store.MemoryRecord, error)
}

MemoryInvoker is the canonical memory decision chain exposed to Agents.

type MemoryService

type MemoryService struct {
	gatewayv1.UnimplementedMemoryGatewayServiceServer
	// contains filtered or unexported fields
}

MemoryService is a fenced, capability-aware Agent memory boundary. The existing Control API remains an operator surface; Agent runtimes use this service so they cannot choose a tenant, version, or namespace grant.

func NewMemoryService

func NewMemoryService(memories MemoryInvoker, fences RuntimeFence, allowedTenant string, capabilities *capability.Authorizer) *MemoryService

func (*MemoryService) PutMemory

func (*MemoryService) SearchMemory

type ModelInvocationService

type ModelInvocationService struct {
	modelv1.UnimplementedModelInvocationServiceServer
	// contains filtered or unexported fields
}

ModelInvocationService is the additive v1 execution surface of the Model Gateway: it runs policy, budget and the call ledger around a real provider invocation and streams the completion. Credentials never cross this boundary in either direction.

func NewModelInvocationService

func NewModelInvocationService(runner ModelRunner, allowedTenant string, capabilities ...*capability.Authorizer) *ModelInvocationService

NewModelInvocationService builds the execution surface. allowedTenant "*" disables the static tenant gate (production relies on SPIFFE mTLS).

func (*ModelInvocationService) Invoke

Invoke executes one model invocation. Content deltas stream as chunks; the terminal chunk is either a finish (ledger metadata and the assembled content) or a structured provider failure. Governance failures (identity, capability, policy, budget) are gRPC status errors — no stream is opened.

type ModelInvoker

ModelInvoker is the fenced model decision chain the service exposes. The model.Gateway satisfies it.

type ModelRunner

type ModelRunner interface {
	InvokeStream(context.Context, model.InvokeInput, func(string)) (model.InvokeOutput, error)
}

ModelRunner executes real model invocations behind the fenced decision chain. The model.Invoker satisfies it.

type ModelService

type ModelService struct {
	modelv1.UnimplementedModelGatewayServiceServer
	// contains filtered or unexported fields
}

ModelService is the fenced gRPC surface of the Model Gateway. Development mode accepts a fixed tenant on a loopback-only listener; production exposure requires SPIFFE mTLS.

func NewModelService

func NewModelService(invoker ModelInvoker, allowedTenant string, capabilities ...*capability.Authorizer) *ModelService

func (*ModelService) Begin

func (*ModelService) Finish

func (*ModelService) Settle

type PeerAuthorizer

type PeerAuthorizer interface {
	Authorize(context.Context, string, string, capability.Kind, ...string) error
}

PeerAuthorizer decides whether the sending AgentVersion holds an immutable grant for the receiving one. *capability.Authorizer satisfies it.

type PeerPolicy

type PeerPolicy interface {
	EvaluatePeer(context.Context, string, policy.PeerContext) policy.Decision
}

PeerPolicy is the tenant-wide half of the same decision: whether this tenant may message that AgentVersion at all. *policy.Engine satisfies it.

It is a narrow consumer-side interface for the same reason tool and model gateways declare their own: the service depends on one method, not on the policy engine's shape.

type RuntimeFence

type RuntimeFence interface {
	GetRuntimeAssignment(context.Context, string, uuid.UUID, int64) (store.RuntimeAssignment, error)
}

RuntimeFence resolves an Attempt only when its fencing token is current.

type Service

type Service struct {
	gatewayv1.UnimplementedToolGatewayServiceServer
	// contains filtered or unexported fields
}

Service is the fenced gRPC surface of the Tool Gateway. Development mode accepts a fixed tenant on a loopback-only listener; production exposure requires SPIFFE mTLS (ADR-006).

func NewService

func NewService(invoker ToolInvoker, allowedTenant string, capabilities ...*capability.Authorizer) *Service

func (*Service) InvokeTool

func (*Service) ListTools

func (*Service) WithRuntimeFence

func (s *Service) WithRuntimeFence(fences RuntimeFence) *Service

WithRuntimeFence attaches a fence validator to the tool gateway service.

type SyscallService

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

SyscallService exposes the unified Agent Syscall ABI over HTTP.

func NewSyscallService

func NewSyscallService(dispatcher *syscall.SyscallDispatcher, allowedTenant string) *SyscallService

NewSyscallService creates a new SyscallService.

func (*SyscallService) Dispatcher

func (s *SyscallService) Dispatcher() *syscall.SyscallDispatcher

Dispatcher returns the underlying kernel SyscallDispatcher.

func (*SyscallService) ServeHTTP

func (s *SyscallService) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles HTTP POST requests for unified system call dispatching.

type ToolInvoker

type ToolInvoker interface {
	InvokeTool(context.Context, tool.InvokeInput) (tool.InvokeResult, error)
	ListTools(context.Context, string) ([]store.ToolDescriptor, error)
	GetToolDescriptor(ctx context.Context, tenantID, name, version string) (store.ToolDescriptor, error)
}

ToolInvoker is the decision chain the service exposes. The tool.Gateway satisfies it; tests substitute fakes.

type WebhookExecutor

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

WebhookExecutor is the production tool adapter boundary. Every immutable tool version maps to one preconfigured HTTPS endpoint; Agent input can never select or modify the destination.

func NewWebhookExecutor

func NewWebhookExecutor(endpoints map[string]string, client *http.Client) (*WebhookExecutor, error)

func (*WebhookExecutor) Execute

Directories

Path Synopsis
Package bao implements the reference Secret Broker backed by OpenBao (ADR-012).
Package bao implements the reference Secret Broker backed by OpenBao (ADR-012).

Jump to

Keyboard shortcuts

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