mintauth

package
v1.786.220 Latest Latest
Warning

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

Go to latest
Published: Jul 12, 2026 License: Apache-2.0, MIT Imports: 2 Imported by: 0

Documentation

Overview

Package mintauth is the ONE structural money-mint invariant for the commerce ledger: a write that MINTS spendable balance (credits the gateway-honored IAM-user wallet without a funded source) is refused unless its persistence context is authorized to mint.

The invariant lives at the datastore write sink (datastore.Datastore.Put calls Enforce), NOT sprinkled across HTTP route gates. That is deliberate — every prior round of the money audit found ANOTHER route that reached a mint sink (billing/deposit, /zap billing.deposit, /allotment/grant, and then /v1/transaction). Gating routes is whack-a-mole; gating the SINK is closed form. No handler — present or future, on any route, in any package — can mint spendable balance without passing through an authorization, because the ledger layer itself refuses the write.

Two orthogonal context markers compose the invariant:

  • Gate (WithGate/Gated): set ONCE at the HTTP→datastore boundary (Organization.Namespaced, for every inbound *gin.Context), because ANY inbound principal is potentially an untrusted org-level admin. A context that never crosses that boundary — a background cron, a migration, a unit test building a plain context — is UNGATED and mints freely, so the fix is backward-compatible with every internal and test flow.

  • Grant (WithAuthorized/Authorized): set ONLY by a proven mint authority — MayMintMoney success (the internal service token or a platform global admin, via PlatformOnly / the ZAP mint gate / the transaction mint gate), a settled external payment (top-up charge, provider webhook settlement), or a server-fixed / subscription-clamped grant (welcome credit, monthly allotment). This is the capability that satisfies the Gate.

Enforce refuses iff the write mints (Guarded.MintRequiresAuthorization) AND the context is Gated AND NOT Authorized. Fail-closed.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotAuthorized = errors.New(
	"commerce: minting spendable balance requires mint authorization " +
		"(internal service token, platform SuperAdmin, settled payment, or server-fixed grant)")

ErrNotAuthorized is returned by Enforce when a spendable-balance mint is attempted through a mint-gated context that carries no mint authorization. It is a fail-closed refusal at the ledger layer, independent of any route gate.

Functions

func Authorized

func Authorized(ctx context.Context) bool

Authorized reports whether ctx carries mint authorization.

func Enforce

func Enforce(ctx context.Context, val interface{}) error

Enforce is THE money-mint invariant, called at the datastore write sink for every entity Put. It refuses a spendable-balance mint when the context is mint-gated (an inbound HTTP principal) and not authorized. It is a no-op for non-ledger entities, for non-mint writes (withdraws, holds, reads), and for ungated contexts (crons, migrations, tests) — so it closes the mint hole without touching any legitimate internal flow.

func Gated

func Gated(ctx context.Context) bool

Gated reports whether ctx crossed the HTTP boundary and is therefore subject to mint enforcement. An ungated context (background job, migration, test) is not enforced.

func Require

func Require(ctx context.Context) error

Require is THE mint-authority policy in one place: it refuses (ErrNotAuthorized) exactly when the context is mint-gated (an inbound HTTP principal) and NOT authorized. An ungated context (background cron, migration, unit test) or an authorized one passes. Both the ledger write sink (Enforce, below) and the chain-backed mint service (treasury.Mint) call it, so "who may mint" is defined once and cannot drift between the two enforcement points.

func WithAuthorized

func WithAuthorized(ctx context.Context) context.Context

WithAuthorized marks ctx as authorized to mint spendable balance. Idempotent. Set ONLY after establishing a proven mint authority (see package doc). This is the ONE way an HTTP request grants itself the capability the Gate demands.

func WithGate

func WithGate(ctx context.Context) context.Context

WithGate marks ctx as mint-gated: a spendable-balance mint flowing through it MUST also be authorized (WithAuthorized) or the ledger sink refuses the write. Idempotent. Set at the HTTP→datastore boundary for every inbound request.

Types

type Guarded

type Guarded interface {
	// MintRequiresAuthorization reports whether persisting this entity mints
	// spendable balance and therefore demands an authorized (or ungated) context.
	MintRequiresAuthorization() bool
}

Guarded is implemented by ledger entities that can MINT spendable balance. The datastore write sink asks the entity whether THIS instance is a spendable mint (its money-semantics live with the entity, e.g. models/transaction), and only then requires authorization. Non-ledger entities do not implement it and are never enforced.

Jump to

Keyboard shortcuts

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