webhook

package
v0.66.0 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2026 License: AGPL-3.0 Imports: 18 Imported by: 0

Documentation

Overview

Package webhook owns personal webhook resources, their opaque credentials, and the admission boundary from inbound HTTP to a fixed Agent invocation.

Index

Constants

View Source
const (
	TokenPrefix = "stella_whk_"

	DefaultWaitTimeoutSeconds   = 60
	DefaultMaxRunTimeoutSeconds = 300
	WaitTimeoutCeilingSeconds   = 600
	RunTimeoutCeilingSeconds    = 3600
)

Variables

View Source
var (
	ErrNotFound           = errors.New("webhook: not found")
	ErrInvalidID          = errors.New("webhook: invalid id")
	ErrInvalidUserID      = errors.New("webhook: invalid user id")
	ErrInvalidName        = errors.New("webhook: name is required")
	ErrInvalidAgentID     = errors.New("webhook: agent id is required")
	ErrInvalidProvider    = errors.New("webhook: invalid provider")
	ErrInvalidTimeout     = errors.New("webhook: timeout is invalid")
	ErrInvalidETag        = errors.New("webhook: invalid etag")
	ErrStaleETag          = errors.New("webhook: changed since the provided etag")
	ErrUserInactive       = errors.New("webhook: user is inactive")
	ErrUserAgentForbidden = errors.New("webhook: user cannot use agent")
)

Functions

func EncodeETag

func EncodeETag(publicID string, revision int64) string

Types

type AdmitCallback

type AdmitCallback func(context.Context, AdmittedInvocation) error

type AdmittedInvocation

type AdmittedInvocation struct {
	WebhookID            string
	UserID               string
	AgentID              string
	Provider             Provider
	WaitTimeoutSeconds   int32
	MaxRunTimeoutSeconds int32
	Authority            authz.Authority
}

type Candidate

type Candidate struct {
	WebhookID string
	// contains filtered or unexported fields
}

Candidate holds verifier material privately across the bounded body read.

func (Candidate) LogValue

func (c Candidate) LogValue() slog.Value

func (Candidate) String

func (c Candidate) String() string

type Config

type Config struct {
	Store  Store
	Users  UserState
	Access UserAgentAccess
}

type CreateRequest

type CreateRequest struct {
	UserID               string
	Name                 string
	AgentID              string
	Provider             Provider
	IsEnabled            bool
	WaitTimeoutSeconds   int32
	MaxRunTimeoutSeconds int32
}

type IssueResult

type IssueResult struct {
	Webhook    Webhook
	Capability string
}

type PostgresStore

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

PostgresStore confines sqlc and short credential-rotation transactions to the webhook domain. Every resource operation scopes by (id, user_id) in SQL.

func NewPostgresStore

func NewPostgresStore(db *pgxpool.Pool) *PostgresStore

func (*PostgresStore) Create

func (s *PostgresStore) Create(ctx context.Context, rec credentialRecord) (credentialRecord, error)

func (*PostgresStore) Delete

func (s *PostgresStore) Delete(ctx context.Context, id, userID string) (int64, error)

func (*PostgresStore) Get

func (s *PostgresStore) Get(ctx context.Context, id, userID string) (credentialRecord, error)

func (*PostgresStore) List

func (s *PostgresStore) List(ctx context.Context, userID string, limit, offset int32) ([]credentialRecord, error)

func (*PostgresStore) ResolveAdmitted

func (s *PostgresStore) ResolveAdmitted(ctx context.Context, publicID string) (credentialRecord, error)

func (*PostgresStore) ResolveByPublicID

func (s *PostgresStore) ResolveByPublicID(ctx context.Context, publicID string) (credentialRecord, error)

func (*PostgresStore) Rotate

func (s *PostgresStore) Rotate(ctx context.Context, id, userID, etag string, next credentialRecord) (credentialRecord, error)

func (*PostgresStore) Update

func (s *PostgresStore) Update(ctx context.Context, req UpdateRequest) (credentialRecord, error)

type Provider

type Provider string
const ProviderGeneric Provider = "generic"

func (Provider) Valid

func (p Provider) Valid() bool

type Service

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

Service is the deep webhook resource boundary. A single lifecycle fence is sufficient for Stella's supported single-replica deployment. Upgrade to a distributed/per-webhook fence when multi-replica ingress is supported.

func NewService

func NewService(cfg Config) (*Service, error)

func (*Service) Admit

func (s *Service) Admit(ctx context.Context, cand Candidate, callback AdmitCallback) error

func (*Service) Create

func (s *Service) Create(ctx context.Context, req CreateRequest) (IssueResult, error)

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, userID, id string) (bool, error)

func (*Service) Get

func (s *Service) Get(ctx context.Context, userID, id string) (Webhook, error)

func (*Service) List

func (s *Service) List(ctx context.Context, userID string, limit, offset int32) ([]Webhook, error)

func (*Service) ResolveCandidate

func (s *Service) ResolveCandidate(ctx context.Context, raw string) (Candidate, error)

func (*Service) Rotate

func (s *Service) Rotate(ctx context.Context, userID, id, etag string) (IssueResult, error)

func (*Service) Update

func (s *Service) Update(ctx context.Context, req UpdateRequest) (Webhook, error)

func (*Service) ValidateUserAgent

func (s *Service) ValidateUserAgent(ctx context.Context, userID, agentID string) error

type Store

type Store interface {
	Create(context.Context, credentialRecord) (credentialRecord, error)
	Get(context.Context, string, string) (credentialRecord, error)
	List(context.Context, string, int32, int32) ([]credentialRecord, error)
	// Update atomically applies only fields present in the owner-scoped request.
	Update(context.Context, UpdateRequest) (credentialRecord, error)
	Rotate(context.Context, string, string, string, credentialRecord) (credentialRecord, error)
	Delete(context.Context, string, string) (int64, error)
	ResolveByPublicID(context.Context, string) (credentialRecord, error)
	ResolveAdmitted(context.Context, string) (credentialRecord, error)
}

type UpdateRequest

type UpdateRequest struct {
	ID                   string
	UserID               string
	Name                 *string
	AgentID              *string
	IsEnabled            *bool
	WaitTimeoutSeconds   *int32
	MaxRunTimeoutSeconds *int32
}

type UserAgentAccess

type UserAgentAccess interface {
	CanUseUser(context.Context, string, string) (bool, error)
}

type UserAgentAccessFromService

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

func NewUserAgentAccess

func NewUserAgentAccess(access *agentaccess.Service) UserAgentAccessFromService

func (UserAgentAccessFromService) CanUseUser

func (a UserAgentAccessFromService) CanUseUser(ctx context.Context, userID, agentID string) (bool, error)

type UserState

type UserState interface {
	IsActive(context.Context, string) (bool, error)
}

type UserStateFromLookup

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

func NewUserState

func NewUserState(lookup credential.UserLookup) UserStateFromLookup

func (UserStateFromLookup) IsActive

func (s UserStateFromLookup) IsActive(ctx context.Context, userID string) (bool, error)

type Webhook

type Webhook struct {
	ID                   string
	UserID               string
	AgentID              string
	Name                 string
	Provider             Provider
	IsEnabled            bool
	WaitTimeoutSeconds   int32
	MaxRunTimeoutSeconds int32
	TokenPublicID        string
	TokenLast4           string
	Revision             int64
	CreatedAt            time.Time
	UpdatedAt            time.Time
	RotatedAt            *time.Time
}

Webhook excludes the credential hash by construction. The opaque public ID is retained only to derive the compare-only etag and never crosses the API boundary.

func (Webhook) ETag

func (w Webhook) ETag() string

Jump to

Keyboard shortcuts

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