platform

package
v0.40.6 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

OrgService provides per-org configuration, credential resolution, and customer identity management. Registered in app.Store() as "org" so Base Functions (Goja JS) can call methods directly:

var org = $app.store().get("org")
var creds = org.getCreds(orgId, "commerce")
var config = org.getConfig(orgId)
var customer = org.getCustomer(orgId, userId)

Package platform implements a multi-org platform plugin for Hanzo Base.

Each org gets isolated collections with prefix-based namespacing. Authentication is handled via Hanzo IAM (hanzo.id) OAuth2 and secrets via Hanzo KMS (kms.hanzo.ai) Universal Auth.

Example:

platform.MustRegister(app, platform.PlatformConfig{
	IAMEndpoint:     "https://hanzo.id",
	KMSEndpoint:     "https://kms.hanzo.ai",
	IAMClientID:     "my-client-id",
	IAMClientSecret: "my-client-secret",
})

Index

Constants

View Source
const (

	// Member roles.
	RoleOwner  = "owner"
	RoleAdmin  = "admin"
	RoleMember = "member"
	RoleViewer = "viewer"
)

Variables

This section is empty.

Functions

func CreateOrgCollections added in v0.29.7

func CreateOrgCollections(app core.App, orgSlug string, templates []CollectionTemplate) error

CreateOrgCollections creates prefixed collections for an org from the given templates. Each template's Name is prefixed with t_{slug}_.

Collections that already exist are skipped.

func CreateOrgProject added in v0.29.7

func CreateOrgProject(orgSlug string, config PlatformConfig) (string, error)

CreateOrgProject creates a KMS project (workspace environment) for an org identified by slug. Returns the project/environment ID.

func DeleteOrgCollections added in v0.29.7

func DeleteOrgCollections(app core.App, orgSlug string) error

DeleteOrgCollections removes all collections with the org's prefix.

func ExchangeOAuth2Token

func ExchangeOAuth2Token(code, redirectURI string, config PlatformConfig) (accessToken, refreshToken string, err error)

ExchangeOAuth2Token exchanges an authorization code for tokens using the IAM OAuth2 token endpoint.

func FetchSecret

func FetchSecret(path string, config PlatformConfig) (string, error)

FetchSecret fetches a secret value from Hanzo KMS at the given path. Uses Universal Auth machine identity (config.IAMClientID / IAMClientSecret).

func IsAPIKey added in v0.39.0

func IsAPIKey(token string) bool

IsAPIKey returns true if the token is any type of IAM API key.

func IsAnalyticsKey added in v0.39.0

func IsAnalyticsKey(token string) bool

IsAnalyticsKey returns true if the token is an insights or analytics key.

func IsPublishableKey added in v0.39.0

func IsPublishableKey(token string) bool

IsPublishableKey returns true if the token has a publishable key prefix.

func IsSecretKey added in v0.39.0

func IsSecretKey(token string) bool

IsSecretKey returns true if the token has a secret key prefix.

func IsWidgetKey added in v0.39.0

func IsWidgetKey(token string) bool

IsWidgetKey returns true if the token is a widget embed key.

func ListOrgCollections added in v0.29.7

func ListOrgCollections(app core.App, orgSlug string) ([]string, error)

ListOrgCollections returns all collection names belonging to an org.

func MustRegister

func MustRegister(app core.App, config PlatformConfig)

MustRegister registers the platform plugin to the provided app instance and panics if it fails.

func OrgPrefix added in v0.29.7

func OrgPrefix(slug string) string

OrgPrefix returns the collection name prefix for an org slug. Format: t_{slug}_

func Register

func Register(app core.App, config PlatformConfig) error

Register registers the platform plugin to the provided app instance.

func ScopedQuery

func ScopedQuery(orgSlug, collection string) string

ScopedQuery returns the prefixed collection name for an org. Example: ScopedQuery("acme", "tasks") returns "t_acme_tasks".

Types

type AuthProxyConfig

type AuthProxyConfig struct {
	IAMEndpoint string
	IAMOrg      string
	IAMApp      string
}

AuthProxyConfig holds the subset of PlatformConfig needed by the auth proxy.

type CollectionTemplate

type CollectionTemplate struct {
	// Name is the base collection name (without org prefix).
	// The actual collection will be created as t_{slug}_{Name}.
	Name string

	// Type is the collection type: "base", "auth", or "view".
	// Defaults to "base" if empty.
	Type string

	// Fields defines the fields for the collection.
	Fields []core.Field
}

CollectionTemplate defines a collection schema that gets cloned per org.

type ComplianceClient

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

ComplianceClient handles communication with the luxfi/compliance service. The compliance service provides KYC/AML, sanctions screening, transaction monitoring, and regulatory validation. This is an optional extension — if ComplianceEndpoint is empty, compliance features are disabled.

func NewComplianceClient

func NewComplianceClient(baseURL, apiKey string) *ComplianceClient

NewComplianceClient creates a client for the compliance service.

func (*ComplianceClient) CreateApplication

func (c *ComplianceClient) CreateApplication(givenName, familyName, email, country string) (string, error)

CreateApplication creates a compliance application for a user.

func (*ComplianceClient) Enabled

func (c *ComplianceClient) Enabled() bool

Enabled returns true if the compliance client is configured.

func (*ComplianceClient) GetKYCStatus

func (c *ComplianceClient) GetKYCStatus(applicationID string) (*ComplianceStatus, error)

GetKYCStatus returns the current KYC status for an application.

func (*ComplianceClient) InitiateKYC

func (c *ComplianceClient) InitiateKYC(applicationID, provider string) (verificationID, redirectURL string, err error)

InitiateKYC starts identity verification for an application.

func (*ComplianceClient) ScreenIndividual

func (c *ComplianceClient) ScreenIndividual(givenName, familyName, country string) (*ScreeningResult, error)

ScreenIndividual runs AML/sanctions screening.

func (*ComplianceClient) ValidatePayment

func (c *ComplianceClient) ValidatePayment(fromID, toID string, amount float64, currency, jurisdiction string) (approved bool, reason string, err error)

ValidatePayment checks payment compliance (travel rule, sanctions, CTR).

type ComplianceStatus

type ComplianceStatus struct {
	ApplicationID string `json:"application_id"`
	Status        string `json:"status"`     // draft, pending, pending_kyc, approved, rejected
	KYCStatus     string `json:"kyc_status"` // not_started, pending, verified, failed
	KYCProvider   string `json:"kyc_provider,omitempty"`
}

ComplianceStatus represents a user's KYC/compliance status.

type DBPool added in v0.39.1

type DBPool = dbx.Pool

type DBPoolConfig added in v0.39.1

type DBPoolConfig = dbx.PoolConfig

func DefaultPoolConfig added in v0.40.0

func DefaultPoolConfig() DBPoolConfig

DefaultPoolConfig returns a PoolConfig with production defaults, overridable via environment variables:

DB_POOL_MAX          — max open DB pools (default: 2000, hard cap: 2000)
DB_POOL_IDLE_TIMEOUT — idle timeout duration (default: 30s, e.g. "1m", "45s")
DB_POOL_SHARDS       — number of lock shards (default: runtime.NumCPU())
DB_POOL_READ_CONNS   — read connections per DB (default: 4)

type DBPoolManager added in v0.39.1

type DBPoolManager = dbx.PoolManager

func NewDBPoolManager added in v0.39.1

func NewDBPoolManager(config DBPoolConfig) *DBPoolManager

type IAMClient

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

IAMClient handles authentication against Hanzo IAM with token caching.

func NewIAMClient

func NewIAMClient(baseURL string) *IAMClient

NewIAMClient creates a new IAM client pointed at the given base URL.

func (*IAMClient) InvalidateToken

func (c *IAMClient) InvalidateToken(token string)

InvalidateToken removes a token from the cache.

func (*IAMClient) ResolveAPIKey added in v0.39.0

func (c *IAMClient) ResolveAPIKey(accessKey string) (*IAMUser, error)

ResolveAPIKey resolves an IAM API key (hk-/pk-/sk-) to user + org context. Uses IAM's GET /api/get-user?accessKey= endpoint. Results cached 5 minutes.

func (*IAMClient) ValidateToken

func (c *IAMClient) ValidateToken(token string) (*IAMUser, error)

ValidateToken validates a Bearer token against IAM userinfo. Results are cached for 5 minutes.

type IAMKey added in v0.39.0

type IAMKey struct {
	Owner       string `json:"owner"`
	Name        string `json:"name"`
	Type        string `json:"type"` // Organization, Application, User
	Org         string `json:"organization"`
	Application string `json:"application"`
	User        string `json:"user"`
	AccessKey   string `json:"accessKey"`
	State       string `json:"state"`
}

IAMKey represents an API key from IAM's Key table.

type IAMUser

type IAMUser struct {
	ID     string   `json:"id"`
	Email  string   `json:"email"`
	Name   string   `json:"name"`
	OrgIDs []string `json:"orgIds"`
}

IAMUser represents an authenticated user from Hanzo IAM.

func ValidateIAMToken

func ValidateIAMToken(token string, config PlatformConfig) (*IAMUser, error)

ValidateIAMToken validates a bearer token against the IAM userinfo endpoint at config.IAMEndpoint/api/userinfo.

This is a convenience function that creates a one-off HTTP request. For production use with caching, use the IAMClient returned by NewIAMClient.

type KMSClient

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

KMSClient handles secret operations with caching.

func NewKMSClient

func NewKMSClient(baseURL, authToken string) *KMSClient

NewKMSClient creates a new KMS client. If baseURL or authToken is empty, operations will return errors but the plugin still functions.

func (*KMSClient) DeleteSecret

func (c *KMSClient) DeleteSecret(orgId, secretPath string) error

DeleteSecret removes a secret.

func (*KMSClient) GetSecret

func (c *KMSClient) GetSecret(orgId, secretPath string) (string, error)

GetSecret fetches a secret with caching (1 min TTL).

func (*KMSClient) InvalidateCache

func (c *KMSClient) InvalidateCache(orgId string)

InvalidateCache clears all cached secrets for an org.

func (*KMSClient) SetSecret

func (c *KMSClient) SetSecret(orgId, secretPath, value string) error

SetSecret creates or updates a secret.

type OrgDB added in v0.29.7

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

OrgDB manages per-org AND per-user SQLite databases.

Directory layout:

{DataDir}/orgs/{orgSlug}/org.db              ← org-level shared data
{DataDir}/orgs/{orgSlug}/users/{userId}/data.db  ← per-user PII + keys

Each file is independently encrypted with a unique DEK:

org DEK  = HMAC-SHA256(masterKey, orgSlug)
user DEK = HMAC-SHA256(masterKey, orgSlug + ":" + userId)

Zero data commingling — org data, user PII, and keys are all in separate files with separate encryption keys.

func NewOrgDB added in v0.29.7

func NewOrgDB(app core.App, masterKey string) *OrgDB

func (*OrgDB) DeleteOrg added in v0.29.7

func (t *OrgDB) DeleteOrg(orgSlug string) error

DeleteOrg removes an org's entire directory (including all user databases).

func (*OrgDB) DeleteUser added in v0.29.7

func (t *OrgDB) DeleteUser(orgSlug, userId string) error

DeleteUser removes a user's database directory.

func (*OrgDB) GetOrgDBPath added in v0.29.7

func (t *OrgDB) GetOrgDBPath(orgSlug string) (string, bool)

GetOrgDBPath returns the database path for an existing org.

func (*OrgDB) GetUserDBPath added in v0.29.7

func (t *OrgDB) GetUserDBPath(orgSlug, userId string) (string, bool)

GetUserDBPath returns the database path for an existing user.

func (*OrgDB) ListOrgs added in v0.29.7

func (t *OrgDB) ListOrgs() ([]string, error)

ListOrgs returns all provisioned org slugs.

func (*OrgDB) ListUsers added in v0.29.7

func (t *OrgDB) ListUsers(orgSlug string) ([]string, error)

ListUsers returns all provisioned user IDs within an org.

func (*OrgDB) OrgDBPath added in v0.29.7

func (t *OrgDB) OrgDBPath(orgSlug string) string

OrgDBPath returns the org-level SQLite database path.

func (*OrgDB) OrgDEK added in v0.29.7

func (t *OrgDB) OrgDEK(orgSlug string) string

OrgDEK derives the org-level data encryption key using HKDF (RFC 5869). Go 1.26+ stdlib crypto/hkdf — proper key derivation, not raw HMAC.

func (*OrgDB) OrgDir added in v0.29.7

func (t *OrgDB) OrgDir(orgSlug string) string

OrgDir returns the directory for an org. Validates slug to prevent path traversal.

func (*OrgDB) OrgsDir added in v0.29.7

func (t *OrgDB) OrgsDir() string

OrgsDir returns the base directory for all org databases.

func (*OrgDB) ProvisionOrg added in v0.29.7

func (t *OrgDB) ProvisionOrg(orgSlug string) (string, error)

ProvisionOrg creates the org directory and org-level database.

func (*OrgDB) ProvisionUser added in v0.29.7

func (t *OrgDB) ProvisionUser(orgSlug, userId string) (string, error)

ProvisionUser creates the per-user directory and database.

func (*OrgDB) UserDBPath added in v0.29.7

func (t *OrgDB) UserDBPath(orgSlug, userId string) string

UserDBPath returns the per-user SQLite database path.

func (*OrgDB) UserDEK added in v0.29.7

func (t *OrgDB) UserDEK(orgSlug, userId string) string

UserDEK derives the per-user data encryption key using HKDF (RFC 5869). Different from the org DEK — user PII gets a user-specific key.

func (*OrgDB) UserDir added in v0.29.7

func (t *OrgDB) UserDir(orgSlug, userId string) string

UserDir returns the directory for a specific user within an org.

type OrgService added in v0.29.7

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

OrgService provides per-org configuration, credential resolution, and customer identity management.

func (*OrgService) GetConfig added in v0.29.7

func (s *OrgService) GetConfig(orgId string) map[string]any

GetConfig returns the org_configs record for an org. Cached 5min.

func (*OrgService) GetCreds added in v0.29.7

func (s *OrgService) GetCreds(orgId, provider string) map[string]string

GetCreds fetches per-org credentials from KMS. Path convention: /orgs/{orgId}/{provider}/{key} Returns map like {"api_key": "...", "api_secret": "...", "base_url": "..."} Cached 5min per (orgId, provider) pair. Falls back to env vars if KMS not configured or secret not found (dev mode).

func (*OrgService) GetCustomer added in v0.29.7

func (s *OrgService) GetCustomer(orgId, userId string) map[string]any

GetCustomer looks up the org_customers record for (orgId, userId).

func (*OrgService) GetOrProvisionCustomer added in v0.29.7

func (s *OrgService) GetOrProvisionCustomer(orgId, userId string) (map[string]any, error)

GetOrProvisionCustomer returns existing customer or creates one.

func (*OrgService) InvalidateCreds added in v0.29.7

func (s *OrgService) InvalidateCreds(orgId string)

InvalidateCreds clears the credential cache for an org (all providers).

func (*OrgService) ProvisionCustomer added in v0.29.7

func (s *OrgService) ProvisionCustomer(orgId, userId string, opts map[string]any) (map[string]any, error)

ProvisionCustomer creates a new customer identity for a user in an org. Generates a sequential customer_id, creates the record.

func (*OrgService) SetCreds added in v0.29.7

func (s *OrgService) SetCreds(orgId, provider string, creds map[string]string) error

SetCreds stores credentials in KMS for an org+provider.

type OrgStorage added in v0.29.7

type OrgStorage struct {
	// Endpoint is the S3 endpoint (e.g., "s3.hanzo.space:9000" or "s3.hanzo.ai").
	Endpoint string

	// Bucket is the root bucket name (e.g., "orgs").
	Bucket string

	// MasterKey for deriving per-org and per-user SSE keys.
	MasterKey string

	// UseSSL enables TLS for the S3 connection.
	UseSSL bool

	// Region for the S3 bucket (default: "us-east-1").
	Region string
}

OrgStorage manages per-org and per-user S3 bucket isolation.

Bucket layout on Hanzo S3 (s3.hanzo.space):

orgs/{orgSlug}/                         ← org bucket prefix
orgs/{orgSlug}/org/                     ← org-level shared data
orgs/{orgSlug}/users/{userId}/          ← per-user isolated storage

Each org gets its own SSE-KMS key derived from the master key. Each user gets their own SSE-C key for client-side encryption.

IAM policy ensures:

  • Org admins can access orgs/{orgSlug}/*
  • Users can only access orgs/{orgSlug}/users/{userId}/*
  • No cross-org or cross-user access possible

func (*OrgStorage) BucketPolicy added in v0.29.7

func (s *OrgStorage) BucketPolicy(orgSlug, iamUser string) string

BucketPolicy returns a MinIO/S3 bucket policy JSON that enforces per-org path isolation. Uses encoding/json to prevent injection via orgSlug/iamUser.

func (*OrgStorage) OrgDataPrefix added in v0.29.7

func (s *OrgStorage) OrgDataPrefix(orgSlug string) string

OrgDataPrefix returns the S3 key prefix for org-level shared data.

func (*OrgStorage) OrgPrefix added in v0.29.7

func (s *OrgStorage) OrgPrefix(orgSlug string) string

OrgPrefix returns the S3 key prefix for an org.

func (*OrgStorage) OrgSSEKey added in v0.29.7

func (s *OrgStorage) OrgSSEKey(orgSlug string) string

OrgSSEKey derives a per-org SSE-C encryption key (32 bytes, base64-encoded). Used as the SSE-C CustomerKey header for server-side encryption.

func (*OrgStorage) UserBucketPolicy added in v0.29.7

func (s *OrgStorage) UserBucketPolicy(orgSlug, userId, iamUser string) string

UserBucketPolicy returns a policy restricting a user to their own prefix only.

func (*OrgStorage) UserPrefix added in v0.29.7

func (s *OrgStorage) UserPrefix(orgSlug, userId string) string

UserPrefix returns the S3 key prefix for a specific user.

func (*OrgStorage) UserSSEKey added in v0.29.7

func (s *OrgStorage) UserSSEKey(orgSlug, userId string) string

UserSSEKey derives a per-user SSE-C encryption key (32 bytes, base64-encoded). Each user's objects are encrypted with a unique key — even if the bucket is shared, objects cannot be decrypted without the user-specific key.

type PlatformConfig

type PlatformConfig struct {
	// IAMEndpoint is the base URL for Hanzo IAM (default: "https://hanzo.id").
	IAMEndpoint string

	// KMSEndpoint is the base URL for Hanzo KMS (default: "https://kms.hanzo.ai").
	KMSEndpoint string

	// IAMClientID is the OAuth2 client ID for IAM authentication.
	IAMClientID string

	// IAMClientSecret is the OAuth2 client secret for IAM authentication.
	IAMClientSecret string

	// IAMOrg is the IAM organization identifier (optional, used by auth proxy).
	IAMOrg string

	// IAMApp is the IAM application identifier (optional, used by auth proxy).
	IAMApp string

	// ComplianceEndpoint is the base URL for Lux Compliance service (optional).
	// If set, enables KYC/AML screening and payment compliance for orgs.
	ComplianceEndpoint string

	// ComplianceAPIKey is the API key for the compliance service.
	ComplianceAPIKey string

	// PrincipalIsolation controls how principal (org or user) data is physically separated.
	//   "prefix"   — (default) t_{slug}_ prefixed collections in shared DB
	//   "sqlite"   — separate encrypted Liquid SQL file per principal
	//   "postgres" — separate PostgreSQL database per principal
	//
	// For "sqlite" mode, each principal gets its own database file at:
	//   {DataDir}/orgs/{slug}/data.db (orgs)
	//   {DataDir}/users/{userId}/data.db (per-user, when enabled)
	// For "postgres" mode, each principal gets a dedicated schema or database.
	// The backend can be configured per-principal via PrincipalBackendFunc.
	//
	// PII is physically isolated — zero data commingling.
	PrincipalIsolation string

	// Deprecated: use PrincipalIsolation. Kept as alias for backward compatibility.
	OrgIsolation string

	// PrincipalEncryptionKey is the master key for deriving per-principal DEKs.
	// Used for both Liquid SQL encryption AND S3 SSE-C key derivation.
	// Each org gets: HMAC-SHA256(masterKey, orgSlug)
	// Each user gets: HMAC-SHA256(masterKey, orgSlug:userId)
	// If empty, encryption is disabled (dev mode).
	PrincipalEncryptionKey string

	// Deprecated: use PrincipalEncryptionKey.
	OrgEncryptionKey string

	// OrgStorageEndpoint is the S3-compatible storage endpoint for per-org
	// object storage (e.g., "s3.hanzo.space" or "s3.hanzo.ai").
	// Each org and user gets isolated prefixes with SSE-C encryption.
	// If empty, no per-org S3 storage is provisioned.
	OrgStorageEndpoint string

	// OrgStorageBucket is the root S3 bucket name (default: "orgs").
	OrgStorageBucket string

	// DefaultTemplates defines collection schemas cloned per org on creation.
	// If nil, no default org collections are created.
	DefaultTemplates []CollectionTemplate
}

PlatformConfig defines the configuration for the platform plugin.

type PoolStats added in v0.39.1

type PoolStats = dbx.PoolStats

type ScreeningResult

type ScreeningResult struct {
	RiskLevel string `json:"risk_level"` // low, medium, high, critical
	Matches   int    `json:"matches"`
	Cleared   bool   `json:"cleared"`
}

ScreeningResult from AML/sanctions screening.

Jump to

Keyboard shortcuts

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