authkit

package module
v0.149.0 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: MIT Imports: 16 Imported by: 0

README

AuthKit

Stop paying for shitty SaaS pay-per-user auth services. Firebase would charge you $4,415 for 1 million monthly-active users; you can self-host that for free inside of the web-server you already run. It's simpler to run auth inside of your Go webserver's binary, in process, on your own Postgres (v18) database.

First install authkit into your Go project:

go get github.com/open-rails/authkit

Next let's build a client:

package main

import (
	"context"
	"errors"
	"log"
	"net/http"
	"os"
	"slices"
	"strconv"
	"sync"

	"github.com/gin-gonic/gin"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgxpool"
	"github.com/open-rails/authkit"
	authkitgin "github.com/open-rails/authkit/adapters/gin"
	"github.com/open-rails/authkit/adapters/twilio"
	"github.com/open-rails/authkit/iam"
	"github.com/open-rails/authkit/verify"
)

func newAuth(ctx context.Context, db *pgxpool.Pool) (*authkit.Client, error) {
	cfg := authkit.Config{
		Schema: "profiles", // the Postgres schema AuthKit's tables go in
		// Configure JWTs; authkit issues these to users; users then send them back with requests to prove who they are!
		Token: authkit.TokenConfig{
			Issuer:          "https://myapp.com", // who issued this; that's you!
			IssuedAudiences: []string{"myapp"},   // who this JWT is intended for (doesn't have to be yourself, but usually is)
		},
		Keys: authkit.KeysConfig{
			Path: "/vault/auth", // where your signing keys are stored; a keys.json file
		},
		HTTP: &authkit.HTTPConfig{
			DirectPeerIP: true, // no proxy in front; otherwise set TrustedProxies
			// Rate limits live in memory; set Deps.Redis when you run more than one copy of your server.
		},
		Roles: rbac, // See below for our RBAC system
	}

	// 1. Create or upgrade AuthKit's tables. Safe to run on every boot.
	if err := authkit.Migrate(ctx, db, cfg, authkit.MigrateOptions{}); err != nil {
		return nil, err
	}

	// 2. Authkit needs to send verification and account recovery codes to emails and phone numbers.
	// Configure your messaging provider (Twilio) here.
	email, err := twilio.NewEmail(twilio.EmailConfig{
		APIKey:    os.Getenv("SENDGRID_API_KEY"),
		FromEmail: "hello@myapp.com",
		AppName:   "MyApp",
	})
	if err != nil {
		return nil, err
	}
	sms, err := twilio.NewSMS(twilio.SMSConfig{
		AccountSID:          os.Getenv("TWILIO_ACCOUNT_SID"),
		AuthToken:           os.Getenv("TWILIO_AUTH_TOKEN"),
		MessagingServiceSID: os.Getenv("TWILIO_MESSAGING_SERVICE_SID"),
		AppName:             "MyApp",
	})
	if err != nil {
		return nil, err
	}

	// 3. Build the auth engine.
	return authkit.New(ctx, cfg, authkit.Deps{
		Postgres: db,    // required: users, sessions and short-lived auth state
		Email:    email, // sends verification codes, login codes and password resets
		SMS:      sms,   // same, for phone numbers
		// Both also report when Twilio can't deliver, pausing that channel's sign-in until it can.
	})
}

Now let's make a shitty Reddit-clone. Oh wait; Reddit is already shit, I forgot lol.

First we need moderators; these are the unpaid neckbeards who enforce their arbitrary policies on users (plebians). Let's build that feature first:

var (
	// This is a mutable object that we'll attach all of our personas, permissions, and roles onto.
	rbac = authkit.NewRoles()

	// Persona's are types of permission groups. root (the whole site) exists by default.
	// we'll have permission group per reddit-channel, like /c/golang
	Channel = rbac.Persona("channel")

	// Our own custom permissions, in addition to the ones that authkit includes automatically.
	PostsEdit     = Channel.Permission("posts", "edit")
	PostsDelete   = Channel.Permission("posts", "delete")
	PostsApprove  = Channel.Permission("posts", "approve")
	ChannelEdit   = Channel.Permission("self", "edit")   // change the channel's own data: its name, description and rules
	ChannelDelete = Channel.Permission("self", "delete") // delete the channel ("self" is just our name for the channel itself)

	// Roles are bundles of permissions, scoped to a specific persona.
	// There is always a singleton persona; root
	Moderator = Channel.Role("moderator", Channel.Resource("posts").All()) // edit, delete and approve posts
	Admin     = rbac.Root.Role("admin",
		Channel.All(),         // everything in every channel, deleting it included
		rbac.Root.Users.All(), // read, ban, delete and manage user accounts
	)
)

Permissions have 3 parts: <persona>:<resource>:<action> and they support wildcards like channel:* too. However, we use enums in code rather than strings, for type-safety.

AuthKit gives every persona these permissions for free, so you never define them yourself:

Permission Lets you
channel:members:read see who holds which role in it
channel:members:manage give someone a role, change it, or take it away
channel:credentials:read, channel:credentials:manage list, or create and revoke, the channel's API keys and connected apps (only when APIKeys or RemoteApplications is on)

What a channel's data is, and who may change it, is define by your app. Authkit merely stores definitions for permissions and checks against those.

For the root persona (single-isntance only), they get these, defined by authkit:

Permission Lets you
root:users:read look through users and their sign-in history
root:users:ban ban and unban
root:users:delete delete an account, or restore it within its 30 days
root:users:manage edit someone else's account and sign them out everywhere
root:users:invite invite someone to create an account
root:members:read, root:members:manage see or hand out site-wide roles

The only built-in role for every permission group is just owner. When owner is assigned to a user, that user automatically gets <persona>:* permissions, which is full permission over the entire channel, or root (entire site).

Now let's seed a reddit admin using ADMIN_EMAIL:

func seed(ctx context.Context, auth *authkit.Client) (iam.User, error) {
	email := os.Getenv("ADMIN_EMAIL")
	if email == "" {
		return iam.User{}, errors.New("set ADMIN_EMAIL to the first admin's address")
	}
	// Creates the user if they don't exist, and grants them the admin role defined above
	return auth.EnsureUserRole(ctx, iam.RootGroup(), iam.UserByEmail(email), Admin)
}

// Our application-specific table
const channelsTable = `CREATE TABLE IF NOT EXISTS channels (
	name        text PRIMARY KEY,
	description text NOT NULL DEFAULT '',
	group_id    uuid NOT NULL UNIQUE
)`

var errChannelTaken = errors.New("that channel already exists")

// createChannel makes channel name, owned by ownerID: our row and AuthKit's permission group
// commit together or not at all.
func createChannel(ctx context.Context, db *pgxpool.Pool, auth *authkit.Client, name, ownerID string) error {
	return pgx.BeginFunc(ctx, db, func(tx pgx.Tx) error {
		owner := iam.UserSubject(ownerID)
		g, err := auth.CreateGroup(ctx, iam.NewGroup{Persona: Channel.Persona, Owner: &owner}, authkit.InTx(tx))
		if err != nil {
			return err
		}
		tag, err := tx.Exec(ctx, `INSERT INTO channels (name, group_id) VALUES ($1, $2) ON CONFLICT DO NOTHING`, name, g.ID)
		if err == nil && tag.RowsAffected() == 0 {
			err = errChannelTaken // rolling back takes the new group with it
		}
		return err
	})
}

Great. Now let's mount authkit's http handlers. This lets your end-users register and login.

func main() { log.Fatal(run(context.Background())) }

func run(ctx context.Context) error {
	db, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
	if err != nil {
		return err
	}
	defer db.Close()
	auth, err := newAuth(ctx, db)
	if err != nil {
		return err
	}
	defer auth.Close()
	if err := auth.Start(ctx); err != nil { // background maintenance jobs
		return err
	}
	if _, err := db.Exec(ctx, channelsTable); err != nil { // our own table
		return err
	}
	admin, err := seed(ctx, auth)
	if err != nil {
		return err
	}
	// Our admin opens /c/announcements; later boots find it already made.
	if err := createChannel(ctx, db, auth, "announcements", admin.ID); err != nil && !errors.Is(err, errChannelTaken) {
		return err
	}

	// Mount all gin routes
	r := gin.Default()
	if err := authkitgin.Mount(r, auth); err != nil {
		return err
	}
	mountForum(r, auth, db)

	return r.Run(":8080")
}

Mounting gives your users all of this: 65 routes under /api/v1, plus the public keys that let anyone verify AuthKit's tokens. Every request and response shape is in api/openapi.json, generated from the route catalog.

Signing up and signing in (every sign-in answers an AuthResult: signed in, or the one next step, such as a second factor)

Route What it does
POST /api/v1/register create an account
GET /api/v1/register/availability is this username free?
POST /api/v1/register/abandon cancel a sign-up that was never confirmed
POST /api/v1/verify/request send a code or link to prove an email or phone
POST /api/v1/verify/confirm prove it
POST /api/v1/password/login sign in with a password
POST /api/v1/password/reset/request send a "forgot password" link
POST /api/v1/password/reset/confirm set a new password with that link
POST /api/v1/passkeys/login/begin, /finish sign in with a passkey
POST /api/v1/2fa/challenge send the second-factor code to another of your factors
POST /api/v1/2fa/verify finish signing in with it
POST /api/v1/account/recovery/confirm undo deleting your own account, within 30 days
POST /api/v1/invitations/redeem accept an invitation

Sessions and tokens

Route What it does
POST /api/v1/token trade a refresh token for fresh tokens
DELETE /api/v1/logout sign out
POST /api/v1/me/step-up/password, /2fa prove it's really you before a sensitive change
POST /api/v1/me/step-up/2fa/send send that second-factor code
GET /api/v1/me/sessions your signed-in devices
DELETE /api/v1/me/sessions sign out everywhere else
DELETE /api/v1/me/sessions/{id} sign out one device
GET /api/v1/me/session-events your sign-in history
GET /.well-known/jwks.json public keys for checking AuthKit's tokens

Your own account

Route What it does
GET /api/v1/me who you are
PATCH /api/v1/me change your username, language or avatar
DELETE /api/v1/me delete your account (30 days to change your mind)
GET /api/v1/me/security whether you need to step up, and how
PUT /api/v1/me/password change your password
PUT /api/v1/me/email change your email (a code goes to the new one)
PUT /api/v1/me/phone change your phone number
DELETE /api/v1/me/phone remove it
DELETE /api/v1/me/providers/{provider} unlink a sign-in provider
GET /api/v1/me/groups the groups you hold a role in
GET /api/v1/me/permissions your role and permissions in one group (?group_id=)
GET /api/v1/users other people's public profiles (?ids= or ?username=)
GET /api/v1/capabilities what this server offers, for your UI

Two-factor, passkeys and device keys

Route What it does
GET /api/v1/me/2fa your second factors
POST /api/v1/me/2fa/setup start adding one: a code to your email or phone, or an authenticator app's secret
POST /api/v1/me/2fa/factors add it with that code
PATCH /api/v1/me/2fa/factors/{id} make it your default
DELETE /api/v1/me/2fa/factors/{id} remove it
DELETE /api/v1/me/2fa turn two-factor off
POST /api/v1/me/2fa/backup-codes new backup codes
GET /api/v1/me/sign-in-keys your passkeys and device keys
PATCH /api/v1/me/sign-in-keys/{id} rename one
DELETE /api/v1/me/sign-in-keys/{id} revoke one
POST /api/v1/me/passkeys/register/begin, /finish add a passkey

Groups (each channel's permission group; root is the site-wide group, where roles like root:admin live)

Route What it does
GET /api/v1/groups/{group_id}/members who holds which role (?expand=user adds their public profiles)
PUT /api/v1/groups/{group_id}/members/{kind}/{id} give someone a role, or change it ({kind} is users)
DELETE /api/v1/groups/{group_id}/members/{kind}/{id} take their role away
GET /api/v1/groups/{group_id}/roles the roles this group has
GET /api/v1/groups/{group_id}/invitations its invitations
POST /api/v1/groups/{group_id}/invitations invite someone with a link, or by email
DELETE /api/v1/groups/{group_id}/invitations/{id} revoke one

Site admins (need the matching root: permission, and a recent sign-in for changes)

Route What it does
GET /api/v1/admin/users look through users
GET /api/v1/admin/users/{user_id} one user
PATCH /api/v1/admin/users/{user_id} edit their account
PUT /api/v1/admin/users/{user_id}/ban ban them, until a time or for good
DELETE /api/v1/admin/users/{user_id}/ban lift the ban
DELETE /api/v1/admin/users/{user_id} delete an account
POST /api/v1/admin/users/{user_id}/restore restore it within 30 days
GET /api/v1/admin/users/{user_id}/sessions their signed-in devices
DELETE /api/v1/admin/users/{user_id}/sessions sign them out everywhere
GET /api/v1/admin/users/{user_id}/session-events their sign-in history

Switch on social logins (Google, Apple, GitHub, Discord) or API keys, and AuthKit mounts their routes too.

Now for our application-specific routes, we can check user permissions using middleware, to enforce that certain actions are moderator or admin-only:

func mountForum(r *gin.Engine, auth *authkit.Client, db *pgxpool.Pool) {
	f := &forum{auth: auth, db: db, posts: map[int]*Post{}}
	signedIn := authkitgin.Required(auth)

	r.GET("/c", f.listChannels)             // anyone can browse the channels
	r.POST("/c", signedIn, f.createChannel) // anyone signed in can start a channel

	ch := r.Group("/c/:channel", f.channel)   // every route below knows its channel
	ch.GET("", f.getChannel)                  // anyone can read a channel's page
	ch.GET("/posts", f.listPosts(true))       // anyone can read
	ch.POST("/posts", signedIn, f.createPost) // anyone signed in can post

	// moderator-specific routes:
	ch.GET("/queue", authkitgin.RequirePermission(auth, PostsApprove), f.listPosts(false))         // see pending posts
	ch.PATCH("/posts/:id", authkitgin.RequirePermission(auth, PostsEdit), f.editPost)              // edit a post
	ch.DELETE("/posts/:id", authkitgin.RequirePermission(auth, PostsDelete), f.deletePost)         // delete a post
	ch.POST("/posts/:id/approve", authkitgin.RequirePermission(auth, PostsApprove), f.approvePost) // approve / disapprove posts

	// admin-specific routes:
	ch.PUT("/moderators/:user_id", signedIn, f.appoint)                               // appoint a moderator
	ch.DELETE("/moderators/:user_id", signedIn, f.appoint)                            // remove a moderator
	ch.PATCH("", authkitgin.RequirePermission(auth, ChannelEdit), f.editChannel)      // edit channel settings
	ch.DELETE("", authkitgin.RequirePermission(auth, ChannelDelete), f.deleteChannel) // delete channel
}

The rest is ordinary app code (our channel and post handlers), not AuthKit. The whole program is one file: examples/reddit/main.go.

More: keys.json, RBAC, security

Documentation

Overview

Package authkit embeds AuthKit in a Go host: accounts, sessions, MFA, passkeys, permission groups, API keys and remote applications on the host's PostgreSQL.

Run Migrate, then New with a Config and Deps, then Start. New returns *Client, the one host type: its methods are the host operations; it authenticates requests (verify.Required(client), and the live gates verify.RequireSession, RequirePermission and Sensitive, which check the session); and with Config.HTTP set, Handler serves AuthKit's HTTP surface (Mount and Routes place it on a router).

Config is plain data; Deps holds everything that reaches outside the process (the pool, keys, providers, senders and the host's hooks, each a func). Both are defined once in internal/config and re-exported here under the same names, so their field docs are on that package's page and in gopls. auth*.go hold the operations, roles.go the permission model's builder and migrations.go Migrate. The implementation lives in internal/engine.

Shared identity and access types live in package iam; package verify verifies tokens without a database, and the adapters mount AuthKit on Gin or Fiber and send its messages through Twilio.

Index

Constants

View Source
const (
	FormerNamesFinite    = config.FormerNamesFinite
	FormerNamesForever   = config.FormerNamesForever
	FormerNamesImmediate = config.FormerNamesImmediate
)

Former-name reservation modes.

View Source
const (
	// APIKeys mounts the group API-key routes. It registers Credentials.
	APIKeys = config.APIKeys
	// RemoteApplications lets the persona's groups control remote
	// applications. It registers Credentials.
	RemoteApplications = config.RemoteApplications
)

Persona capabilities.

Variables

This section is empty.

Functions

func DefaultRateLimits added in v0.147.0

func DefaultRateLimits() map[string]RateLimit

DefaultRateLimits returns AuthKit's built-in per-endpoint limits, keyed by bucket name ("default" applies to unlisted buckets).

func Migrate added in v0.147.0

func Migrate(ctx context.Context, pool *pgxpool.Pool, cfg Config, opts MigrateOptions) error

Migrate applies AuthKit's PostgreSQL migrations to cfg.Schema through a privileged pool, and River's to cfg.River.Schema unless cfg.River.HostOwned. New and Start never run DDL, so runtime credentials can be restricted. Migrate creates the schemas; callers must not.

func ParseBootstrapManifestYAML added in v0.148.0

func ParseBootstrapManifestYAML(raw []byte) (iam.BootstrapManifest, error)

ParseBootstrapManifestYAML parses a bootstrap manifest without a Client or database, so a tool can check a file before connecting: it rejects empty manifests, structurally invalid entries and a root_role of another persona. An unknown key is logged as a warning, with its path (users[0].nickname), and ignored. Client.ApplyBootstrapManifest checks the rest against its Config: each root_role against Config.Roles, passwords against the policy, jwks_uri against the network policy.

Types

type APIKeysConfig added in v0.147.0

type APIKeysConfig = config.APIKeysConfig

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is AuthKit embedded in a host: the engine and, when Config.HTTP is set, its HTTP surface. Build it with New, then Start it. Operations are methods, grouped by domain in the auth_*.go files. It is the authority verify's middleware takes: verify.Required(client), verify.RequirePermission(client, perm).

Start, Close, RiverJobs, EmailAvailable, EmailHealth, SMSAvailable, SMSHealth, TwoFactorMethods, Handler, Routes, Mount and the request verification methods (auth_verify.go) are embedding-only: they wire the in-process deployment, and a Client of a remote deployment would not have them. Every other method is an operation a remote deployment could serve.

func New added in v0.147.0

func New(ctx context.Context, cfg Config, deps Deps) (_ *Client, err error)

New builds AuthKit from host configuration and dependencies. Run Migrate on the pool first. ctx bounds the boot-time database work.

func (*Client) ApplyBootstrapManifest

func (a *Client) ApplyBootstrapManifest(ctx context.Context, m iam.BootstrapManifest, o iam.BootstrapOptions, opts ...Option) (iam.BootstrapResult, error)

ApplyBootstrapManifest seeds accounts, their root roles and remote applications. See iam.BootstrapManifestUser for how existing accounts are found; nothing runs it implicitly.

func (*Client) AuthenticateRequest added in v0.147.0

func (a *Client) AuthenticateRequest(ctx context.Context, r *http.Request) (auth.Principal, error)

AuthenticateRequest verifies r and returns its helpers/auth principal, whose Can checks permissions live.

func (*Client) Ban added in v0.147.0

func (a *Client) Ban(ctx context.Context, actor iam.Actor, userID string, b iam.Ban, opts ...Option) error

Ban bans an account under ACCT(root:users:ban) and revokes its sessions, device keys, and the API keys and invitations it issued. Nobody bans themselves.

func (*Client) Can

func (a *Client) Can(ctx context.Context, actor iam.Actor, ref iam.GroupRef, perm iam.Perm) (bool, error)

Can reports whether actor holds perm in the group, checked live: a banned or deleted user, a revoked key, an unknown group or an actor bound to another group is false. An actor built from a token (verify.ActorFromClaims) is bound to its session: once that session or device key is revoked, Can is iam.ErrSessionRevoked. An unregistered perm is iam.ErrUnknownPermission, never a silent false.

func (*Client) CheckIssuerKeys added in v0.147.0

func (a *Client) CheckIssuerKeys(ctx context.Context) error

CheckIssuerKeys is a no-I/O health probe of the remote applications' JWKS keys: it fails naming every application whose last key fetch failed, with the age of its keys and whether they are past max-stale (its tokens then fail closed).

func (*Client) CheckRecentSignIn added in v0.147.0

func (a *Client) CheckRecentSignIn(ctx context.Context, cl verify.Claims) error

CheckRecentSignIn is the gate verify.Sensitive applies: CheckSession, and the user's own token, signed in within the last 15 minutes, with the second factor when the account has one; otherwise step_up_required (its metadata lists the account's step-up methods). A delegated token is forbidden.

func (*Client) CheckSession added in v0.147.0

func (a *Client) CheckSession(ctx context.Context, cl verify.Claims) error

CheckSession is the gate verify.RequireSession applies, for callers holding verified claims: nil when the session or device key cl was minted from is still active, else iam.ErrSessionRevoked. A user's token names one, and so does a delegated token minted from a sign-in (MintDelegatedAccessToken with a session-bound actor); a token minted without one is refused. Any other credential is forbidden.

func (*Client) CheckUsername added in v0.147.0

func (a *Client) CheckUsername(ctx context.Context, name string) error

CheckUsername reports whether a new account could take name: nil, the username policy's validation error, iam.ErrUsernameInUse, or the NameAdmission refusal. A name is in use while any account holds it, as its name or a live alias, including its own; the answer says nothing more about that account. Serve it to untrusted callers only rate-limited.

func (*Client) Close added in v0.147.0

func (a *Client) Close()

Close releases AuthKit-owned resources. Host-owned dependencies stay open.

func (*Client) CreateAPIKey added in v0.147.0

func (a *Client) CreateAPIKey(ctx context.Context, actor iam.Actor, ref iam.GroupRef, k iam.NewAPIKey, opts ...Option) (iam.APIKeyCreated, error)

CreateAPIKey issues a key holding k.Role in ref. The actor needs <persona>:credentials:manage and must cover the role; only a user or the system issues credentials (the system's keys have no creator). The secret is returned once.

func (*Client) CreateGroup added in v0.147.0

func (a *Client) CreateGroup(ctx context.Context, g iam.NewGroup, opts ...Option) (iam.Group, error)

CreateGroup creates a group of a declared persona. g.Owner, when set, must be a live account (not banned, deleted or reserved); it becomes the new group's owner. With g.ID it is idempotent: creating a live group of the same persona returns it unchanged, while a deleted group or one of another persona under that id is iam.ErrGroupConflict.

func (*Client) CreateInvitation added in v0.147.0

func (a *Client) CreateInvitation(ctx context.Context, actor iam.Actor, ref iam.GroupRef, n iam.NewInvitation, opts ...Option) (iam.InvitationCreated, error)

CreateInvitation creates an invite link (n.Email empty) that grants n.Role to the signed-in account redeeming it, or emails an invitation to n.Email. A link, and an email invitation carrying a role, need the group's <persona>:members:manage and coverage of the role; a plain email invitation (no role) is created in iam.RootGroup() and needs root:users:invite. Only a user or the system issues credentials. The code is returned once.

func (*Client) CreateUser

func (a *Client) CreateUser(ctx context.Context, u iam.NewUser, opts ...Option) (iam.User, error)

CreateUser creates a native account. Host operation: your code decides.

func (*Client) DeleteGroup added in v0.147.0

func (a *Client) DeleteGroup(ctx context.Context, ref iam.GroupRef, opts ...Option) error

DeleteGroup soft-deletes a group: it stops resolving and granting at once, while its rows stay until PurgeGroup. Deleting a deleted group is a no-op.

func (*Client) DeleteRemoteApplication

func (a *Client) DeleteRemoteApplication(ctx context.Context, actor iam.Actor, ref iam.GroupRef, id string, opts ...Option) error

DeleteRemoteApplication deletes the application id that ref controls; an id unknown in ref is iam.ErrRemoteApplicationNotFound. Only the system deletes a system-registered application.

func (*Client) DeleteUsers added in v0.147.0

func (a *Client) DeleteUsers(ctx context.Context, actor iam.Actor, ids []string, opts ...Option) ([]iam.OpResult, error)

DeleteUsers soft-deletes accounts under ACCT(root:users:delete), starting the 30-day recovery window; an account may delete itself. Only a self-deletion is undone by signing in; any other comes back through RestoreUsers. Results are per item; the error is a whole-call failure.

func (*Client) DeviceKeys added in v0.147.0

func (a *Client) DeviceKeys(ctx context.Context, userID string) ([]iam.DeviceKey, error)

DeviceKeys returns the account's device keys in enrollment order, revoked ones included. iam.ErrDeviceKeysDisabled without Config.DeviceKeys.Enabled.

func (*Client) EffectivePermissions added in v0.147.0

func (a *Client) EffectivePermissions(ctx context.Context, actor iam.Actor, refs []iam.GroupRef) (map[string][]iam.Perm, error)

EffectivePermissions returns actor's effective grant patterns per group id (globs verbatim, glob-match with iam.Perm.Matches). Groups granting nothing are absent. At most iam.MaxBatch groups.

func (*Client) EmailAvailable added in v0.149.0

func (a *Client) EmailAvailable() bool

EmailAvailable reports whether email flows are offered: Deps.Email is set and its latest health check, if any, passed.

func (*Client) EmailHealth added in v0.149.0

func (a *Client) EmailHealth() (checkedAt time.Time, err error)

EmailHealth is the latest Deps.Email.CheckHealth verdict and when it ran (Start runs it every Config.SenderHealthInterval); a zero time means no check has run.

func (*Client) EnsureUserRole added in v0.147.0

func (a *Client) EnsureUserRole(ctx context.Context, group iam.GroupRef, u iam.UserRef, role iam.Role, opts ...Option) (iam.User, error)

EnsureUserRole makes the account u names hold role in group, and is safe to call on every boot. With no account for the email or phone, it creates one without credentials and with the contact unverified: only a proof of that contact (a password reset or a passwordless sign-in) can ever sign in to it, and that proof verifies it. An existing account is used when u is its id, when the contact is verified, or when it already holds role, the group's owner role, or a role covering role (a re-run, including on the account an earlier call created). Any other account gets iam.ErrContactNotVerified, so a pre-registered account is never adopted. A username never finds one.

func (*Client) Group added in v0.147.0

func (a *Client) Group(ctx context.Context, ref iam.GroupRef) (iam.Group, error)

Group reads one group, a soft-deleted one included, with DeletedAt set. Absence is iam.ErrGroupNotFound.

func (*Client) GroupRoles added in v0.147.0

func (a *Client) GroupRoles(ctx context.Context, ref iam.GroupRef, subjects []iam.Subject) (map[iam.Subject]iam.Role, error)

GroupRoles returns the direct role of each subject holding one in the group (at most iam.MaxBatch subjects). Subjects without a role are absent.

func (*Client) Groups added in v0.147.0

func (a *Client) Groups(ctx context.Context, ids []string) (map[string]iam.Group, error)

Groups reads many groups by id in one query, soft-deleted ones included. Unknown ids are absent. At most iam.MaxBatch ids.

func (*Client) Handler added in v0.147.0

func (a *Client) Handler() http.Handler

Handler serves AuthKit's whole HTTP surface; nil when Config.HTTP is zero. Mount it at the host root: its paths already include HTTPConfig.BasePath.

func (a *Client) ImportSolanaLinks(ctx context.Context, rows []iam.ImportSolanaLink, opts ...Option) (iam.ImportSolanaLinksResult, error)

ImportSolanaLinks reserves legacy wallet addresses for their accounts without making them login methods; only a later Sign-In with Solana proof verifies one.

func (*Client) ImportUsers

func (a *Client) ImportUsers(ctx context.Context, rows []iam.ImportUser, o iam.ImportOptions, opts ...Option) (iam.ImportResult, error)

ImportUsers imports accounts in bulk (hundreds of thousands per call), in chunks that commit independently. Every row is reported: see iam.ImportRow and iam.ImportConflict. Invalid rows are rejected alone; a database error stops the import and the rows of committed chunks are still reported.

func (*Client) IssuerKeyStatuses added in v0.147.0

func (a *Client) IssuerKeyStatuses() []verify.IssuerKeyStatus

IssuerKeyStatuses reports the remote applications' JWKS key state and age.

func (*Client) KnownPermission added in v0.147.0

func (a *Client) KnownPermission(perm iam.Perm) bool

KnownPermission reports whether perm is registered in a persona catalog of Config.Roles, AuthKit's built-ins included.

func (*Client) LinkProvider

func (a *Client) LinkProvider(ctx context.Context, userID string, l iam.ProviderLink, opts ...Option) error

LinkProvider links an external identity to an account as a login method. Browser flows link through the provider login instead.

func (*Client) ListAPIKeys

func (a *Client) ListAPIKeys(ctx context.Context, ref iam.GroupRef, p iam.PageRequest) (iam.ListPage[iam.APIKey], error)

ListAPIKeys lists the group's keys, newest first, including revoked and expired ones.

func (*Client) ListGroupMembers

func (a *Client) ListGroupMembers(ctx context.Context, ref iam.GroupRef, q iam.MemberQuery) (iam.ListPage[iam.GroupMember], error)

ListGroupMembers lists the subjects holding a role in a group, a page at a time.

func (*Client) ListGroups added in v0.147.0

func (a *Client) ListGroups(ctx context.Context, q iam.GroupQuery) (iam.ListPage[iam.Group], error)

ListGroups lists the groups of a persona, oldest first, a page at a time.

func (*Client) ListInvitations added in v0.147.0

func (a *Client) ListInvitations(ctx context.Context, ref iam.GroupRef, p iam.PageRequest) (iam.ListPage[iam.Invitation], error)

ListInvitations lists the group's invitations, newest first, active or not (never their codes). Root's include the plain email invitations.

func (*Client) ListMemberships added in v0.147.0

func (a *Client) ListMemberships(ctx context.Context, s iam.Subject, p iam.PageRequest) (iam.ListPage[iam.Membership], error)

ListMemberships lists the live groups a subject holds a role in, a page at a time.

func (*Client) ListRemoteApplications

func (a *Client) ListRemoteApplications(ctx context.Context, ref iam.GroupRef, p iam.PageRequest) (iam.ListPage[iam.RemoteApplication], error)

ListRemoteApplications lists the applications ref controls, newest first.

func (*Client) ListSessionEvents added in v0.147.0

func (a *Client) ListSessionEvents(ctx context.Context, userID string, q iam.SessionEventQuery) (iam.ListPage[iam.SessionEvent], error)

ListSessionEvents pages the account's sign-in and session history, newest first: sign-ins, failed sign-ins, revocations and password changes.

func (*Client) ListUsers added in v0.147.0

func (a *Client) ListUsers(ctx context.Context, q iam.UserQuery) (iam.ListPage[iam.UserEntry], error)

ListUsers pages through the user directory. Each entry carries the account's root role and, with q.WithEntitlements, its entitlements; q.Total counts every match.

func (*Client) MintAccessToken added in v0.98.0

func (a *Client) MintAccessToken(ctx context.Context, userID string, o iam.AccessTokenOptions, opts ...Option) (iam.Token, error)

MintAccessToken mints an access token for a live account outside any login flow; reserved claims are dropped. Host operation: your code decides.

func (*Client) MintDelegatedAccessToken

func (a *Client) MintDelegatedAccessToken(ctx context.Context, actor iam.Actor, d iam.DelegatedAccess, opts ...Option) (iam.Token, error)

MintDelegatedAccessToken signs a delegated access token as this deployment. A user actor mints only for itself, and every AuthKit permission in d.Permissions must be held live by it on the root group (iam.ErrDelegationRefused otherwise). The system mints for any subject.

func (*Client) MintServiceJWT

func (a *Client) MintServiceJWT(ctx context.Context, s iam.ServiceJWT, opts ...Option) (iam.Token, iam.ServiceJWTClaims, error)

MintServiceJWT signs a first-party service JWT with this deployment's key. It grants nothing AuthKit enforces; the receiver authorizes it.

func (*Client) Mount added in v0.147.0

func (a *Client) Mount(mux *http.ServeMux) (err error)

Mount registers every route's pattern on mux (a GET pattern also serves HEAD), all served by Handler.

func (*Client) NewVerifier added in v0.147.0

func (a *Client) NewVerifier(audiences []string, opts ...verify.VerifierOption) (*Verifier, error)

NewVerifier builds a Verifier for a host resource server in this process: this deployment's API keys and tokens and its remote applications' tokens, for audiences. DPoP proofs are spent once in AuthKit's replay store and checked against verify.WithPublicURL (default: the issuer's origin).

func (*Client) PatchUserMetadata

func (a *Client) PatchUserMetadata(ctx context.Context, actor iam.Actor, userID string, patch map[string]any, opts ...Option) error

PatchUserMetadata applies patch to the account's metadata as an RFC 7396 JSON Merge Patch under ACCT(root:users:manage): objects merge recursively, a nil value deletes its key, and any other value (arrays included) replaces the one it names. {"prefs": {"theme": "dark", "beta": nil}} sets prefs.theme, deletes prefs.beta and keeps prefs' other keys.

func (*Client) Permission added in v0.147.0

func (a *Client) Permission(text string) (iam.Perm, error)

Permission resolves a concrete permission: iam.ErrUnknownPermission unless it is registered.

func (*Client) Persona added in v0.147.0

func (a *Client) Persona(name string) (iam.Persona, error)

Persona resolves a persona name: iam.ErrUnknownGroupPersona unless Config.Roles declares it (root always is).

func (*Client) PublicUsers added in v0.147.0

func (a *Client) PublicUsers(ctx context.Context, ids []string) (map[string]iam.PublicUser, error)

PublicUsers returns what other people may see of ids: deleted accounts are tombstones, unknown ids are absent.

func (*Client) PurgeGroup added in v0.147.0

func (a *Client) PurgeGroup(ctx context.Context, ref iam.GroupRef, opts ...Option) error

PurgeGroup permanently deletes a group, live or soft-deleted, with every role, API key, invitation and application in it. Purging an unknown group is a no-op.

func (*Client) PurgeUsers added in v0.147.0

func (a *Client) PurgeUsers(ctx context.Context, ids []string, opts ...Option) ([]iam.OpResult, error)

PurgeUsers ends the recovery window of accounts now; the rows go once the host deletion callbacks complete. Host operation: your code decides.

<schema>.users(id) is the one AuthKit column a host table may reference: a foreign key ON DELETE CASCADE (or SET NULL) keeps host rows for as long as the account row exists, through the recovery window, and removes them with it at purge. Every other AuthKit table is private.

func (*Client) RemoteApplication added in v0.147.0

func (a *Client) RemoteApplication(ctx context.Context, ref iam.AppRef) (iam.RemoteApplication, error)

RemoteApplication returns one application, disabled ones included (Enabled), with its role in its group and the permissions that role confers now; else iam.ErrRemoteApplicationNotFound.

func (*Client) RemoveGroupMember added in v0.147.0

func (a *Client) RemoveGroupMember(ctx context.Context, actor iam.Actor, ref iam.GroupRef, subject iam.Subject, opts ...Option) error

RemoveGroupMember takes subject's role in ref away; removing a non-member changes nothing. With IfRole, a subject holding another role keeps it.

func (*Client) ResetAccountMFA added in v0.147.0

func (a *Client) ResetAccountMFA(ctx context.Context, userID string, opts ...Option) error

ResetAccountMFA recovers an account that lost its second factors, such as a passkey-only account answering passkey_required. It deletes the account's passkeys, 2FA factors and backup codes, revokes its device keys and sessions, and notifies its address through the email sender. Roles stay: when one needs MFA, or 2FA is Required, the next sign-in enrolls a factor. Host operation: your code decides, so verify who is asking before calling it.

func (*Client) ResolveAPIKey

func (a *Client) ResolveAPIKey(ctx context.Context, token string) (iam.APIKeyPrincipal, error)

ResolveAPIKey authenticates a presented token: iam.ErrAPIKeyInvalid, iam.ErrAPIKeyRevoked (also when its creator is banned or deleted) or iam.ErrAPIKeyExpired. The verifier resolves API keys through it.

func (*Client) ResolveUsername added in v0.147.0

func (a *Client) ResolveUsername(ctx context.Context, name string) (iam.NameResolution, error)

ResolveUsername resolves a username, current or a live alias of a renamed account, to its account. An expired alias, a deleted account and a name kept for a purged account are iam.ErrUserNotFound.

func (*Client) RestoreUsers added in v0.147.0

func (a *Client) RestoreUsers(ctx context.Context, actor iam.Actor, ids []string, opts ...Option) ([]iam.OpResult, error)

RestoreUsers restores soft-deleted accounts within their recovery window under ACCT(root:users:delete).

func (*Client) RevokeAPIKey

func (a *Client) RevokeAPIKey(ctx context.Context, actor iam.Actor, ref iam.GroupRef, id string, opts ...Option) error

RevokeAPIKey revokes the group's key id; it needs the authority to issue the key's role. Revoking a revoked key is a no-op; an id unknown in the group is iam.ErrAPIKeyNotFound.

func (*Client) RevokeAccountSessions added in v0.147.0

func (a *Client) RevokeAccountSessions(ctx context.Context, actor iam.Actor, userID string, opts ...Option) (iam.AccountSessionRevocation, error)

RevokeAccountSessions revokes the account's refresh sessions on every account issuer and its device keys, under ACCT(root:users:manage); an account may revoke its own. Their access tokens are refused at once by every session check (permission checks, verify.Sensitive, account changes) and pass stateless verification until they expire.

func (*Client) RevokeInvitation added in v0.147.0

func (a *Client) RevokeInvitation(ctx context.Context, actor iam.Actor, ref iam.GroupRef, id string, opts ...Option) error

RevokeInvitation revokes the group's invitation id; it needs the authority to issue it. Revoking a revoked or redeemed invitation is a no-op; an id unknown in the group is iam.ErrInvitationNotFound.

func (*Client) RevokeSession added in v0.147.0

func (a *Client) RevokeSession(ctx context.Context, actor iam.Actor, userID, sessionID string, opts ...Option) error

RevokeSession revokes one refresh session under ACCT(root:users:manage); an account may revoke its own.

func (*Client) RiverJobs added in v0.147.0

func (a *Client) RiverJobs() riverhelpers.Contribution

RiverJobs contributes AuthKit's jobs to a host-owned River fleet (Config.River.HostOwned).

func (*Client) Role added in v0.147.0

func (a *Client) Role(text string) (iam.Role, error)

Role resolves role text `<persona>:<name>` (`channel:moderator`), the one text form of a role: a declared role or a persona's owner role, else iam.ErrRoleNotAssignable.

func (*Client) RolePermissions added in v0.148.0

func (a *Client) RolePermissions(role iam.Role) ([]iam.Perm, error)

RolePermissions returns role's grants in Config.Roles, includes flattened: permissions and patterns (`channel:*`), matched with iam.Perm.Matches. A role the catalog does not declare is iam.ErrRoleNotAssignable (iam.ErrUnknownGroupPersona for an undeclared persona).

func (*Client) Routes added in v0.147.0

func (a *Client) Routes() []iam.Route

Routes returns the mounted route catalog, with a HEAD entry per GET route; Route.Pattern is its net/http ServeMux pattern.

func (*Client) SMSAvailable

func (a *Client) SMSAvailable() bool

SMSAvailable is EmailAvailable for Deps.SMS and phone flows.

func (*Client) SMSHealth added in v0.147.0

func (a *Client) SMSHealth() (checkedAt time.Time, err error)

SMSHealth is EmailHealth for Deps.SMS.

func (*Client) Sessions added in v0.147.0

func (a *Client) Sessions(ctx context.Context, userID string) ([]iam.Session, error)

Sessions lists the account's live refresh sessions on this issuer.

func (*Client) SetGroupRole added in v0.147.0

func (a *Client) SetGroupRole(ctx context.Context, actor iam.Actor, ref iam.GroupRef, subject iam.Subject, role iam.Role, opts ...Option) (iam.GroupMember, error)

SetGroupRole makes subject hold role in ref, replacing the role it holds. Holding role already changes nothing.

func (*Client) Start added in v0.147.0

func (a *Client) Start(ctx context.Context) error

Start starts AuthKit's background work: River (account lifecycle, events, auth-state cleanup) and the senders' health checks. Call it once, before serving.

func (*Client) TwoFactorMethods added in v0.148.0

func (a *Client) TwoFactorMethods() []iam.TwoFactorMethod

TwoFactorMethods are the second factors a user can enroll now, as GET /capabilities lists them: enabled by Config.TwoFactor, with their dependency present (Deps.Email and Deps.SMS while healthy, the TOTP key). Empty when 2FA is disabled.

func (*Client) Unban added in v0.147.0

func (a *Client) Unban(ctx context.Context, actor iam.Actor, userID string, opts ...Option) error

Unban lifts a ban under ACCT(root:users:ban). Nobody lifts their own ban.

func (*Client) UpdateUser added in v0.147.0

func (a *Client) UpdateUser(ctx context.Context, actor iam.Actor, userID string, u iam.UserUpdate, opts ...Option) (iam.User, error)

UpdateUser changes an account under ACCT(root:users:manage). An account may change its own Username, AvatarURL and PreferredLanguage. Password, PasswordHash and the verified flags are system-only; setting a verified flag on an account with no proven contact first retires its pre-proof credentials. An email change never moves the account's email factor.

func (*Client) UpsertRemoteApplication

func (a *Client) UpsertRemoteApplication(ctx context.Context, actor iam.Actor, ref iam.GroupRef, app iam.RemoteApplication, opts ...Option) (iam.RemoteApplication, error)

UpsertRemoteApplication registers the issuer app.Issuer in the group ref, or updates it there. TrustRoot is the system's to set; other actors register at trust root user.

func (*Client) User added in v0.147.0

func (a *Client) User(ctx context.Context, ref iam.UserRef, opts ...Option) (iam.User, error)

User returns one account by iam.UserByID, UserByEmail, UserByPhone or UserByUsername. Soft-deleted accounts need IncludeDeleted(). A miss is iam.ErrUserNotFound. An address match proves nothing about who owns the account unless EmailVerified or PhoneVerified is set: never grant authority to an account found by an unverified address.

func (*Client) UserMetadata added in v0.147.0

func (a *Client) UserMetadata(ctx context.Context, userID string) (map[string]any, error)

UserMetadata returns the account's application-owned metadata. It is not a public profile: select public fields explicitly.

func (*Client) Users added in v0.147.0

func (a *Client) Users(ctx context.Context, ids []string) (map[string]iam.User, error)

Users returns the accounts among ids (at most iam.MaxBatch), deleted ones included; unknown ids are absent. It carries contact details: render other people with PublicUsers.

func (*Client) Verify added in v0.147.0

func (a *Client) Verify(ctx context.Context, token string) (verify.Claims, error)

Verify is VerifyRequest for a token detached from any request (a WebSocket message, a queue job); a sender-bound delegated token fails with verify.ErrSenderProofRequired.

func (*Client) VerifyRequest added in v0.147.0

func (a *Client) VerifyRequest(r *http.Request) (verify.Claims, error)

VerifyRequest authenticates r: one of this deployment's API keys, a token it issued, or a token one of its remote applications issued. Its own tokens are verified statelessly, so a token outlives its revoked session until it expires; CheckSession and the live gates (verify.RequireSession, RequirePermission, Sensitive) check it.

func (*Client) VerifyServiceJWT added in v0.147.0

func (a *Client) VerifyServiceJWT(ctx context.Context, token string, opts ...verify.ServiceJWTVerifyOption) (iam.ServiceJWTClaims, error)

VerifyServiceJWT verifies a service JWT this deployment (MintServiceJWT) or one of its remote applications issued. It grants nothing: the host intersects the requested permissions with its own grants.

type Config added in v0.147.0

type Config = config.Config

Config is the host configuration: plain data. Everything that reaches outside the process is in Deps.

type CredentialPerms added in v0.147.0

type CredentialPerms = config.CredentialPerms

The permission model's builder, defined in internal/config.

type DelegatedConfig added in v0.147.0

type DelegatedConfig = config.DelegatedConfig

type Deps added in v0.147.0

type Deps = config.Deps

Deps is everything AuthKit reaches outside the process through: the store, keys, identity providers, senders and the host's hooks.

type DeviceKeysConfig added in v0.147.0

type DeviceKeysConfig = config.DeviceKeysConfig

type EmailSender added in v0.149.0

type EmailSender = config.EmailSender

EmailSender delivers email and reports whether it can (adapters/twilio.NewEmail).

type FormerNamesConfig added in v0.147.0

type FormerNamesConfig = config.FormerNamesConfig

type FormerNamesMode added in v0.147.0

type FormerNamesMode = config.FormerNamesMode

type FrontendConfig added in v0.147.0

type FrontendConfig = config.FrontendConfig

type HTTPConfig added in v0.147.0

type HTTPConfig = config.HTTPConfig

type KeysConfig added in v0.147.0

type KeysConfig = config.KeysConfig

type LanguageConfig added in v0.147.0

type LanguageConfig = config.LanguageConfig

type MemberPerms added in v0.147.0

type MemberPerms = config.MemberPerms

The permission model's builder, defined in internal/config.

type MigrateOptions added in v0.147.0

type MigrateOptions = config.MigrateOptions

MigrateOptions configures Migrate beyond what Config declares.

type Option added in v0.147.0

type Option = ops.Option

Option adjusts one operation. Every mutation and host operation takes ...Option; an operation refuses an option it does not take, never ignoring it.

func IfRole added in v0.147.0

func IfRole(role iam.Role) Option

IfRole makes RemoveGroupMember remove the subject only while it holds role: a guard against a concurrent re-role.

func InTx added in v0.147.0

func InTx(tx pgx.Tx) Option

InTx runs the operation inside tx, the host's own transaction, so AuthKit's changes commit or roll back with the host's: a group and the app row that stores its ID, or neither. tx must be a READ COMMITTED transaction on the database of Deps.Postgres; AuthKit's schema needs no search_path entry. AuthKit works in a savepoint of tx: a refused operation rolls back to it and leaves tx usable. Its authority lock, the credential sweep and its event records are all part of tx, and the lock is held until tx ends, so commit promptly.

CreateGroup, DeleteGroup, PurgeGroup, SetGroupRole, RemoveGroupMember, EnsureUserRole, CreateUser, PatchUserMetadata, Unban, CreateAPIKey, RevokeAPIKey, CreateInvitation (a link), RevokeInvitation, UpsertRemoteApplication and DeleteRemoteApplication take it.

func IncludeDeleted added in v0.147.0

func IncludeDeleted() Option

IncludeDeleted makes User return a soft-deleted account too.

type PasskeyConfig added in v0.147.0

type PasskeyConfig = config.PasskeyConfig

type PasswordPolicy added in v0.147.0

type PasswordPolicy = config.PasswordPolicy

type PersonaDef added in v0.147.0

type PersonaDef = config.PersonaDef

The permission model's builder, defined in internal/config.

type PersonaOption added in v0.147.0

type PersonaOption = config.PersonaOption

The permission model's builder, defined in internal/config.

type RateLimit added in v0.147.0

type RateLimit = config.RateLimit

type RegistrationConfig added in v0.147.0

type RegistrationConfig = config.RegistrationConfig

type Resource added in v0.147.0

type Resource = config.Resource

The permission model's builder, defined in internal/config.

type RiverConfig added in v0.147.0

type RiverConfig = config.RiverConfig

type Roles added in v0.72.0

type Roles = config.Roles

Roles is the app's permission model: its personas, their permissions and their roles. Declare it once and pass it as Config.Roles.

func NewRoles added in v0.147.0

func NewRoles(opts ...PersonaOption) *Roles

NewRoles starts a permission model holding only root; opts switch on root's capabilities.

type RootDef added in v0.147.0

type RootDef = config.RootDef

The permission model's builder, defined in internal/config.

type SMSSender added in v0.149.0

type SMSSender = config.SMSSender

SMSSender delivers text messages and reports whether it can (adapters/twilio.NewSMS).

type TokenConfig added in v0.147.0

type TokenConfig = config.TokenConfig

type TwoFactorConfig added in v0.147.0

type TwoFactorConfig = config.TwoFactorConfig

type UserPerms added in v0.147.0

type UserPerms = config.UserPerms

The permission model's builder, defined in internal/config.

type UsernameConfig added in v0.147.0

type UsernameConfig = config.UsernameConfig

type Verifier added in v0.147.0

type Verifier struct {
	// contains filtered or unexported fields
}

Verifier is a Client's verifier for a host resource server's audiences (Client.NewVerifier), a verify.Authority like the Client: it reads API keys and remote applications from AuthKit's database, and its live gates check sessions and permissions through the Client. It applies no 2FA policy.

func (*Verifier) AuthenticateRequest added in v0.147.0

func (v *Verifier) AuthenticateRequest(ctx context.Context, r *http.Request) (auth.Principal, error)

AuthenticateRequest is Client.AuthenticateRequest for this Verifier.

func (*Verifier) Can added in v0.147.0

func (v *Verifier) Can(ctx context.Context, actor iam.Actor, ref iam.GroupRef, perm iam.Perm) (bool, error)

Can is Client.Can.

func (*Verifier) CheckIssuerKeys added in v0.147.0

func (v *Verifier) CheckIssuerKeys(ctx context.Context) error

CheckIssuerKeys is Client.CheckIssuerKeys for this Verifier.

func (*Verifier) CheckRecentSignIn added in v0.147.0

func (v *Verifier) CheckRecentSignIn(ctx context.Context, cl verify.Claims) error

CheckRecentSignIn is Client.CheckRecentSignIn.

func (*Verifier) CheckSession added in v0.147.0

func (v *Verifier) CheckSession(ctx context.Context, cl verify.Claims) error

CheckSession is Client.CheckSession.

func (*Verifier) IssuerKeyStatuses added in v0.147.0

func (v *Verifier) IssuerKeyStatuses() []verify.IssuerKeyStatus

IssuerKeyStatuses is Client.IssuerKeyStatuses for this Verifier.

func (*Verifier) KnownPermission added in v0.147.0

func (v *Verifier) KnownPermission(perm iam.Perm) bool

KnownPermission is Client.KnownPermission.

func (*Verifier) Verify added in v0.147.0

func (v *Verifier) Verify(ctx context.Context, token string) (verify.Claims, error)

Verify is VerifyRequest for a token detached from any request.

func (*Verifier) VerifyRequest added in v0.147.0

func (v *Verifier) VerifyRequest(r *http.Request) (verify.Claims, error)

VerifyRequest authenticates r (Client.VerifyRequest, for this Verifier's audiences).

func (*Verifier) VerifyServiceJWT added in v0.147.0

func (v *Verifier) VerifyServiceJWT(ctx context.Context, token string, opts ...verify.ServiceJWTVerifyOption) (iam.ServiceJWTClaims, error)

VerifyServiceJWT is Client.VerifyServiceJWT for this Verifier's audiences.

Directories

Path Synopsis
adapters
fiber
Package authkitfiber bridges AuthKit's net/http middleware to Fiber v3.
Package authkitfiber bridges AuthKit's net/http middleware to Fiber v3.
gin
Package authkitgin bridges AuthKit's net/http middleware to Gin.
Package authkitgin bridges AuthKit's net/http middleware to Gin.
twilio
Package twilio delivers AuthKit's emails through Twilio SendGrid and its text messages through Twilio Messaging.
Package twilio delivers AuthKit's emails through Twilio SendGrid and its text messages through Twilio Messaging.
riverjobs module
Package authtest runs AuthKit in a host's Go tests: a real Client on a scratch PostgreSQL schema, an Outbox that captures every email and SMS, and helpers for the usual setup (a verified user, a signed-in session, a role, an authenticator app, a device key, a replica, a stale session).
Package authtest runs AuthKit in a host's Go tests: a real Client on a scratch PostgreSQL schema, an Outbox that captures every email and SMS, and helpers for the usual setup (a verified user, a signed-in session, a role, an authenticator app, a device key, a replica, a stale session).
cmd
authkit-migrate command
Command authkit-migrate is AuthKit's repository-owned migration runner.
Command authkit-migrate is AuthKit's repository-owned migration runner.
Package devicekey is the client side of AuthKit's device-key protocol, for CLIs and machines.
Package devicekey is the client side of AuthKit's device-key protocol, for CLIs and machines.
examples
reddit command
Command reddit is the example from the README: a tiny Reddit-like forum where channels live in the app and AuthKit keeps who may do what in each of them.
Command reddit is the example from the README: a tiny Reddit-like forum where channels live in the app and AuthKit keeps who may do what in each of them.
Package iam holds AuthKit's shared identity and access vocabulary: users, subjects, groups, roles and permissions, actors, remote applications, credential parsing, naming policy, and the one error catalog with its wire envelope.
Package iam holds AuthKit's shared identity and access vocabulary: users, subjects, groups, roles and permissions, actors, remote applications, credential parsing, naming policy, and the one error catalog with its wire envelope.
internal
apikey
Package apikey is the API-key token format, shared by the engine (mint and resolve) and verify (routing a bearer token to the API-key path).
Package apikey is the API-key token format, shared by the engine (mint and resolve) and verify (routing a bearer token to the API-key path).
apitest
Package apitest holds black-box tests of the Client and its HTTP API, one file per feature.
Package apitest holds black-box tests of the Client and its HTTP API, one file per feature.
builtwith
Package builtwith lets authtest read what a Client was built with, which the Client does not publish: a replica or a stale session of a Client the host built itself.
Package builtwith lets authtest read what a Client was built with, which the Client does not publish: a replica or a stale session of a Client the host built itself.
cmd/contract command
Command contract generates AuthKit's HTTP contract from the route catalog (httpapi.Catalog) and the error catalog: api/openapi.json, and auth-ui's generated wire types, route table and error codes and messages.
Command contract generates AuthKit's HTTP contract from the route catalog (httpapi.Catalog) and the error catalog: api/openapi.json, and auth-ui's generated wire types, route table and error codes and messages.
config
Package config is the one definition of AuthKit's host configuration: Config (plain data), Deps (everything that reaches outside the process), the Roles builder and MigrateOptions.
Package config is the one definition of AuthKit's host configuration: Config (plain data), Deps (everything that reaches outside the process), the Roles builder and MigrateOptions.
cursor
Package cursor is AuthKit's one page-cursor codec: a keyset position as opaque base64url JSON.
Package cursor is AuthKit's one page-cursor codec: a keyset position as opaque base64url JSON.
db
dpop
Package dpop verifies the ES256/P-256 profile of RFC 9449 sender proofs.
Package dpop verifies the ES256/P-256 profile of RFC 9449 sender proofs.
enrollment
Package enrollment marks requests to AuthKit's 2FA-enrollment routes, the only ones a 2FA-enrollment-only token reaches and the only ones a user a Required 2FA policy has yet to enroll may use.
Package enrollment marks requests to AuthKit's 2FA-enrollment routes, the only ones a 2FA-enrollment-only token reaches and the only ones a user a Required 2FA policy has yet to enroll may use.
errmodel
Package errmodel is AuthKit's one error model: the catalog fixing every wire code's HTTP status and message, the concrete error value, and its constructors.
Package errmodel is AuthKit's one error model: the catalog fixing every wire code's HTTP status and message, the concrete error value, and its constructors.
ident
Package ident builds iam identifiers from strings AuthKit already trusts: stored rows, verified token claims, its compiled role schema and its own tests.
Package ident builds iam identifiers from strings AuthKit already trusts: stored rows, verified token claims, its compiled role schema and its own tests.
jose
Package jose is AuthKit's JWT mechanics: signing with a keys.Signer, signature verification, the token types, claim readers, sender-binding (cnf) claims and JWKS serving.
Package jose is AuthKit's JWT mechanics: signing with a keys.Signer, signature verification, the token types, claim readers, sender-binding (cnf) claims and JWKS serving.
jwks
Package jwks is the issuer key cache behind every AuthKit verifier: it fetches an issuer's JWKS, serves it stale-while-revalidate up to a max staleness, refetches on key rotation, and reports health.
Package jwks is the issuer key cache behind every AuthKit verifier: it fetches an issuer's JWKS, serves it stale-while-revalidate up to a max staleness, refetches on key rotation, and reports health.
keypolicy
Package keypolicy is AuthKit's one public-key policy, applied to every signing and verification key: RSA of 2048-8192 bits with a sane exponent, P-256/384/521, or Ed25519.
Package keypolicy is AuthKit's one public-key policy, applied to every signing and verification key: RSA of 2048-8192 bits with a sane exponent, P-256/384/521, or Ed25519.
lang
Package lang is AuthKit's one language normalizer and the request language the HTTP layer hands the engine.
Package lang is AuthKit's one language normalizer and the request language the HTTP layer hands the engine.
migrations/postgres
Package postgres embeds AuthKit's private PostgreSQL schema migrations.
Package postgres embeds AuthKit's private PostgreSQL schema migrations.
migrations/retired
Package retired converts databases built by the migration chain AuthKit v0.125.0–v0.148.x shipped (0001–0015, kept verbatim in v0.148/) to the v1 baseline in place.
Package retired converts databases built by the migration chain AuthKit v0.125.0–v0.148.x shipped (0001–0015, kept verbatim in v0.148/) to the v1 baseline in place.
naming
Package naming applies the username rule of a normalized config.UsernameConfig: validation, derivation, renames and former names.
Package naming applies the username rule of a normalized config.UsernameConfig: validation, derivation, renames and former names.
netguard
Package netguard is the single outbound-network policy for AuthKit: the private/reserved address list, the resolve-then-dial SSRF guard, and the timeout-bounded HTTP client every package uses for fetches it does not fully control (JWKS, IdP endpoints).
Package netguard is the single outbound-network policy for AuthKit: the private/reserved address list, the resolve-then-dial SSRF guard, and the timeout-bounded HTTP client every package uses for fetches it does not fully control (JWKS, IdP endpoints).
oidcstate
Package oidcstate holds the browser-flow state shared by the HTTP layer and the engine: the pending-login record and PKCE generation.
Package oidcstate holds the browser-flow state shared by the HTTP layer and the engine: the pending-login record and PKCE generation.
ops
Package ops declares AuthKit's operations once, with the signatures of the root Client's methods.
Package ops declares AuthKit's operations once, with the signatures of the root Client's methods.
passkeytest
Package passkeytest is a software WebAuthn authenticator for passkey integration tests: it answers real registration and assertion ceremonies with a P-256 key, so tests exercise the production ceremony code paths.
Package passkeytest is a software WebAuthn authenticator for passkey integration tests: it answers real registration and assertion ceremonies with a P-256 key, so tests exercise the production ceremony code paths.
password/internal/commongen command
Command commongen regenerates ../../common_passwords.txt.gz from pinned SecLists (MIT) lists: run `go generate ./password`.
Command commongen regenerates ../../common_passwords.txt.gz from pinned SecLists (MIT) lists: run `go generate ./password`.
ratelimit/memory
Package memorylimiter is the in-memory sliding-window rate limiter over ratelimit.Limit buckets.
Package memorylimiter is the in-memory sliding-window rate limiter over ratelimit.Limit buckets.
ratelimit/redis
Package redislimiter is the Redis-backed sliding-window rate limiter over ratelimit.Limit buckets.
Package redislimiter is the Redis-backed sliding-window rate limiter over ratelimit.Limit buckets.
rbac
Package rbac compiles the host's role configuration into the immutable schema the engine authorizes against: each persona's permission catalog, its roles, and the pure grant-resolution core.
Package rbac compiles the host's role configuration into the immutable schema the engine authorizes against: each persona's permission catalog, its roles, and the pure grant-resolution core.
secret
Package secret mints and compares one-time secrets over crypto/rand: tokens, numeric and alphabet codes, their stored digests and constant-time comparison.
Package secret mints and compares one-time secrets over crypto/rand: tokens, numeric and alphabet codes, their stored digests and constant-time comparison.
siws
Package siws implements Sign In With Solana (SIWS) authentication.
Package siws implements Sign In With Solana (SIWS) authentication.
testclock
Package testclock is a settable clock for tests that would otherwise sleep through a TTL, grace window or rate-limit window.
Package testclock is a settable clock for tests that would otherwise sleep through a TTL, grace window or rate-limit window.
testdb
Package testdb owns AuthKit's Postgres integration-test harness.
Package testdb owns AuthKit's Postgres integration-test harness.
testdpop
Package testdpop creates genuine signed sender proofs for workflow tests.
Package testdpop creates genuine signed sender proofs for workflow tests.
testhttp
Package testhttp is the adapters' preset over authtest.New.
Package testhttp is the adapters' preset over authtest.New.
testidp
Package testidp is a fake identity provider for tests of AuthKit's provider sign-in, link and recovery flows: an OpenID Provider (discovery, JWKS, ID tokens) and a plain OAuth2 server (token, userinfo) on one TLS server.
Package testidp is a fake identity provider for tests of AuthKit's provider sign-in, link and recovery flows: an OpenID Provider (discovery, JWKS, ID tokens) and a plain OAuth2 server (token, userinfo) on one TLS server.
testkeys
Package testkeys generates signing keys for tests.
Package testkeys generates signing keys for tests.
testoutbox
Package testoutbox defines the capturing email and SMS senders that authtest publishes as authtest.Outbox.
Package testoutbox defines the capturing email and SMS senders that authtest publishes as authtest.Outbox.
wireform
Package wireform puts a value in AuthKit's wire form before it is marshaled: every time in UTC, every list [] and every map {} rather than null.
Package wireform puts a value in AuthKit's wire form before it is marshaled: every time in UTC, every list [] and every map {} rather than null.
Package provider defines the external identity providers AuthKit's browser login flows delegate to.
Package provider defines the external identity providers AuthKit's browser login flows delegate to.
Package verify verifies AuthKit tokens without a database: access tokens and delegated access tokens of the issuers a Verifier trusts, checked against their keys (a JWKS, static keys or a live key source).
Package verify verifies AuthKit tokens without a database: access tokens and delegated access tokens of the issuers a Verifier trusts, checked against their keys (a JWKS, static keys or a live key source).

Jump to

Keyboard shortcuts

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