guard

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package guard is authorization: the question "may this caller do this?", asked once per route, before the handler runs.

A guard returns nil to allow and an *errs.Error to refuse, and the refusal carries its own status — so a guard that needs to answer 402 rather than 403 just says so.

Why a guard and not an `if` at the top of the handler: a route is declared in one line, and the guards on it are part of that line. A reviewer reading the module's Register function can see what protects each route without opening six handlers, and a route added without protection is visibly different from its neighbours.

Index

Constants

This section is empty.

Variables

View Source
var Authenticated = Of("authenticated", func(c fiber.Ctx) error {
	if ctxkit.ActorOf(c.Context()).UserID.String() == "00000000-0000-0000-0000-000000000000" {
		return errs.Unauthorized("authentication required").WithCode("UNAUTHENTICATED")
	}
	return nil
})

Authenticated refuses a request that carries no actor.

It reads what the authentication middleware put on the context; it does not itself verify a token. Keeping the two apart means a test can establish an actor without minting a credential.

View Source
var Operator = Of("operator", func(c fiber.Ctx) error {
	if !ctxkit.TenantOf(c.Context()).Operator {

		return errs.Forbidden("not permitted").WithCode("OPERATOR_ONLY")
	}
	return nil
})

Operator allows only a platform super-admin.

View Source
var Tenanted = Of("tenanted", func(c fiber.Ctx) error {
	if ctxkit.TenantOf(c.Context()).Zero() {
		return errs.Unauthorized("no account context on this request").WithCode("NO_TENANT")
	}
	return nil
})

Tenanted refuses a request that is not scoped to an account.

Every tenant-owned read and write depends on this having run: a zero account id reaching a repository is the bug that returns another customer's rows.

Functions

func Use

func Use(guards ...Guard) fiber.Handler

Use returns a fiber handler that runs the guards in order and stops at the first refusal.

Order is yours to choose and it matters: put the cheap checks first. An authentication guard that reads a cached token should run before a quota guard that queries a database, so an unauthenticated flood costs a map lookup rather than a connection.

Types

type Func

type Func struct {
	Label string
	Check func(c fiber.Ctx) error
}

Func adapts a plain function to Guard.

func (Func) CanActivate

func (f Func) CanActivate(c fiber.Ctx) error

CanActivate implements Guard.

func (Func) Name

func (f Func) Name() string

Name implements Guard.

type Guard

type Guard interface {
	// Name identifies the guard in logs and in the route table.
	Name() string
	CanActivate(c fiber.Ctx) error
}

Guard decides whether a request may proceed.

Returning nil allows it. Returning an error refuses it, and the error's kind picks the status — use errs.Unauthorized for "who are you", errs.Forbidden for "not you", errs.PaymentRequired or errs.Exhausted where those fit.

func All

func All(name string, guards ...Guard) Guard

All passes only when every guard passes. It is the same as listing them, and exists so a set of guards can be named once and reused.

func Any

func Any(name string, guards ...Guard) Guard

Any passes when at least one guard passes, and reports the LAST refusal when none do.

Use it for "an owner or an admin may do this". Do not use it to paper over a guard that is failing for a reason you have not understood.

func HasRole

func HasRole(roles ...string) Guard

HasRole refuses a caller lacking any of the listed roles. A platform operator is NOT automatically allowed; say so explicitly with Any if that is what you mean.

func Of

func Of(name string, check func(c fiber.Ctx) error) Guard

Of builds a Guard from a name and a function.

Jump to

Keyboard shortcuts

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