accesstoken

package
v0.14.21 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package accesstoken manages Personal Access Tokens — static bearer credentials a user generates from /profile/tokens and pastes into a remote MCP client (Claude Desktop, Cursor, VSCode plugin, custom CLI). The same token also authenticates any other wick HTTP API a user wires up.

The plaintext token is shown to the user exactly once, at creation time. Wick stores only the SHA-256 hash so the token can be looked up on incoming requests but never reconstructed if the DB leaks.

Token wire format:

wick_pat_<32 hex chars>

The "wick_pat_" prefix is the routing hint auth middleware uses to distinguish static bearers from OAuth JWTs (see internal/docs/ connectors-design.md §8.3).

Index

Constants

View Source
const Prefix = "wick_pat_"

Prefix is the leading marker of every wick PAT. MCP auth middleware uses it to route the request into pat.Service.Authenticate before falling back to the OAuth path.

Variables

View Source
var ErrInvalid = errors.New("invalid token")

ErrInvalid signals an unparseable or unrecognized token. Returned (rather than wrapped) so middleware can short-circuit cheaply.

View Source
var StaticFS embed.FS

Functions

This section is empty.

Types

type Handler

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

Handler exposes the /profile/tokens and /profile/mcp routes — the user-facing surface for issuing access tokens and reading the MCP install instructions. Tokens are general-purpose bearers (any wick HTTP endpoint accepts them); the MCP page is a thin documentation layer pointing at the same tokens.

func NewHandler

func NewHandler(svc *Service, cfg appConfig) *Handler

func (*Handler) Register

func (h *Handler) Register(mux *http.ServeMux, midd *login.Middleware)

Register wires the routes. All require an authenticated user; no admin role gate (every approved user manages their own tokens).

type IssueResult

type IssueResult struct {
	Token string // plaintext "wick_pat_..." — never re-derivable
	Row   *entity.PersonalAccessToken
}

IssueResult bundles the freshly stored row plus the plaintext token. The plaintext is only ever returned by Issue — there is no other API to read it. The handler displays it once and discards it.

type Repo

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

Repo wraps the gorm handle. All queries scope on context so HTTP cancellation propagates into the DB driver.

func NewRepo

func NewRepo(db *gorm.DB) *Repo

func (*Repo) Create

func (r *Repo) Create(ctx context.Context, t *entity.PersonalAccessToken) error

Create inserts a new token row.

func (*Repo) FindByHash

func (r *Repo) FindByHash(ctx context.Context, hash string) (*entity.PersonalAccessToken, error)

FindByHash looks up an active token by its SHA-256 hash. Returns gorm.ErrRecordNotFound when no active row matches.

func (*Repo) GetForUser

func (r *Repo) GetForUser(ctx context.Context, id, userID string) (*entity.PersonalAccessToken, error)

GetForUser loads a token belonging to userID. Used by the revoke handler to enforce ownership before mutating.

func (*Repo) ListActiveByUser

func (r *Repo) ListActiveByUser(ctx context.Context, userID string) ([]entity.PersonalAccessToken, error)

ListActiveByUser returns the user's non-revoked tokens, newest first.

func (*Repo) ListAllActive

func (r *Repo) ListAllActive(ctx context.Context) ([]entity.PersonalAccessToken, error)

ListAllActive returns every non-revoked token across all users, newest first. Drives the admin MCP page; not exposed to non-admin callers.

func (*Repo) Revoke

func (r *Repo) Revoke(ctx context.Context, id, userID string) error

Revoke stamps RevokedAt on a token belonging to userID. No-op when the row is already revoked.

func (*Repo) RevokeAny

func (r *Repo) RevokeAny(ctx context.Context, id string) error

RevokeAny stamps RevokedAt on a token regardless of owner. Used by the admin override path; the user-facing Revoke still enforces ownership.

func (*Repo) TouchLastUsed

func (r *Repo) TouchLastUsed(ctx context.Context, id string) error

TouchLastUsed stamps LastUsedAt = now. Cheap fire-and-forget call from the MCP auth middleware.

type Service

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

Service is the runtime façade for token CRUD. The handler at /profile/mcp drives Issue/Revoke; the future MCP middleware drives Authenticate.

func NewService

func NewService(r *Repo) *Service

func NewServiceFromDB

func NewServiceFromDB(db *gorm.DB) *Service

func (*Service) Authenticate

func (s *Service) Authenticate(ctx context.Context, plain string) (userID string, err error)

Authenticate validates a plaintext bearer pulled from an incoming request and returns the owning user_id. Returns ErrInvalid for any malformed, unknown, or revoked token so middleware can respond with a uniform 401 — callers MUST NOT distinguish "wrong format" from "wrong token" in the response.

LastUsedAt is stamped best-effort; failure to update does not fail the auth (the DB write is observability, not a gate).

func (*Service) Issue

func (s *Service) Issue(ctx context.Context, userID, name string) (*IssueResult, error)

Issue mints a new token for userID with the given human label. Returns the plaintext token and the persisted row. The plaintext MUST NOT be logged or stored anywhere outside the response back to the user.

func (*Service) ListActive

func (s *Service) ListActive(ctx context.Context, userID string) ([]entity.PersonalAccessToken, error)

ListActive returns the user's non-revoked tokens, newest first. The plaintext is unrecoverable — UI shows the masked form via Row.Masked().

func (*Service) ListAllActive

func (s *Service) ListAllActive(ctx context.Context) ([]entity.PersonalAccessToken, error)

ListAllActive returns every non-revoked token across all users. Admin-only — exposed via /admin/mcp.

func (*Service) Revoke

func (s *Service) Revoke(ctx context.Context, id, userID string) error

Revoke stamps RevokedAt on a token the user owns. Errors when the row does not exist or belongs to another user.

func (*Service) RevokeAny

func (s *Service) RevokeAny(ctx context.Context, id string) error

RevokeAny stamps RevokedAt on a token without checking ownership. Admin-only override; the user-facing Revoke still enforces it.

Directories

Path Synopsis
templ: version: v0.3.1020
templ: version: v0.3.1020

Jump to

Keyboard shortcuts

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