kernel

package
v1.0.73 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package kernel provides authenticated cross-account calls to kernel services.

This package enables partner account services to make SigV4-authenticated API calls to services running in the kernel account (qakernel or production kernel).

Overview

The kernel client handles:

  • STS AssumeRole for cross-account authentication
  • SigV4 request signing for API Gateway
  • Automatic kernel environment detection (qakernel vs kernel)
  • URL construction with region/service prefix support
  • Integration with Lift observability (logger, metrics, tracing)

Authentication Modes

Mode 1: Shared Role (Default for trusted partners in AWS Organization)

  • Uses role: kernel-access
  • No External ID required
  • For partners: qakernel, paytheory, etc.

Mode 2: External Partner Role (For partners outside AWS Organization)

  • Uses role: kernel-access-external
  • Requires External ID via K3_EXTERNAL_ID environment variable
  • For external partners with additional security requirements

Environment Variables

Required:

  • PARTNER: Partner identifier (e.g., "qakernel", "paytheory")
  • STAGE: Deployment stage (e.g., "dev", "stage", "prod")

Optional:

  • TARGET_REGION: AWS region (default: "us-east-1")
  • K3_EXTERNAL_ID: External ID for Mode 2 authentication
  • KERNEL_ENV_OVERRIDE: Force kernel environment ("qakernel" or "kernel")

Kernel Environment Selection

The client automatically selects the kernel environment based on partner:

  • Partners "innovate" and "austin" → qakernel (account: 058264189048)
  • All other partners → kernel (account: 075149869707)
  • Override with KERNEL_ENV_OVERRIDE environment variable

URL Patterns

K3 (without region):

https://k3.{kernel_env}.{stage}.com/{endpoint}

Other services (with region):

https://{region}.{kernel_env}.{stage}.com/{service-prefix}/{endpoint}

Usage Examples

Basic client creation:

import (
    "context"
    "github.com/pay-theory/lift/pkg/services/kernel"
    pkglogger "github.com/yourservice/internal/logger"
)

// Create kernel client using your service's singleton logger
ctx := context.Background()
client, err := kernel.NewClient(ctx, pkglogger.GetLiftLogger)
if err != nil {
    log.Fatal(err)
}

Call Paze wallet service:

response, err := client.PazeWalletCall(ctx, "decode-token", map[string]any{
    "token": "encrypted_paze_token...",
})
if err != nil {
    log.Printf("Paze call failed: %v", err)
    return err
}

var result map[string]any
if err := response.Unmarshal(&result); err != nil {
    log.Printf("Failed to unmarshal response: %v", err)
    return err
}

Call K3 API:

response, err := client.K3Call(ctx, "v1/tokenize", map[string]any{
    "card_number": "4111111111111111",
    "exp_month":   "12",
    "exp_year":    "2025",
    "cvv":         "123",
}, "POST")
if err != nil {
    log.Printf("K3 call failed: %v", err)
    return err
}

Call bin lookup service:

response, err := client.BinLookupCall(ctx, "?card_bin=411111", "GET", nil)
if err != nil {
    log.Printf("Bin lookup failed: %v", err)
    return err
}

var binData struct {
    CardBrand string `json:"card_brand"`
    CardType  string `json:"card_type"`
    BankName  string `json:"bank_name"`
}
if err := response.Unmarshal(&binData); err != nil {
    log.Printf("Failed to unmarshal bin data: %v", err)
    return err
}

Generic call with custom options:

response, err := client.Call(ctx, &kernel.CallOptions{
    ServicePrefix:  "custom-service",
    Endpoint:       "api/v1/process",
    Method:         "POST",
    Body:           map[string]any{"data": "value"},
    IncludeRegion:  true,
    Subsystem:      "CUSTOM SERVICE",
    ConnectTimeout: 10 * time.Second,
    ReadTimeout:    30 * time.Second,
    Headers: map[string]string{
        "X-Custom-Header": "custom-value",
    },
})
if err != nil {
    log.Printf("Custom call failed: %v", err)
    return err
}

Using with Lift middleware:

import (
    "github.com/pay-theory/lift/pkg/lift"
    "github.com/pay-theory/lift/pkg/services/kernel"
    pkglogger "github.com/yourservice/internal/logger"
)

// In main.go Lambda setup
app := lift.New()

// Create kernel client with your singleton logger getter
kernelClient, err := kernel.NewClient(ctx, pkglogger.GetLiftLogger)
if err != nil {
    log.Fatal(err)
}

// Register middleware
app.Use(kernel.KernelClientMiddleware(kernelClient))

// In handler function
func MyHandler(ctx *lift.Context) error {
    // Get kernel client from context
    kernelClient := kernel.GetKernelClient(ctx)
    if kernelClient == nil {
        return lift.SystemError("Kernel client not available")
    }

    // Use kernel client
    response, err := kernelClient.PazeWalletCall(ctx, "decode-token", data, "POST")
    if err != nil {
        return lift.SystemError("Paze call failed").WithCause(err)
    }

    return ctx.OK(response)
}

Convenience Functions

The package provides service-specific convenience functions:

  • K3Call: Call K3 API Gateway
  • PazeWalletCall: Call Paze Wallet Key Service
  • AppleWalletCall: Call Apple Wallet Key Service
  • GoogleWalletCall: Call Google Wallet Key Service
  • BinLookupCall: Call Bin Lookup Service
  • BankDataCall: Call Bank Data Service

All convenience functions use sensible defaults for method, region inclusion, and subsystem logging names.

Error Handling

The client returns errors for:

  • Missing required environment variables
  • STS AssumeRole failures (invalid credentials, role not found)
  • HTTP request failures (network errors, timeouts)
  • HTTP status codes >= 400 (includes error details in logs)

Logging

All calls are logged with structured logging including:

  • Request details (service, endpoint, method)
  • Response details (status code, duration)
  • Error details (for failures)
  • Subsystem tags (for filtering logs by service)

Security

The client implements AWS best practices:

  • STS AssumeRole with least-privilege temporary credentials
  • SigV4 request signing for authentication
  • External ID support for cross-organization access
  • Automatic credential expiration handling
  • TLS encryption for all HTTP requests

Performance

The client is designed for performance:

  • Reusable HTTP client with connection pooling
  • Configurable timeouts (connect, read)
  • Efficient request signing
  • Minimal memory allocations

Thread Safety

The Client struct is safe for concurrent use. Multiple goroutines can call methods on the same Client instance simultaneously.

Index

Constants

View Source
const (
	// Kernel account IDs
	QAKernelAccountID = "058264189048"
	KernelAccountID   = "075149869707"

	// Default timeouts
	DefaultConnectTimeout = 30 * time.Second
	DefaultReadTimeout    = 30 * time.Second
)

Variables

This section is empty.

Functions

func KernelClientMiddleware

func KernelClientMiddleware(client *Client) lift.Middleware

KernelClientMiddleware creates middleware for kernel client integration

Types

type CallOptions

type CallOptions struct {
	Body           any               // Request payload (will be JSON marshaled)
	Headers        map[string]string // Additional headers (optional)
	ServicePrefix  string            // Service name (e.g., "k3", "paze-wallet-key-service")
	Endpoint       string            // API endpoint path
	Method         string            // HTTP method (GET, POST, etc.)
	Subsystem      string            // Logging subsystem name (optional)
	ConnectTimeout time.Duration     // Connection timeout (optional)
	ReadTimeout    time.Duration     // Read timeout (optional)
	IncludeRegion  bool              // Whether to include region in URL
}

CallOptions configures a kernel service call

type Client

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

Client provides authenticated cross-account calls to kernel services

func GetKernelClient

func GetKernelClient(ctx *lift.Context) *Client

GetKernelClient retrieves the kernel client from Lift context

func NewClient

func NewClient(ctx context.Context, loggerFunc LoggerFunc) (*Client, error)

NewClient creates a new kernel service client loggerFunc should return the calling service's singleton logger (e.g., logger.GetLiftLogger)

func NewClientWithConfig

func NewClientWithConfig(
	ctx context.Context,
	loggerFunc LoggerFunc,
	partner, stage, region string,
	connectTimeout, readTimeout time.Duration,
) (*Client, error)

NewClientWithConfig creates a client with custom configuration

func (*Client) AppleWalletCall

func (c *Client) AppleWalletCall(ctx context.Context, endpoint string, body any, method string) (*Response, error)

AppleWalletCall makes an authenticated call to Apple Wallet Key Service

func (*Client) BankDataCall

func (c *Client) BankDataCall(ctx context.Context, endpoint string, method string, body any) (*Response, error)

BankDataCall makes an authenticated call to Bank Data Service

func (*Client) BinLookupCall

func (c *Client) BinLookupCall(ctx context.Context, endpoint string, method string, body any) (*Response, error)

BinLookupCall makes an authenticated call to Bin Lookup Service

func (*Client) Call

func (c *Client) Call(ctx context.Context, opts *CallOptions) (*Response, error)

Call makes an authenticated call to a kernel service

func (*Client) GoogleWalletCall

func (c *Client) GoogleWalletCall(ctx context.Context, endpoint string, body any, method string) (*Response, error)

GoogleWalletCall makes an authenticated call to Google Wallet Key Service

func (*Client) K3Call

func (c *Client) K3Call(ctx context.Context, endpoint string, body any, method string) (*Response, error)

K3Call makes an authenticated call to K3 API Gateway

func (*Client) PazeWalletCall

func (c *Client) PazeWalletCall(ctx context.Context, endpoint string, body any, method string) (*Response, error)

PazeWalletCall makes an authenticated call to Paze Wallet Key Service

type LoggerFunc

type LoggerFunc func() observability.StructuredLogger

LoggerFunc is a function that returns the singleton logger from the calling service

type Response

type Response struct {
	Body       []byte
	Headers    map[string]string
	StatusCode int
	Duration   time.Duration
}

Response represents a kernel service response

func (*Response) Unmarshal

func (r *Response) Unmarshal(v any) error

Unmarshal unmarshals the response body into the provided struct

Jump to

Keyboard shortcuts

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