Documentation
¶
Overview ¶
Package capability contains shared capability storage.
Index ¶
- Constants
- Variables
- func AdmissionLockSQL(namespace, viewerSQL string) string
- func AdmitHeadersInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, headers []Header, limits Limits) error
- func BindHeadersInTx(ctx context.Context, tx *sql.Tx, headers []Header) error
- func ClaimHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, purpose string, ...) (bool, error)
- func ConsumeHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, nowMillis int64) (bool, error)
- func DropHeadersInTx(ctx context.Context, tx *sql.Tx, scope HeaderScope, digests []string) error
- func LockHeaderScopeInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, scope HeaderScope) error
- func PruneExpired(ctx context.Context, db *sql.DB, now time.Time) (int64, error)
- func PruneHeadersInTx(ctx context.Context, tx *sql.Tx, namespace string, cutoffMillis int64, ...) (int64, error)
- func PruneScopedHeadersInTx(ctx context.Context, tx *sql.Tx, namespace string, viewerID int64, ...) (int64, error)
- func RenewHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, nowMillis int64) (bool, error)
- type CapacityError
- type Header
- type HeaderScope
- type Limits
- type Ticket
- type TicketEntry
- type TicketScope
- type Tickets
Constants ¶
const HeaderBatchMax = 40
HeaderBatchMax bounds work per call; it is not a storage quota or a fence against old writers. Adapters must enforce their own durable admission limits.
const HeaderShardCount int64 = 64
HeaderShardCount is the stable shard modulus used by domain adapters when coordinating admission. Changing it requires a migration and writer fence.
const RetirementOwnerClaim = "retirement-owner"
RetirementOwnerClaim reserves a header while a typed domain owner still protects an acquired resource. Domains create it atomically with header issuance and their typed owner, and remove it atomically with that owner. It must not be attached after an unprotected header becomes visible. Expiry maintenance skips it; expiry alone must never authorize retirement. Admission continues to charge the header.
Variables ¶
var ErrInvalidHeader = errors.New("capability: invalid header or scope")
Functions ¶
func AdmissionLockSQL ¶
AdmissionLockSQL returns a PostgreSQL advisory-lock expression matching the Go admission lock. Inputs must be trusted migration constants, never request text. Keeping both forms here prevents domain triggers taking a different lock.
func AdmitHeadersInTx ¶
func AdmitHeadersInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, headers []Header, limits Limits) error
AdmitHeadersInTx reserves bounded storage in the domain transaction. A batch has one namespace/viewer/surface, but may contain different devices. The caller authorizes and inserts its typed records in this same transaction and must roll back on any error. Existing rows (including pre-cutover headers) count toward admission. This does not fence direct SQL or old binaries.
func BindHeadersInTx ¶
BindHeadersInTx inserts headers on the caller's transaction. The caller owns scope authorization, per-domain quota, timestamp selection and atomic domain insertion; tx must come from the same database as the domain operation. Duplicate namespace/digest fails and must cause the caller to roll back.
func ClaimHeaderInTx ¶
func ClaimHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, purpose string, nowMillis int64) (bool, error)
ClaimHeaderInTx atomically claims one purpose on a reusable handle. A false result is an already-claimed purpose; absent, foreign or expired handles fail closed. Typed domain authorization must be checked in this transaction.
func ConsumeHeaderInTx ¶
func ConsumeHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, nowMillis int64) (bool, error)
ConsumeHeaderInTx removes exactly one live, scoped reservation. The domain must revalidate authorization and consume its typed payload in this same transaction. A false result never authorizes a fallback. Reusable handles should be revoked with this operation only when their domain lifetime ends.
func DropHeadersInTx ¶
DropHeadersInTx removes only exact scope matches. Unknown or foreign headers are left untouched. Callers must authorize their corresponding domain deletion in the same transaction and not infer authorization from this operation.
func LockHeaderScopeInTx ¶
LockHeaderScopeInTx acquires the admission shard lock before a domain touches typed rows. Maintenance and issuance use the same header-first order.
func PruneExpired ¶
PruneExpired performs bounded maintenance independently of issuance. Only expired rows are deleted; the outer predicate protects concurrent renewal. Failure leaves the remaining work for the next pass.
func PruneHeadersInTx ¶
func PruneHeadersInTx(ctx context.Context, tx *sql.Tx, namespace string, cutoffMillis int64, limit int) (int64, error)
PruneHeadersInTx deletes at most limit expired headers in one namespace. cutoffMillis must come from the same trusted clock used for domain expiry; callers must account for any authority lifetime extending beyond the header. This only removes mirror bookkeeping; domain retention and active-session retirement remain the caller's responsibility. No capability, including one considered live by its domain, may rely on this header surviving beyond the supplied cutoff. The caller commits or rolls back.
func PruneScopedHeadersInTx ¶
func PruneScopedHeadersInTx(ctx context.Context, tx *sql.Tx, namespace string, viewerID int64, surface string, cutoffMillis int64, limit int) (int64, error)
PruneScopedHeadersInTx deletes expired headers for one viewer and surface. It takes no advisory lock; callers serialize it with their domain writers. The trusted cutoff must use the domain expiry clock. No domain rows are deleted.
func RenewHeaderInTx ¶
func RenewHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, nowMillis int64) (bool, error)
RenewHeaderInTx extends one live, exact-scoped header under the admission lock without adding a reservation. Existing active lifetimes remain renewable when migrated state is over quota; fresh admission still fails closed. The domain must authorize renewal and update its typed payload in the same tx.
Types ¶
type CapacityError ¶
type CapacityError struct{ Scope string }
func (*CapacityError) Error ¶
func (e *CapacityError) Error() string
type Header ¶
type Header struct {
HeaderScope
Digest string
ExpiresMillis int64
}
Header is non-secret bookkeeping; Digest is the domain's existing token hash. ExpiresMillis is an absolute Unix timestamp in milliseconds. Domain payloads and authorization remain in the domain's own table.
type HeaderScope ¶
HeaderScope binds a header to its owning domain and authenticated subject. The calling adapter must authorize this scope against its domain authority.
type Limits ¶
type Limits struct{ PerScope, PerShard int }
Limits are fixed by the issuing domain, never by a request. All writers for a namespace must use the same limits. Expired rows remain charged until the domain safely retires them; admission never evicts a live resource.
type TicketEntry ¶
type TicketEntry struct{ Digest, Purpose string }
type TicketScope ¶
type Tickets ¶
type Tickets struct {
// contains filtered or unexported fields
}
func NewTicketsWithClock ¶
NewTicketsWithClock preserves a service-owned trusted clock contract. The clock is injected by the host, never by a front-end request.
func (*Tickets) Consume ¶
Consume uses a guarded DELETE as the linearization point; selection alone never authorizes consumption.
func (*Tickets) IssueBatch ¶
func (s *Tickets) IssueBatch(ctx context.Context, scope TicketScope, entries []TicketEntry) (int64, error)
IssueBatch authorizes and admits typed tickets atomically.