Every multi-tenant product ends up writing the same layer before it writes anything that is actually its own: who belongs to which tenant, who may do what, who changed what, which settings and flags apply to whom, where uploads go, how people are told things, and how it all gets backed up. In Laravel there is a well-worn package for most of it; in Go it usually gets written from scratch, product by product.
So we have released eleven of those pieces as separate Go modules, under the MIT license, each installed on its own.
go get github.com/byteminus/go-tenancy
Every module needs Go 1.26 or later. The ones that store data do it in PostgreSQL through pgx v5. All are tagged v0.2.0: usable today, and — as a v0 Go module — free to change their API before 1.0, so pin the version.
Who belongs, and who may do what
go-tenancy is the foundation: tenants with slugs and custom domains, memberships with roles and a last-owner guard that holds under concurrency, and single-use invitations whose tokens are stored only as hashes. HTTP middleware resolves the tenant of each request, and PostgreSQL row-level security keeps tenants apart inside shared tables — integrity lives in the database, not in every query remembering a WHERE clause.
go-permission answers the next question with one call:
ok, err := authz.Can(ctx, alice, "posts.publish", "team-1")
Permissions group into roles, roles are assigned per tenant or team, and wildcards like posts.* work. Rules that depend on the resource itself — "authors may edit their own posts" — are typed policy functions that can call the role checks. Effective permissions are cached, and the cache is invalidated across every instance through PostgreSQL LISTEN/NOTIFY.
go-approvals runs multi-step workflows: an expense approved by a manager and then by finance, an access request that expires if nobody answers. Steps can need any, all or a quorum of approvers; separation of duties is on by default; requests snapshot their steps so a deploy never breaks work in flight; and your hooks run in the same transaction as each transition.
What happened, and what applies
go-activitylog records every create, update and delete in the same database transaction as the change, with the actor, tenant and request details you put in the context once, and exactly which fields changed. Secrets are marked as changed without their values, at any depth.
go-settings gives you typed settings: declare a Key[T] with a default and a validation rule, override it globally, per tenant or per user, and the most specific value wins. Secrets are encrypted at rest with rotating AES-256-GCM keys.
go-featureflags evaluates flags against an immutable in-memory snapshot, so a request never waits on the database: kill switches, user and tenant targeting, attribute rules, sticky percentage rollouts and weighted variants. Snapshots refresh by polling or are pushed from PostgreSQL.
go-translatable keeps translations in your own tables as jsonb, with fallback chains (pt-BR → pt → en), the request locale from the URL, a cookie or Accept-Language, and the same fallback applied inside SQL for sorting and filtering. For a product that ships in Bangla and English, that is most of the job.
Files, messages, backups and the back office
go-medialibrary attaches uploads to your models — avatars, product photos, invoice PDFs. It checks the real content type, stores files on local disk or any S3-compatible bucket (AWS S3, Cloudflare R2, MinIO), records them in PostgreSQL, and makes image conversions inline or through your own job queue. Writes are ordered so a record never points at a missing file.
go-notifications sends email, SMS, push and in-app notifications through one dispatcher. A notification is a Go type that says how it renders on each channel; the dispatcher respects opt-outs and tells you what happened per recipient and channel, including which push tokens to delete. SMTP, Twilio and Firebase Cloud Messaging are built in.
go-backup dumps PostgreSQL with pg_dump, archives upload directories, encrypts with age, ships to a local volume and S3-compatible storage at once, verifies every checksum, prunes grandfather-father-son, and restores. A backup counts as complete only once every byte and its manifest are stored.
go-admin turns resource definitions written in Go into a server-rendered admin panel: lists with search, filters and bulk actions, detail pages, validated forms and a dashboard. It is a plain http.Handler with no code generation, it never authenticates users itself, it asks your authoriser before every page and write, and it ships a strict Content-Security-Policy.
Using them
Each repository's README opens with a quick start, and the API documentation is on pkg.go.dev — go-tenancy's, for example. The open-source page lists all eleven with their install lines.
Issues and pull requests are welcome on each repository. Security reports go to contact@byteminus.com, not a public issue.