coreapi

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package coreapi provides API management capabilities including rate limiting, API key management, and usage tracking.

CoreAPI is designed to work alongside CoreAuth for comprehensive API management:

  • CoreAuth: Authentication & Authorization (who can access what)
  • CoreAPI: API Management (how much, how fast, usage tracking)

Rate Limiting

Rate limiting is policy-based, where policies can be assigned to OAuth clients:

store := coreapi.NewMemoryPolicyStore()
store.SavePolicy(ctx, coreapi.PremiumPolicy)
store.AssignPolicyToClient(ctx, "my-oauth-client-id", "premium")

Integration with HTTP Middleware

Use with CoreForge session/ratelimit for HTTP enforcement:

resolver := ratelimit.NewPolicyResolver(store)
limiter := ratelimit.New(storage, ratelimit.WithResolver(resolver))
router.Use(limiter.Middleware())

Index

Constants

This section is empty.

Variables

View Source
var (
	// FreePolicy is for free tier users and anonymous requests.
	FreePolicy = &RateLimitPolicy{
		ID:          "free",
		Name:        "Free Tier",
		Description: "Rate limits for free tier users and anonymous requests",
		Enabled:     true,
		Limits: RateLimits{
			PerMinute: 10,
			PerHour:   100,
			PerDay:    500,
			BurstSize: 5,
		},
	}

	// StandardPolicy is for standard paid users.
	StandardPolicy = &RateLimitPolicy{
		ID:          "standard",
		Name:        "Standard Tier",
		Description: "Rate limits for standard tier users",
		Enabled:     true,
		Limits: RateLimits{
			PerMinute: 100,
			PerHour:   1000,
			PerDay:    10000,
			BurstSize: 20,
		},
	}

	// PremiumPolicy is for premium users.
	PremiumPolicy = &RateLimitPolicy{
		ID:          "premium",
		Name:        "Premium Tier",
		Description: "Rate limits for premium tier users",
		Enabled:     true,
		Limits: RateLimits{
			PerMinute: 1000,
			PerHour:   10000,
			PerDay:    100000,
			BurstSize: 100,
		},
	}

	// EnterprisePolicy is for enterprise users with high limits.
	EnterprisePolicy = &RateLimitPolicy{
		ID:          "enterprise",
		Name:        "Enterprise Tier",
		Description: "Rate limits for enterprise tier users",
		Enabled:     true,
		Limits: RateLimits{
			PerMinute: 10000,
			PerHour:   100000,
			PerDay:    1000000,
			BurstSize: 500,
		},
	}

	// InternalPolicy is for internal service-to-service calls.
	InternalPolicy = &RateLimitPolicy{
		ID:          "internal",
		Name:        "Internal Service",
		Description: "High limits for internal service-to-service communication",
		Enabled:     true,
		Priority:    100,
		Limits: RateLimits{
			PerSecond: 10000,
			BurstSize: 1000,
		},
	}

	// UnlimitedPolicy has no rate limits (use with caution).
	UnlimitedPolicy = &RateLimitPolicy{
		ID:          "unlimited",
		Name:        "Unlimited",
		Description: "No rate limits - use for trusted internal services only",
		Enabled:     true,
		Priority:    1000,
		Limits:      RateLimits{},
	}
)

Predefined rate limit policies for common use cases.

View Source
var (
	ErrPolicyNotFound  = errors.New("policy not found")
	ErrPolicyExists    = errors.New("policy already exists")
	ErrBindingNotFound = errors.New("client binding not found")
)

Common errors returned by the policy store.

Functions

This section is empty.

Types

type ClientPolicyBinding

type ClientPolicyBinding struct {
	// ClientID is the OAuth 2.0 client_id.
	ClientID string `json:"client_id"`

	// PolicyID is the ID of the bound policy.
	PolicyID string `json:"policy_id"`

	// Enabled controls whether this binding is active.
	Enabled bool `json:"enabled"`

	// CreatedAt is when the binding was created.
	CreatedAt time.Time `json:"created_at,omitzero"`
}

ClientPolicyBinding associates an OAuth client with a rate limit policy.

type MemoryPolicyStore

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

MemoryPolicyStore is an in-memory implementation of PolicyStore. Suitable for development, testing, or single-instance deployments.

func NewMemoryPolicyStore

func NewMemoryPolicyStore() *MemoryPolicyStore

NewMemoryPolicyStore creates a new in-memory policy store. It initializes with a default "standard" policy.

func NewMemoryPolicyStoreWithPolicies

func NewMemoryPolicyStoreWithPolicies(policies []*RateLimitPolicy, defaultPolicyID string) *MemoryPolicyStore

NewMemoryPolicyStoreWithPolicies creates a store initialized with the given policies.

func (*MemoryPolicyStore) BindClientToPolicy

func (s *MemoryPolicyStore) BindClientToPolicy(ctx context.Context, clientID, policyID string) error

BindClientToPolicy implements PolicyStore.

func (*MemoryPolicyStore) CreatePolicy

func (s *MemoryPolicyStore) CreatePolicy(ctx context.Context, policy *RateLimitPolicy) error

CreatePolicy implements PolicyStore.

func (*MemoryPolicyStore) DeletePolicy

func (s *MemoryPolicyStore) DeletePolicy(ctx context.Context, policyID string) error

DeletePolicy implements PolicyStore.

func (*MemoryPolicyStore) GetDefaultPolicy

func (s *MemoryPolicyStore) GetDefaultPolicy(ctx context.Context) (*RateLimitPolicy, error)

GetDefaultPolicy implements PolicyStore.

func (*MemoryPolicyStore) GetPolicy

func (s *MemoryPolicyStore) GetPolicy(ctx context.Context, policyID string) (*RateLimitPolicy, error)

GetPolicy implements PolicyStore.

func (*MemoryPolicyStore) GetPolicyForClient

func (s *MemoryPolicyStore) GetPolicyForClient(ctx context.Context, clientID string) (*RateLimitPolicy, error)

GetPolicyForClient implements PolicyStore.

func (*MemoryPolicyStore) ListClientBindings

func (s *MemoryPolicyStore) ListClientBindings(ctx context.Context) ([]*ClientPolicyBinding, error)

ListClientBindings implements PolicyStore.

func (*MemoryPolicyStore) ListClientsForPolicy

func (s *MemoryPolicyStore) ListClientsForPolicy(ctx context.Context, policyID string) ([]string, error)

ListClientsForPolicy implements PolicyStore.

func (*MemoryPolicyStore) ListPolicies

func (s *MemoryPolicyStore) ListPolicies(ctx context.Context) ([]*RateLimitPolicy, error)

ListPolicies implements PolicyStore.

func (*MemoryPolicyStore) SetDefaultPolicy

func (s *MemoryPolicyStore) SetDefaultPolicy(ctx context.Context, policyID string) error

SetDefaultPolicy implements PolicyStore.

func (*MemoryPolicyStore) UnbindClient

func (s *MemoryPolicyStore) UnbindClient(ctx context.Context, clientID string) error

UnbindClient implements PolicyStore.

func (*MemoryPolicyStore) UpdatePolicy

func (s *MemoryPolicyStore) UpdatePolicy(ctx context.Context, policy *RateLimitPolicy) error

UpdatePolicy implements PolicyStore.

type PolicyStore

type PolicyStore interface {
	// Policy CRUD operations
	GetPolicy(ctx context.Context, policyID string) (*RateLimitPolicy, error)
	ListPolicies(ctx context.Context) ([]*RateLimitPolicy, error)
	CreatePolicy(ctx context.Context, policy *RateLimitPolicy) error
	UpdatePolicy(ctx context.Context, policy *RateLimitPolicy) error
	DeletePolicy(ctx context.Context, policyID string) error

	// Default policy
	GetDefaultPolicy(ctx context.Context) (*RateLimitPolicy, error)
	SetDefaultPolicy(ctx context.Context, policyID string) error

	// Client bindings
	GetPolicyForClient(ctx context.Context, clientID string) (*RateLimitPolicy, error)
	BindClientToPolicy(ctx context.Context, clientID, policyID string) error
	UnbindClient(ctx context.Context, clientID string) error
	ListClientBindings(ctx context.Context) ([]*ClientPolicyBinding, error)
	ListClientsForPolicy(ctx context.Context, policyID string) ([]string, error)
}

PolicyStore defines the interface for managing rate limit policies.

type RateLimitPolicy

type RateLimitPolicy struct {
	// ID is the unique identifier for this policy.
	ID string `json:"id"`

	// Name is a human-readable name for the policy.
	Name string `json:"name"`

	// Description explains the policy's purpose.
	Description string `json:"description,omitempty"`

	// Limits defines the rate limits for this policy.
	Limits RateLimits `json:"limits"`

	// EndpointOverrides allows different limits for specific endpoints.
	// Keys are path prefixes (e.g., "/api/v1/uploads").
	EndpointOverrides map[string]RateLimits `json:"endpoint_overrides,omitempty"`

	// Priority determines precedence when multiple policies apply.
	// Higher priority wins. Default is 0.
	Priority int `json:"priority,omitempty"`

	// Enabled controls whether the policy is active.
	Enabled bool `json:"enabled"`

	// Metadata holds arbitrary key-value data.
	Metadata map[string]string `json:"metadata,omitempty"`

	// CreatedAt is when the policy was created.
	CreatedAt time.Time `json:"created_at,omitzero"`

	// UpdatedAt is when the policy was last modified.
	UpdatedAt time.Time `json:"updated_at,omitzero"`
}

RateLimitPolicy defines rate limits that can be applied to API clients.

func DefaultPolicies

func DefaultPolicies() []*RateLimitPolicy

DefaultPolicies returns all predefined policies.

func (*RateLimitPolicy) WithEndpointOverride

func (p *RateLimitPolicy) WithEndpointOverride(pathPrefix string, limits RateLimits) *RateLimitPolicy

WithEndpointOverride returns a copy of the policy with an endpoint override added.

type RateLimits

type RateLimits struct {
	// PerSecond is the maximum requests per second.
	PerSecond int `json:"per_second,omitempty"`

	// PerMinute is the maximum requests per minute.
	PerMinute int `json:"per_minute,omitempty"`

	// PerHour is the maximum requests per hour.
	PerHour int `json:"per_hour,omitempty"`

	// PerDay is the maximum requests per day.
	PerDay int `json:"per_day,omitempty"`

	// BurstSize is the maximum burst allowed.
	// If zero, defaults to the most granular rate limit.
	BurstSize int `json:"burst_size,omitempty"`
}

RateLimits defines rate limits across multiple time windows. Zero values mean no limit for that window.

func (RateLimits) IsUnlimited

func (r RateLimits) IsUnlimited() bool

IsUnlimited returns true if no rate limits are configured.

func (RateLimits) MostGranularLimit

func (r RateLimits) MostGranularLimit() (rate int, period time.Duration, burst int)

MostGranularLimit returns the most granular non-zero limit from RateLimits. Returns rate, period, and burst.

type UsageRecord

type UsageRecord struct {
	// ClientID is the OAuth client that made the requests.
	ClientID string `json:"client_id"`

	// PrincipalID is the user/principal if applicable.
	PrincipalID string `json:"principal_id,omitempty"`

	// Endpoint is the API endpoint (optional, for per-endpoint tracking).
	Endpoint string `json:"endpoint,omitempty"`

	// Period is the time period for this record.
	Period time.Time `json:"period"`

	// PeriodType is the granularity (minute, hour, day).
	PeriodType string `json:"period_type"`

	// RequestCount is the number of requests made.
	RequestCount int64 `json:"request_count"`

	// RateLimitedCount is requests that were rate limited.
	RateLimitedCount int64 `json:"rate_limited_count"`
}

UsageRecord represents API usage for a client in a time period.

type UsageStore

type UsageStore interface {
	// RecordRequest increments the usage counter for a client.
	RecordRequest(ctx context.Context, clientID, principalID, endpoint string, rateLimited bool) error

	// GetUsage retrieves usage records for a client.
	GetUsage(ctx context.Context, clientID string, from, to time.Time) ([]*UsageRecord, error)

	// GetUsageSummary retrieves aggregated usage for a client.
	GetUsageSummary(ctx context.Context, clientID string, periodType string, from, to time.Time) (*UsageSummary, error)
}

UsageStore defines the interface for tracking API usage.

type UsageSummary

type UsageSummary struct {
	ClientID         string    `json:"client_id"`
	PeriodStart      time.Time `json:"period_start"`
	PeriodEnd        time.Time `json:"period_end"`
	TotalRequests    int64     `json:"total_requests"`
	RateLimitedCount int64     `json:"rate_limited_count"`
	UniqueEndpoints  int       `json:"unique_endpoints"`
	UniquePrincipals int       `json:"unique_principals"`
}

UsageSummary provides aggregated usage statistics.

Jump to

Keyboard shortcuts

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