externalexecution

package
v0.2.1 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	ScopeValidateTarget            = "target.validate"
	ScopeStartExecution            = "execution.start"
	ScopeReadExecution             = "execution.read"
	ScopeCancelExecution           = "execution.cancel"
	ErrorCodeJTIReplay             = "EXTERNAL_EXECUTION_JTI_REPLAY"
	ErrorCodeRequestBindingInvalid = "EXTERNAL_EXECUTION_REQUEST_BINDING_INVALID"
	RequestBindingVersionV1        = "v1"
	// LegacyCutoverCallerServiceID is the caller namespace assigned to every
	// pre-074 execution row. Deployments must keep this identity until a future
	// migration explicitly rekeys that historical namespace.
	LegacyCutoverCallerServiceID = "openlinker-cloud"
)
View Source
const (
	TargetTypeAgent    = "agent"
	TargetTypeWorkflow = "workflow"
)

Variables

View Source
var (
	ErrExecutionIdentityConflict = errors.New("external execution actor identity conflict")
	ErrExecutionCanceled         = errors.New("external execution was canceled")
)

Functions

func ParseEd25519PrivateKey

func ParseEd25519PrivateKey(raw string) (ed25519.PrivateKey, error)

func ParseEd25519PublicKey

func ParseEd25519PublicKey(raw string) (ed25519.PublicKey, error)

func RequestBodySHA256

func RequestBodySHA256(body []byte) string

func StartCancellationMaintenanceWorker

func StartCancellationMaintenanceWorker(ctx context.Context, svc *Service, interval time.Duration, batch int)

func StartCancellationMaintenanceWorkerWithWake

func StartCancellationMaintenanceWorkerWithWake(
	ctx context.Context,
	svc *Service,
	interval time.Duration,
	batch int,
	source eventwake.TopicSource,
)

StartCancellationMaintenanceWorkerWithWake replaces the healthy idle poll with transactional Core external-execution hints. Unresolved cancellation evidence retains the original interval, and listener degradation immediately restores the legacy poll. PostgreSQL remains the only cancellation fact.

Types

type Authorizer

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

func NewAuthorizer

func NewAuthorizer(keys []VerificationKey, issuer, audience, callerServiceID string, replay ReplayStore, options ...AuthorizerOption) (*Authorizer, error)

func (*Authorizer) Authorize

func (a *Authorizer) Authorize(ctx context.Context, rawToken, requiredScope string) (*Principal, error)

type AuthorizerOption

type AuthorizerOption func(*Authorizer)

func WithRequestBindingRequired

func WithRequestBindingRequired() AuthorizerOption

WithRequestBindingRequired selects the Release B fail-closed mode. Without this option Release A accepts only tokens whose four binding keys are all absent; partial, null, malformed, or unknown binding claims still fail.

type CancellationRecord

type CancellationRecord struct {
	ID                    uuid.UUID
	CallerServiceID       string
	ExternalRequestID     uuid.UUID
	ActorUserID           uuid.UUID
	ReasonCode            string
	State                 string
	ExecutionKindSnapshot *string
	ExecutionIDSnapshot   *uuid.UUID
	ErrorCode             *string
	RequestedAt           time.Time
	AppliedAt             *time.Time
	FinishedAt            *time.Time
	UpdatedAt             time.Time
}

type ExecutionCancelRequest

type ExecutionCancelRequest struct {
	ReasonCode string `json:"reason_code"`
}

type ExecutionCancellationResponse

type ExecutionCancellationResponse struct {
	CancellationID string `json:"cancellation_id"`
	State          string `json:"state"`
	ReasonCode     string `json:"reason_code"`
	ExecutionKind  string `json:"execution_kind,omitempty"`
	ExecutionID    string `json:"execution_id,omitempty"`
	RequestedAt    string `json:"requested_at"`
	AppliedAt      string `json:"applied_at,omitempty"`
	FinishedAt     string `json:"finished_at,omitempty"`
}

type ExecutionKey

type ExecutionKey struct {
	CallerServiceID   string
	ExternalRequestID uuid.UUID
	ActorUserID       uuid.UUID
}

type ExecutionRecord

type ExecutionRecord struct {
	CallerServiceID           string
	ExternalRequestID         uuid.UUID
	RequestFingerprintVersion int16
	ActorUserID               uuid.UUID
	TargetType                string
	TargetID                  uuid.UUID
	InputFingerprint          []byte
	ExpectedContractHash      *string
	InputSchemaFingerprint    []byte
	TraceID                   string
	DownstreamReplayIdentity  []byte
	StartState                string
	StartToken                *uuid.UUID
	StartLeaseUntil           *time.Time
	AuthorizedTargetOwnerID   *uuid.UUID
	RejectionCode             *string
	ExecutionKind             *string
	ExecutionID               *uuid.UUID
	DownstreamKeyHash         []byte
	DownstreamFingerprint     []byte
}

type ExecutionRequest

type ExecutionRequest struct {
	ExternalRequestID    string                 `json:"external_request_id"`
	TargetType           string                 `json:"target_type"`
	TargetID             string                 `json:"target_id"`
	Input                map[string]interface{} `json:"input"`
	Metadata             map[string]interface{} `json:"metadata,omitempty"`
	TraceID              string                 `json:"trace_id"`
	ExpectedContractHash string                 `json:"expected_contract_hash"`
	InputSchema          json.RawMessage        `json:"input_schema"`
}

type ExecutionStartResponse

type ExecutionStartResponse struct {
	ExecutionID string `json:"execution_id"`
	Status      string `json:"status"`
}

type ExecutionStatusResponse

type ExecutionStatusResponse struct {
	ExternalRequestID string                         `json:"external_request_id"`
	ExecutionID       string                         `json:"execution_id,omitempty"`
	TargetType        string                         `json:"target_type,omitempty"`
	Status            string                         `json:"status"`
	Output            map[string]interface{}         `json:"output,omitempty"`
	Artifacts         []runtime.RunArtifactResponse  `json:"artifacts"`
	ErrorCode         string                         `json:"error_code,omitempty"`
	ErrorMessage      string                         `json:"error_message,omitempty"`
	StartedAt         string                         `json:"started_at,omitempty"`
	FinishedAt        string                         `json:"finished_at,omitempty"`
	Cancellation      *ExecutionCancellationResponse `json:"cancellation,omitempty"`
}

type Handler

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

func NewHandler

func NewHandler(svc executionService, authorizer *Authorizer) *Handler

func (*Handler) CancelExecution

func (h *Handler) CancelExecution(c echo.Context) error

func (*Handler) GetExecution

func (h *Handler) GetExecution(c echo.Context) error

func (*Handler) Register

func (h *Handler) Register(e *echo.Echo)

func (*Handler) StartExecution

func (h *Handler) StartExecution(c echo.Context) error

func (*Handler) ValidateTarget

func (h *Handler) ValidateTarget(c echo.Context) error

type Principal

type Principal struct {
	CallerServiceID string
	ActorUserID     uuid.UUID
}

type RedisReplayStore

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

func NewRedisReplayStore

func NewRedisReplayStore(client *redis.Client) *RedisReplayStore

func (*RedisReplayStore) Consume

func (s *RedisReplayStore) Consume(ctx context.Context, issuer, jti string, ttl time.Duration) (bool, error)

type ReplayStore

type ReplayStore interface {
	Consume(context.Context, string, string, time.Duration) (bool, error)
}

type RequestBinding

type RequestBinding struct {
	Version string
	Method  string
	Path    string
	BodySHA string
}

type SQLStore

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

func NewSQLStore

func NewSQLStore(pool *pgxpool.Pool) *SQLStore

func (*SQLStore) AdvanceCancellation

func (s *SQLStore) AdvanceCancellation(
	ctx context.Context,
	callerServiceID string,
	externalRequestID uuid.UUID,
	nextState string,
) (*ExecutionRecord, CancellationRecord, error)

func (*SQLStore) Attach

func (s *SQLStore) Attach(ctx context.Context, callerServiceID string, externalRequestID uuid.UUID, executionKind string, executionID uuid.UUID) (ExecutionRecord, error)

func (*SQLStore) AttachCanceledRecovery

func (s *SQLStore) AttachCanceledRecovery(
	ctx context.Context,
	callerServiceID string,
	externalRequestID uuid.UUID,
	executionKind string,
	executionID uuid.UUID,
) (ExecutionRecord, bool, error)

func (*SQLStore) AttachLaunched

func (s *SQLStore) AttachLaunched(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, token uuid.UUID,
	executionKind string,
	executionID uuid.UUID,
) (ExecutionRecord, bool, error)

func (*SQLStore) AuthorizeStart

func (s *SQLStore) AuthorizeStart(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, token, targetOwnerID uuid.UUID,
) (ExecutionRecord, bool, error)

func (*SQLStore) ClaimLaunch

func (s *SQLStore) ClaimLaunch(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, token uuid.UUID,
	lease time.Duration,
) (ExecutionRecord, bool, error)

func (*SQLStore) ClaimStartEvaluation

func (s *SQLStore) ClaimStartEvaluation(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, token uuid.UUID,
	lease time.Duration,
) (ExecutionRecord, bool, error)

func (*SQLStore) Get

func (s *SQLStore) Get(ctx context.Context, callerServiceID string, externalRequestID uuid.UUID) (ExecutionRecord, error)

func (*SQLStore) GetCancellation

func (s *SQLStore) GetCancellation(ctx context.Context, callerServiceID string, externalRequestID uuid.UUID) (CancellationRecord, error)

func (*SQLStore) GetKey

func (s *SQLStore) GetKey(ctx context.Context, callerServiceID string, externalRequestID uuid.UUID) (ExecutionKey, error)

func (*SQLStore) ListPendingCancellations

func (s *SQLStore) ListPendingCancellations(ctx context.Context, limit int) ([]CancellationRecord, error)

func (*SQLStore) PromoteLegacyReservation

func (s *SQLStore) PromoteLegacyReservation(ctx context.Context, record ExecutionRecord) (ExecutionRecord, error)

func (*SQLStore) RejectStart

func (s *SQLStore) RejectStart(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, token uuid.UUID,
	rejectionCode string,
) (ExecutionRecord, bool, error)

func (*SQLStore) ReleaseStartEvaluation

func (s *SQLStore) ReleaseStartEvaluation(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, token uuid.UUID,
) error

func (*SQLStore) RequestCancel

func (s *SQLStore) RequestCancel(
	ctx context.Context,
	callerServiceID string,
	externalRequestID, actorUserID uuid.UUID,
	reasonCode string,
) (*ExecutionRecord, CancellationRecord, error)

func (*SQLStore) Reserve

func (s *SQLStore) Reserve(ctx context.Context, record ExecutionRecord) (ExecutionRecord, error)

func (*SQLStore) ResolveTargetOwner

func (s *SQLStore) ResolveTargetOwner(ctx context.Context, targetType string, targetID uuid.UUID) (uuid.UUID, error)

type SafeExecutionError

type SafeExecutionError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

type Service

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

func NewService

func NewService(agents agentService, runtimeSvc runtimeService, workflows workflowService, store Store) *Service

func (*Service) CancelExecution

func (s *Service) CancelExecution(
	ctx context.Context,
	principal *Principal,
	externalRequestID string,
	req *ExecutionCancelRequest,
) (*ExecutionStatusResponse, error)

func (*Service) GetExecution

func (s *Service) GetExecution(ctx context.Context, principal *Principal, externalRequestID string) (*ExecutionStatusResponse, error)

func (*Service) ReconcilePendingCancellations

func (s *Service) ReconcilePendingCancellations(ctx context.Context, limit int) (int, error)

ReconcilePendingCancellations is the maintenance-only mutation path. GET never calls it and therefore remains strictly read-only.

func (*Service) StartExecution

func (s *Service) StartExecution(ctx context.Context, principal *Principal, req *ExecutionRequest) (*ExecutionStartResponse, error)

func (*Service) ValidateTarget

func (s *Service) ValidateTarget(ctx context.Context, principal *Principal, req *TargetValidationRequest) (*TargetValidationResponse, error)

type ServiceTokenClaims

type ServiceTokenClaims struct {
	Scope                 string `json:"scope"`
	DelegatedActor        string `json:"delegated_actor"`
	CallerServiceID       string `json:"caller_service_id"`
	RequestBindingVersion string `json:"request_binding_version,omitempty"`
	RequestMethod         string `json:"request_method,omitempty"`
	RequestPath           string `json:"request_path,omitempty"`
	RequestBodySHA256     string `json:"request_body_sha256,omitempty"`
	jwt.RegisteredClaims
}

type ServiceTokenSigner

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

func NewServiceTokenSigner

func NewServiceTokenSigner(rawPrivateKey, keyID, issuer, audience, callerServiceID string, ttl time.Duration) (*ServiceTokenSigner, error)

func (*ServiceTokenSigner) Sign

func (s *ServiceTokenSigner) Sign(scope, delegatedActor string) (string, error)

func (*ServiceTokenSigner) SignRequest

func (s *ServiceTokenSigner) SignRequest(scope, delegatedActor, method, escapedPath string, body []byte) (string, error)

SignRequest issues a v1 credential bound to the exact HTTP request bytes. escapedPath must be the final request URL's EscapedPath, not a route template.

type Store

type Store interface {
	ResolveTargetOwner(context.Context, string, uuid.UUID) (uuid.UUID, error)
	Reserve(context.Context, ExecutionRecord) (ExecutionRecord, error)
	PromoteLegacyReservation(context.Context, ExecutionRecord) (ExecutionRecord, error)
	Get(context.Context, string, uuid.UUID) (ExecutionRecord, error)
	ClaimStartEvaluation(context.Context, string, uuid.UUID, uuid.UUID, time.Duration) (ExecutionRecord, bool, error)
	AuthorizeStart(context.Context, string, uuid.UUID, uuid.UUID, uuid.UUID) (ExecutionRecord, bool, error)
	RejectStart(context.Context, string, uuid.UUID, uuid.UUID, string) (ExecutionRecord, bool, error)
	ReleaseStartEvaluation(context.Context, string, uuid.UUID, uuid.UUID) error
	Attach(context.Context, string, uuid.UUID, string, uuid.UUID) (ExecutionRecord, error)
	ClaimLaunch(context.Context, string, uuid.UUID, uuid.UUID, time.Duration) (ExecutionRecord, bool, error)
	AttachLaunched(context.Context, string, uuid.UUID, uuid.UUID, string, uuid.UUID) (ExecutionRecord, bool, error)
	AttachCanceledRecovery(context.Context, string, uuid.UUID, string, uuid.UUID) (ExecutionRecord, bool, error)
	GetKey(context.Context, string, uuid.UUID) (ExecutionKey, error)
	GetCancellation(context.Context, string, uuid.UUID) (CancellationRecord, error)
	RequestCancel(context.Context, string, uuid.UUID, uuid.UUID, string) (*ExecutionRecord, CancellationRecord, error)
	AdvanceCancellation(context.Context, string, uuid.UUID, string) (*ExecutionRecord, CancellationRecord, error)
	ListPendingCancellations(context.Context, int) ([]CancellationRecord, error)
}

type TargetValidationRequest

type TargetValidationRequest struct {
	TargetType  string          `json:"target_type"`
	TargetID    string          `json:"target_id"`
	InputSchema json.RawMessage `json:"input_schema,omitempty"`
}

type TargetValidationResponse

type TargetValidationResponse struct {
	TargetType        string `json:"target_type"`
	TargetID          string `json:"target_id"`
	TargetName        string `json:"target_name"`
	Executable        bool   `json:"executable"`
	UnavailableReason string `json:"unavailable_reason,omitempty"`
	ContractHash      string `json:"contract_hash,omitempty"`
}

type VerificationKey

type VerificationKey struct {
	KeyID     string
	PublicKey string
}

type WorkflowTargetValidation

type WorkflowTargetValidation struct {
	TargetName        string
	Executable        bool
	UnavailableReason string
	ContractHash      string
}

Jump to

Keyboard shortcuts

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