Skip to main content

pkg/sdk/iface

The consumer-facing interfaces. Cross-module imports go only through this package — never into another module's services/ or repository/ directories.

Implemented by the core

A representative slice, not the full list — read the package for the rest.

InterfaceProvided byConsumed by
UserProvideruserauth, and every module that needs a user record
OperatorUserProvider / ClientUserProviderusertier-specific lookups
SessionTerminatoruserany module that must revoke a principal's sessions
NotificationSendernotificationauth (verification, password reset)
CategoryConfiguredCheckernotificationauth pre-flight guards — optional; IsConfiguredForCategory falls back to IsConfigured
TenantProvidertenantauthz, auth (JWT membership embedding), middleware
AccessProvidertenantmiddleware (RequireCapability)
AuthzProviderauthzmiddleware (permission checks)
JWTProvider / TenantScopedTokenProviderauththe dev-token endpoint, any custom auth integration
PasswordHasher / AdminAuthInviterauthuser (admin-direct Tier-2 flows)
ServiceAccountListerauthuser
AuditSinkcomplianceevery module performing a security-sensitive action
PIIProduceruser, auth, tenant, authz, notificationcompliance (the GDPR DSR pipeline)
KMSProvidercomplianceper-tenant envelope encryption and crypto-shred
ObjectStore / ObjectStoreProviderthe platform's blob provideruser (avatars), and any module storing uploads

AuditSinkSetter and KMSProviderSetter are the setter seams on core services: nil by default, so a fork can wire its own audit or key-management implementation the way the core compliance module does.

KMSProvider.CreateKey is idempotent under concurrency, not just for sequential callers: two calls racing to create a key for the same tenantUUID must both return the single winning keyID, never mint two DEKs for one tenant. The in-tree compliance implementation backs this with the collection's unique tenantUuid index plus a duplicate-key reread; any other implementation of KMSProvider (a remote HTTP-backed client, say) must uphold the same guarantee, since a resumable operation (like tenant provisioning) may call CreateKey more than once for the same tenant.

Reserved for a fork's addons

ADR-0006 collapsed the base to core-only, but kept the interfaces the removed verticals used. Nothing in the base implements these — they are the shape a fork's addon satisfies so it plugs into the same seam:

PDFProvider · GraphProvider · AIModelProvider · RAGQueryProvider · PaymentProvider · SubscriptionReconciler · SelfServiceCheckoutPlanner · BillingTenantProvider · ClientSelfDeletionGate

Why the indirection

Any implementation — in-process, or a remote HTTP-backed client a fork wires in — satisfies the same interface, so consumer code never changes. It is also what keeps the dependency graph honest: a module declares what it needs, and the registry resolves who provides it.