services

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2026 License: MIT Imports: 23 Imported by: 2

README

go-services

go-services is an integration runtime for Go applications that need to connect to third party providers (OAuth2, API key/PAT, HMAC, mTLS/basic, AWS SigV4), persist credentials safely, execute provider operations, and process webhook/sync lifecycles.

It is designed as a backend package and not as a standalone API server.

Status

  • Current release: v0.1.0
  • API stability: pre-v1.0.0 (breaking changes are still possible)

What This Package Does

  • Manages connection lifecycle: Connect, callback completion, refresh, revoke, and re consent.
  • Persists integration state: connections, credentials, subscriptions, sync cursors, installations, grant snapshots/events, lifecycle outbox, and webhook deliveries.
  • Enforces capability access based on granted permissions.
  • Executes provider operations with transport abstraction, request signing, idempotency keys, retry policies, and optional adaptive rate limit policy.
  • Supports inbound webhook dispatch with claim/complete/fail idempotency semantics.
  • Supports embedded auth primitives (for providers that implement it), including session token validation, replay protection, and token exchange orchestration.
  • Exposes command/query handlers and facade wiring for integration with go-command.

When To Use It

Use go-services when you need one place to standardize:

  • Multi provider auth and credential lifecycle.
  • Secure credential storage and key rotation compatibility.
  • Provider call execution behavior (timeouts, retries, signing, rate limit state).
  • Webhook and sync processing with durable state and recovery.
  • Integration specific observability signals.

When Not To Use It

  • You only need direct one off HTTP calls to a single provider.
  • You do not want database backed integration state.
  • You want a fully hosted integration platform instead of embedding runtime primitives in your app.

Security and Secrets

Credential payloads are codec encoded and encrypted before persistence. A SecretProvider is required for credential persistence operations.

Included secret provider implementations:

  • security.AppKeySecretProvider: local AES-GCM encryption with key id/version metadata.
  • security.KMSSecretProvider: envelope encryption via external KMS client.
  • security.VaultSecretProvider: envelope encryption via external Vault client.
  • security.FailoverSecretProvider: primary/fallback provider policy with diagnostics (strict_fail or fallback_allowed).
  • Key rotation windows and decrypt-compatibility controls are available for KMS/Vault providers.

Observability and Reliability

  • Structured operation logging and metrics are emitted by core service paths.
  • Default metric names include:
    • services.<operation>.total
    • services.<operation>.duration_ms
  • Common operation tags include operation, status, provider_id, scope_type, scope_id, connection_id.
  • Lifecycle outbox dispatcher supports claim/ack/retry with bounded backoff and max attempts.
  • Webhook delivery processing uses explicit claim state transitions (pending/retry_ready -> processing -> processed|dead) to support retry safe recovery.
  • Runbook: docs/runbooks/services_failure_modes.md

Built-in Providers

Factory functions are exported at package root:

  • GitHubProvider
  • GmailProvider
  • DriveProvider
  • DocsProvider
  • CalendarProvider
  • ShopifyProvider
  • InstagramProvider
  • FacebookProvider
  • TikTokProvider
  • PinterestProvider
  • GoogleShoppingProvider
  • AmazonProvider
  • SalesforceProvider
  • WorkdayProvider

You can also register custom providers through core.Registry.

Install

go get github.com/goliatone/go-services@latest

Quick Start

1. Apply embedded migrations

go-services embeds Postgres and SQLite migrations:

  • services.GetMigrationsFS()
  • migrations.Filesystems()
  • migrations.Register(...)
import (
	"context"
	"io/fs"

	servicemigrations "github.com/goliatone/go-services/migrations"
)

_, err := servicemigrations.Register(
	context.Background(),
	func(ctx context.Context, dialect string, source string, fsys fs.FS) error {
		return myMigrationRunner.Register(ctx, dialect, source, fsys)
	},
)
2. Build a service with stores, secrets, and providers
package main

import (
	"context"
	"log"

	services "github.com/goliatone/go-services"
	"github.com/goliatone/go-services/core"
	"github.com/goliatone/go-services/providers/github"
	"github.com/goliatone/go-services/security"
	sqlstore "github.com/goliatone/go-services/store/sql"
	"github.com/uptrace/bun"
)

func newService(db *bun.DB) (*services.Service, error) {
	secretProvider, err := security.NewAppKeySecretProviderFromString("replace-with-secret-key-material")
	if err != nil {
		return nil, err
	}

	repositoryFactory, err := sqlstore.NewRepositoryFactoryFromDB(db)
	if err != nil {
		return nil, err
	}

	githubProvider, err := services.GitHubProvider(github.Config{
		ClientID:     "github-client-id",
		ClientSecret: "github-client-secret",
	})
	if err != nil {
		return nil, err
	}

	registry := core.NewProviderRegistry()
	if err := registry.Register(githubProvider); err != nil {
		return nil, err
	}

	return services.NewService(
		services.DefaultConfig(),
		services.WithPersistenceClient(db),
		services.WithRepositoryFactory(repositoryFactory),
		services.WithSecretProvider(secretProvider),
		services.WithRegistry(registry),
	)
}

func main() {
	var db *bun.DB // initialize this with your Bun database connection

	svc, err := newService(db)
	if err != nil {
		log.Fatal(err)
	}

	begin, err := svc.Connect(context.Background(), services.ConnectRequest{
		ProviderID:  "github",
		Scope:       core.ScopeRef{Type: "user", ID: "usr_123"},
		RedirectURI: "https://app.example.com/integrations/callback",
	})
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("send user to provider auth URL: %s", begin.URL)
}

Embedded Auth (Shopify)

go-services supports a dedicated embedded auth contract:

  • core.EmbeddedAuthRequest
  • core.EmbeddedAuthResult
  • Service.AuthenticateEmbedded(ctx, req)

Shopify providers implement this when configured with app credentials (client_id, client_secret), and the flow performs:

  1. App Bridge session JWT validation (HS256 + claim checks).
  2. Replay claim (provider + shop + jti) with TTL.
  3. Shopify token exchange for offline/online access tokens.

Hybrid constructor (OAuth auth code + embedded auth):

provider, err := services.ShopifyProvider(shopify.Config{
	Mode:         shopify.ModeHybrid, // default when omitted
	ClientID:     "shopify-client-id",
	ClientSecret: "shopify-client-secret",
	ShopDomain:   "merchant-shop",
})
if err != nil {
	return err
}

Embedded only constructor (embedded auth only):

provider, err := shopify.NewEmbedded(shopify.EmbeddedConfig{
	ClientID:     "shopify-client-id",
	ClientSecret: "shopify-client-secret",
})
if err != nil {
	return err
}

In embedded only mode, OAuth auth code methods (BeginAuth, CompleteAuth, Refresh) intentionally return an unsupported error.

Embedded auth call example:

result, err := svc.AuthenticateEmbedded(ctx, services.EmbeddedAuthRequest{
	ProviderID:   "shopify",
	Scope:        core.ScopeRef{Type: "org", ID: "org_123"},
	SessionToken: sessionJWTFromAppBridge,
	RequestedTokenType: services.EmbeddedRequestedTokenTypeOffline,
})
if err != nil {
	return err
}
_ = result.Credential.AccessToken

Package Map

  • core: domain contracts, service orchestration, permission/rate limit/runtime logic.
  • providers: built in provider implementations.
  • store/sql: Bun backed repositories and stores.
  • security: encryption/secret providers and key rotation helpers.
  • transport: REST/GraphQL/protocol transport adapters and resolver registry.
  • webhooks, inbound, sync: webhook processing and sync orchestration.
  • command, query, facade: command/query handlers and grouped facade access.
  • adapters: compatibility adapters for go-command, go-job, and go-logger.
  • migrations: migration filesystem discovery and registration helpers.

Additional Docs

  • CHANGELOG.md
  • docs/identity_profiles.md
  • docs/runbooks/services_failure_modes.md
  • docs/shopify_embedded_auth_plan.md

Documentation

Index

Constants

View Source
const (
	CallbackURLResolveFlowConnect     = core.CallbackURLResolveFlowConnect
	CallbackURLResolveFlowReconsent   = core.CallbackURLResolveFlowReconsent
	EmbeddedRequestedTokenTypeOffline = core.EmbeddedRequestedTokenTypeOffline
	EmbeddedRequestedTokenTypeOnline  = core.EmbeddedRequestedTokenTypeOnline
)

Variables

View Source
var (
	WithLogger                  = core.WithLogger
	WithLoggerProvider          = core.WithLoggerProvider
	WithMetricsRecorder         = core.WithMetricsRecorder
	WithErrorFactory            = core.WithErrorFactory
	WithErrorMapper             = core.WithErrorMapper
	WithSecretProvider          = core.WithSecretProvider
	WithPersistenceClient       = core.WithPersistenceClient
	WithRepositoryFactory       = core.WithRepositoryFactory
	WithConfigProvider          = core.WithConfigProvider
	WithOptionsResolver         = core.WithOptionsResolver
	WithOAuthStateStore         = core.WithOAuthStateStore
	WithConnectionLocker        = core.WithConnectionLocker
	WithRefreshBackoffScheduler = core.WithRefreshBackoffScheduler
	WithTransportResolver       = core.WithTransportResolver
	WithRateLimitPolicy         = core.WithRateLimitPolicy
	WithInheritancePolicy       = core.WithInheritancePolicy
	WithRegistry                = core.WithRegistry
	WithConnectionStore         = core.WithConnectionStore
	WithCredentialStore         = core.WithCredentialStore
	WithSubscriptionStore       = core.WithSubscriptionStore
	WithSyncCursorStore         = core.WithSyncCursorStore
	WithInstallationStore       = core.WithInstallationStore
	WithSyncJobStore            = core.WithSyncJobStore
	WithGrantStore              = core.WithGrantStore
	WithPermissionEvaluator     = core.WithPermissionEvaluator
	WithSigner                  = core.WithSigner
	WithCredentialCodec         = core.WithCredentialCodec
	WithCallbackURLResolver     = core.WithCallbackURLResolver
)

Functions

func AmazonProvider added in v0.2.0

func AmazonProvider(cfg amazon.Config) (core.Provider, error)

func CalendarProvider

func CalendarProvider(cfg calendar.Config) (core.Provider, error)

func DocsProvider

func DocsProvider(cfg docs.Config) (core.Provider, error)

func DriveProvider

func DriveProvider(cfg drive.Config) (core.Provider, error)

func FacebookProvider added in v0.2.0

func FacebookProvider(cfg facebook.Config) (core.Provider, error)

func GetCoreMigrationsFS

func GetCoreMigrationsFS() fs.FS

GetCoreMigrationsFS returns the default core services schema migration tree.

v1 intentionally ships only core migrations; segmented getters are deferred.

func GetMigrationsFS

func GetMigrationsFS() fs.FS

GetMigrationsFS returns the full embedded migration tree.

func GitHubProvider

func GitHubProvider(cfg github.Config) (core.Provider, error)

func GmailProvider

func GmailProvider(cfg gmail.Config) (core.Provider, error)

func GoogleShoppingProvider added in v0.2.0

func GoogleShoppingProvider(cfg shopping.Config) (core.Provider, error)

func InstagramProvider added in v0.2.0

func InstagramProvider(cfg instagram.Config) (core.Provider, error)

func PinterestProvider added in v0.2.0

func PinterestProvider(cfg pinterest.Config) (core.Provider, error)

func SalesforceProvider added in v0.2.0

func SalesforceProvider(cfg salesforce.Config) (core.Provider, error)

func ShopifyProvider added in v0.2.0

func ShopifyProvider(cfg shopify.Config) (core.Provider, error)

func TikTokProvider added in v0.2.0

func TikTokProvider(cfg tiktok.Config) (core.Provider, error)

func WorkdayProvider added in v0.2.0

func WorkdayProvider(cfg workday.Config) (core.Provider, error)

Types

type CallbackURLResolveFlow added in v0.2.0

type CallbackURLResolveFlow = core.CallbackURLResolveFlow

type CallbackURLResolveRequest added in v0.2.0

type CallbackURLResolveRequest = core.CallbackURLResolveRequest

type CallbackURLResolver added in v0.2.0

type CallbackURLResolver = core.CallbackURLResolver

type CallbackURLResolverFunc added in v0.2.0

type CallbackURLResolverFunc = core.CallbackURLResolverFunc

type CapabilityDescriptorPack

type CapabilityDescriptorPack struct {
	Name        string
	ProviderID  string
	Descriptors []core.CapabilityDescriptor
}

type CommandQueryBundleFactory

type CommandQueryBundleFactory func(service CommandQueryService) (any, error)

type CompleteAuthRequest

type CompleteAuthRequest = core.CompleteAuthRequest

type Config

type Config = core.Config

func DefaultConfig

func DefaultConfig() Config

type ConnectRequest

type ConnectRequest = core.ConnectRequest

type ConnectionLocker

type ConnectionLocker = core.ConnectionLocker

type CreateSyncJobRequest added in v0.2.0

type CreateSyncJobRequest = core.CreateSyncJobRequest

type CreateSyncJobResult added in v0.2.0

type CreateSyncJobResult = core.CreateSyncJobResult

type CredentialCodec

type CredentialCodec = core.CredentialCodec

type EmbeddedAccessToken added in v0.3.0

type EmbeddedAccessToken = core.EmbeddedAccessToken

type EmbeddedAuthRequest added in v0.3.0

type EmbeddedAuthRequest = core.EmbeddedAuthRequest

type EmbeddedAuthResult added in v0.3.0

type EmbeddedAuthResult = core.EmbeddedAuthResult

type EmbeddedAuthService added in v0.3.0

type EmbeddedAuthService = core.EmbeddedAuthService

type EmbeddedRequestedTokenType added in v0.3.0

type EmbeddedRequestedTokenType = core.EmbeddedRequestedTokenType

type EmbeddedSessionClaims added in v0.3.0

type EmbeddedSessionClaims = core.EmbeddedSessionClaims

type ExtensionHooks

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

func NewExtensionHooks

func NewExtensionHooks() *ExtensionHooks

func (*ExtensionHooks) ApplyProviderPacks

func (h *ExtensionHooks) ApplyProviderPacks(registry core.Registry) error

func (*ExtensionHooks) BuildCommandQueryBundles

func (h *ExtensionHooks) BuildCommandQueryBundles(
	service CommandQueryService,
) (map[string]any, error)

func (*ExtensionHooks) BundleNames

func (h *ExtensionHooks) BundleNames() []string

func (*ExtensionHooks) CapabilityDescriptors

func (h *ExtensionHooks) CapabilityDescriptors(providerID string) []core.CapabilityDescriptor

func (*ExtensionHooks) ProviderPacks

func (h *ExtensionHooks) ProviderPacks() []ProviderPack

func (*ExtensionHooks) RegisterCapabilityPack

func (h *ExtensionHooks) RegisterCapabilityPack(pack CapabilityDescriptorPack) error

func (*ExtensionHooks) RegisterCommandQueryBundle

func (h *ExtensionHooks) RegisterCommandQueryBundle(
	name string,
	factory CommandQueryBundleFactory,
) error

func (*ExtensionHooks) RegisterProviderPack

func (h *ExtensionHooks) RegisterProviderPack(pack ProviderPack) error

type Facade

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

func NewFacade

func NewFacade(service CommandQueryService, opts ...FacadeOption) (*Facade, error)

func (*Facade) Commands

func (f *Facade) Commands() Commands

func (*Facade) Queries

func (f *Facade) Queries() Queries

func (*Facade) Service

func (f *Facade) Service() CommandQueryService

type FacadeOption

type FacadeOption func(*facadeOptions)

type GetSyncJobRequest added in v0.2.0

type GetSyncJobRequest = core.GetSyncJobRequest

type GrantStore

type GrantStore = core.GrantStore

type GrantStoreTransactional

type GrantStoreTransactional = core.GrantStoreTransactional

type IdempotencyClaimStore

type IdempotencyClaimStore = core.IdempotencyClaimStore

type InheritanceConfig

type InheritanceConfig = core.InheritanceConfig

type InstallationStore

type InstallationStore = core.InstallationStore

type InvokeCapabilityRequest

type InvokeCapabilityRequest = core.InvokeCapabilityRequest

type MetricsRecorder

type MetricsRecorder = core.MetricsRecorder

type OAuthStateStore

type OAuthStateStore = core.OAuthStateStore

type Option

type Option = core.Option

type PermissionEvaluator

type PermissionEvaluator = core.PermissionEvaluator

type ProviderPack

type ProviderPack struct {
	Name      string
	Providers []core.Provider
}

type Queries

type Queries struct {
	LoadSyncCursor       *servicesquery.LoadSyncCursorQuery
	ListServicesActivity *servicesquery.ListServicesActivityQuery
	GetInstallation      *servicesquery.GetInstallationQuery
	ListInstallations    *servicesquery.ListInstallationsQuery
	GetSyncJob           *servicesquery.GetSyncJobQuery
}

type RateLimitPolicy

type RateLimitPolicy = core.RateLimitPolicy

type ReconsentRequest

type ReconsentRequest = core.ReconsentRequest

type RefreshBackoffScheduler

type RefreshBackoffScheduler = core.RefreshBackoffScheduler

type RefreshRequest

type RefreshRequest = core.RefreshRequest

type RefreshRunOptions

type RefreshRunOptions = core.RefreshRunOptions

type RefreshRunResult

type RefreshRunResult = core.RefreshRunResult

type SecretProvider

type SecretProvider = core.SecretProvider

type Service

type Service = core.Service

func NewService

func NewService(cfg Config, opts ...Option) (*Service, error)

func Setup

func Setup(cfg Config, opts ...Option) (*Service, error)

type ServiceDependencies

type ServiceDependencies = core.ServiceDependencies

type Signer

type Signer = core.Signer

type SubscriptionStore

type SubscriptionStore = core.SubscriptionStore

type SyncCursorStore

type SyncCursorStore = core.SyncCursorStore

type SyncJobStore added in v0.2.0

type SyncJobStore = core.SyncJobStore

type TransportResolver

type TransportResolver = core.TransportResolver

Directories

Path Synopsis
Package adapters contains interoperability bridges with external runtimes.
Package adapters contains interoperability bridges with external runtimes.
gocommand
Package gocommand provides compatibility helpers for wiring go-services command flows through github.com/goliatone/go-command registry/dispatcher.
Package gocommand provides compatibility helpers for wiring go-services command flows through github.com/goliatone/go-command registry/dispatcher.
gojob
Package gojob provides compatibility adapters between go-services runtime contracts and github.com/goliatone/go-job queue/worker contracts.
Package gojob provides compatibility adapters between go-services runtime contracts and github.com/goliatone/go-job queue/worker contracts.
gologger
Package gologger bridges go-services logging contracts with go-logger and go-job logger-provider adapters.
Package gologger bridges go-services logging contracts with go-logger and go-job logger-provider adapters.
Package auth contains authentication strategy implementations.
Package auth contains authentication strategy implementations.
Package command exposes transport-agnostic command handlers that wrap go-services mutating core operations and implement go-command.Commander[T].
Package command exposes transport-agnostic command handlers that wrap go-services mutating core operations and implement go-command.Commander[T].
Package core contains canonical services domain contracts, entities, and orchestration logic.
Package core contains canonical services domain contracts, entities, and orchestration logic.
Package identity resolves normalized user profile fields from OAuth/OIDC credentials.
Package identity resolves normalized user profile fields from OAuth/OIDC credentials.
Package inbound contains inbound surface handling abstractions.
Package inbound contains inbound surface handling abstractions.
Package installations contains installation lifecycle orchestration.
Package installations contains installation lifecycle orchestration.
Package oauth2 contains OAuth2 flow helpers and adapter logic.
Package oauth2 contains OAuth2 flow helpers and adapter logic.
Package providers contains built-in provider implementations and factories.
Package providers contains built-in provider implementations and factories.
devkit
Package devkit provides reusable fixtures and conformance helpers for provider integration development and testing.
Package devkit provides reusable fixtures and conformance helpers for provider integration development and testing.
Package query exposes transport-agnostic read handlers that wrap go-services read-side operations and implement go-command.Querier[T, R].
Package query exposes transport-agnostic read handlers that wrap go-services read-side operations and implement go-command.Querier[T, R].
Package ratelimit contains rate-limit policy and quota state helpers.
Package ratelimit contains rate-limit policy and quota state helpers.
Package security contains encryption and signing adapter implementations.
Package security contains encryption and signing adapter implementations.
store
sql
Package sqlstore contains SQL-backed persistence adapters for core stores.
Package sqlstore contains SQL-backed persistence adapters for core stores.
Package sync contains sync orchestration contracts and implementations.
Package sync contains sync orchestration contracts and implementations.
Package transport contains protocol transport adapters used by providers.
Package transport contains protocol transport adapters used by providers.
Package webhooks contains webhook verification and dispatch components.
Package webhooks contains webhook verification and dispatch components.
Package worker contains worker runtime abstractions and adapters.
Package worker contains worker runtime abstractions and adapters.

Jump to

Keyboard shortcuts

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