auth

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2025 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package auth provides utilities for authenticating requests.

Authentication is delegated to an identity provider, which is responsible for verifying the identity of the client and returning an identity token. The identity token is then signed and returned to the client as a JWT — either as a cookie or in the response.

The client then uses the cookie, or token, to authenticate future requests.

Identity Providers should implement the LoginHandler interface, and register it with AddLoginHandler. This will hook the provider into the Login endpoint and allow it to handle login requests.

Observe the google or magiclink example for a complete example of how to use this package.

Index

Constants

View Source
const (
	LoginEvent  = "auth.login"
	LogoutEvent = "auth.logout"
)
View Source
const (
	AuthService_Login_FullMethodName    = "/prefab.auth.AuthService/Login"
	AuthService_Logout_FullMethodName   = "/prefab.auth.AuthService/Logout"
	AuthService_Identity_FullMethodName = "/prefab.auth.AuthService/Identity"
)
View Source
const IdentityTokenCookieName = "pf-id"

Cookie name used for storing the prefab identity token.

View Source
const PluginName = "auth"

Constant name for identifying the core auth plugin.

Variables

View Source
var (
	// No identity was found within the incoming context.
	ErrNotFound = errors.NewC("identity not found", codes.Unauthenticated)

	// The token's expiration date was in the past.
	ErrExpired = errors.NewC("token has expired", codes.Unauthenticated)

	// The token was not signed correctly.
	ErrInvalidToken = errors.NewC("token is invalid", codes.InvalidArgument)

	// Invalid authorization header.
	ErrInvalidHeader = errors.NewC("bad authorization header", codes.InvalidArgument)

	// Identity token has been revoked or blocked.
	ErrRevoked = errors.NewC("token has been revoked", codes.Unauthenticated)
)
View Source
var AuthService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "prefab.auth.AuthService",
	HandlerType: (*AuthServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Login",
			Handler:    _AuthService_Login_Handler,
		},
		{
			MethodName: "Logout",
			Handler:    _AuthService_Logout_Handler,
		},
		{
			MethodName: "Identity",
			Handler:    _AuthService_Identity_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "plugins/auth/authservice.proto",
}

AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service. It's only intended for direct use with grpc.RegisterService, and not to be introspected or modified (even as a copy)

View Source
var File_plugins_auth_authservice_proto protoreflect.FileDescriptor

Functions

func IdentityToken

func IdentityToken(ctx context.Context, identity Identity) (string, error)

IdentityToken creates a signed JWT for the given identity.

func IsBlocked

func IsBlocked(ctx context.Context, key string) (bool, error)

IsBlocked checks if a token is blocked.

func MaybeBlock

func MaybeBlock(ctx context.Context, key string) error

MaybeBlock adds a token to the blocklist if a blocklist is present in the context.

func RegisterAuthServiceHandler

func RegisterAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error

RegisterAuthServiceHandler registers the http handlers for service AuthService to "mux". The handlers forward requests to the grpc endpoint over "conn".

func RegisterAuthServiceHandlerClient

func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthServiceClient) error

RegisterAuthServiceHandlerClient registers the http handlers for service AuthService to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthServiceClient". Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthServiceClient" doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in "AuthServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.

func RegisterAuthServiceHandlerFromEndpoint

func RegisterAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error)

RegisterAuthServiceHandlerFromEndpoint is same as RegisterAuthServiceHandler but automatically dials to "endpoint" and closes the connection when "ctx" gets done.

func RegisterAuthServiceHandlerServer

func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServiceServer) error

RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux". UnaryRPC :call AuthServiceServer directly. StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthServiceHandlerFromEndpoint instead. GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.

func RegisterAuthServiceServer

func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer)

func SendIdentityCookie

func SendIdentityCookie(ctx context.Context, token string) error

SendIdentityCookie attaches the token to the outgoing GRPC metadata such that it will be propagated as a `Set-Cookie` HTTP header by the Gateway.

func WithBlockist

func WithBlockist(ctx context.Context, bl Blocklist) context.Context

WithBlockist adds a blocklist to the context.

func WithIdentityExtractors

func WithIdentityExtractors(ctx context.Context, providers ...IdentityExtractor) context.Context

WithIdentityExtractors attaches a list of identity providers to the context.

func WithIdentityExtractorsForTest

func WithIdentityExtractorsForTest(ctx context.Context) context.Context

WithIdentityExtractorsForTest returns a context with the default identity extractors attached. This is useful for testing, where we want to simulate a request with a given identity.

func WithIdentityForTest

func WithIdentityForTest(ctx context.Context, identity Identity) context.Context

WithIdentityForTest creates a new context with the given identity attached. This is useful for testing, where we want to simulate a request with a given identity.

Types

type AuthEvent

type AuthEvent struct {
	Identity Identity
}

AuthEvent is an event that is emitted when an authentication event occurs.

type AuthOption

type AuthOption func(*AuthPlugin)

AuthOptions allow configuration of the AuthPlugin.

func WithBlocklist

func WithBlocklist(bl Blocklist) AuthOption

WithBlockist configures a custom blocklist to use for token revocation. Tokens can be revoked by application code and will be revoked during Logout. The blocklist is checked during token validation.

func WithExpiration

func WithExpiration(expiration time.Duration) AuthOption

WithExpiration sets the expiration to use when signing JWT tokens.

func WithSigningKey

func WithSigningKey(signingKey string) AuthOption

WithSigningKey sets the signing key to use when signing JWT tokens.

type AuthPlugin

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

AuthPlugin exposes plugin interfaces that register and manage the AuthService and related functionality.

func Plugin

func Plugin(opts ...AuthOption) *AuthPlugin

Plugin returns a new AuthPlugin.

func (*AuthPlugin) AddIdentityExtractor

func (ap *AuthPlugin) AddIdentityExtractor(provider IdentityExtractor)

AddIdentityExtractor can be called by other plugins to register identity extractors which will be used to authenticate requests.

The AuthPlugin assumes that any identity returned by an extractor has been verified, and will not perform any additional verification. Extractors should return ErrNotFound if no identity is observed.

func (*AuthPlugin) AddLoginHandler

func (ap *AuthPlugin) AddLoginHandler(provider string, h LoginHandler)

AddLoginHandler can be called by other plugins to register login handlers.

func (*AuthPlugin) Init

func (ap *AuthPlugin) Init(ctx context.Context, r *prefab.Registry) error

From prefab.InitializablePlugin.

func (*AuthPlugin) Name

func (ap *AuthPlugin) Name() string

From prefab.Plugin.

func (*AuthPlugin) OptDeps

func (ap *AuthPlugin) OptDeps() []string

From prefab.OptionalDependentPlugin.

func (*AuthPlugin) ServerOptions

func (ap *AuthPlugin) ServerOptions() []prefab.ServerOption

From prefab.OptionProvider.

type AuthServiceClient

type AuthServiceClient interface {
	// Login allows a client to provide credentials which can be used to
	// authenticate the client's identity. POST is preferred, some providers need
	// credentials to be passed as GET.
	Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error)
	// Logout clears the prefab id cookie. It should be noted that by default the
	// identity token will remain valid until its expiry. Token invalidatation is
	// supported via the addition of a blocklist.
	Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error)
	// Identity returns information about the authenticated user.
	Identity(ctx context.Context, in *IdentityRequest, opts ...grpc.CallOption) (*IdentityResponse, error)
}

AuthServiceClient is the client API for AuthService service.

For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.

type AuthServiceServer

type AuthServiceServer interface {
	// Login allows a client to provide credentials which can be used to
	// authenticate the client's identity. POST is preferred, some providers need
	// credentials to be passed as GET.
	Login(context.Context, *LoginRequest) (*LoginResponse, error)
	// Logout clears the prefab id cookie. It should be noted that by default the
	// identity token will remain valid until its expiry. Token invalidatation is
	// supported via the addition of a blocklist.
	Logout(context.Context, *LogoutRequest) (*LogoutResponse, error)
	// Identity returns information about the authenticated user.
	Identity(context.Context, *IdentityRequest) (*IdentityResponse, error)
	// contains filtered or unexported methods
}

AuthServiceServer is the server API for AuthService service. All implementations must embed UnimplementedAuthServiceServer for forward compatibility.

func New

func New() AuthServiceServer

type BlockedToken

type BlockedToken struct {
	Key string
}

BlockedToken is a model for storing blocked tokens.

func (*BlockedToken) PK

func (bt *BlockedToken) PK() string

Implements storage.Model.

type Blocklist

type Blocklist interface {
	// IsBlocked checks if a token with the given key is blocked.
	IsBlocked(key string) (bool, error)

	// Block adds a token to the blocklist. Key can be the token itself or a
	// unique ID.
	Block(key string) error
}

Blocklist is an interface for managed blocked tokens. By default identity tokens are valid until they expire. This interface allows applications to block tokens before they expire.

func NewBlocklist

func NewBlocklist(store storage.Store) Blocklist

NewBlocklist creates a basic implementation of the blocklist interface, backed via a storage.Store.

type Claims

type Claims struct {
	// Standard public JWT claims per https://www.iana.org/assignments/jwt/jwt.xhtml
	jwt.RegisteredClaims
	Name          string           `json:"name"`
	Email         string           `json:"email"`
	EmailVerified bool             `json:"email_verified"`
	AuthTime      *jwt.NumericDate `json:"auth_time,omitempty"`

	// Custom claims.
	Provider string `json:"idp"`
}

Claims registered as part of a prefab identity token.

func (*Claims) Validate

func (c *Claims) Validate() error

type ConfigRequest

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

Empty request object.

func (*ConfigRequest) Descriptor deprecated

func (*ConfigRequest) Descriptor() ([]byte, []int)

Deprecated: Use ConfigRequest.ProtoReflect.Descriptor instead.

func (*ConfigRequest) ProtoMessage

func (*ConfigRequest) ProtoMessage()

func (*ConfigRequest) ProtoReflect

func (x *ConfigRequest) ProtoReflect() protoreflect.Message

func (*ConfigRequest) Reset

func (x *ConfigRequest) Reset()

func (*ConfigRequest) String

func (x *ConfigRequest) String() string

type ConfigResponse

type ConfigResponse struct {

	// Token that should be used in non-XHR requests to avoid cross-site request
	// forgery attacks.
	CsrfToken string `protobuf:"bytes,1,opt,name=csrf_token,json=csrfToken,proto3" json:"csrf_token,omitempty"`
	// A map of key-value pairs configured by available auth plugins, for example
	// google.client_id.
	Configs map[string]string `` /* 141-byte string literal not displayed */
	// contains filtered or unexported fields
}

Configuration information to help clients facilitate login.

func (*ConfigResponse) Descriptor deprecated

func (*ConfigResponse) Descriptor() ([]byte, []int)

Deprecated: Use ConfigResponse.ProtoReflect.Descriptor instead.

func (*ConfigResponse) GetConfigs

func (x *ConfigResponse) GetConfigs() map[string]string

func (*ConfigResponse) GetCsrfToken

func (x *ConfigResponse) GetCsrfToken() string

func (*ConfigResponse) ProtoMessage

func (*ConfigResponse) ProtoMessage()

func (*ConfigResponse) ProtoReflect

func (x *ConfigResponse) ProtoReflect() protoreflect.Message

func (*ConfigResponse) Reset

func (x *ConfigResponse) Reset()

func (*ConfigResponse) String

func (x *ConfigResponse) String() string

type Identity

type Identity struct {

	// Unique identifier for the session that authenticated the identity. Maps to
	// the `jti` JWT claim.
	SessionID string

	// The time at which the identity was authenticated. Maps to `auth_time` JWT
	// claim. May differ from IssuedAt if a token is refreshed.
	AuthTime time.Time

	// Identity provider specific identifier. Maps to `sub` JWT claim.
	Subject string

	// Name of the identity provider used to authenticate the user. Maps to custom
	// `idp` JWT claim.
	Provider string

	// The email address received from the identity provider, if available. Maps
	// to `email` JWT claim.
	Email string

	// Whether the identity provider has verified the email address. Maps to
	// `email_verified` JWT claim.
	EmailVerified bool

	// Name received from the identity provider, if available. Maps to `name` JWT
	// claim.
	Name string
}

func IdentityFromContext

func IdentityFromContext(ctx context.Context) (Identity, error)

IdentityFromContext parses and verifies a JWT received from the incoming request context (including GRPC metadata.) An `Authorization` header will take precedence over a `Cookie`, which in turn will take precedence over other identity extractors.

func ParseIdentityToken

func ParseIdentityToken(ctx context.Context, tokenString string) (Identity, error)

ParseIdentityToken takes a signed JWT, validates it, and returns the identity information encoded within. Invalid and expired tokens will error.

type IdentityExtractor

type IdentityExtractor func(ctx context.Context) (Identity, error)

IdentityExtractor is a function which returns a user identity from a given context. Providers should return ErrNotFound if no identity is found. By default, JWT identities are extracted from the `Authorization` header, and then from cookies. If no identity is found, the next registered extractor is called.

type IdentityRequest

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

Empty request object. Auth credentials come from headers or cookie.

func (*IdentityRequest) Descriptor deprecated

func (*IdentityRequest) Descriptor() ([]byte, []int)

Deprecated: Use IdentityRequest.ProtoReflect.Descriptor instead.

func (*IdentityRequest) ProtoMessage

func (*IdentityRequest) ProtoMessage()

func (*IdentityRequest) ProtoReflect

func (x *IdentityRequest) ProtoReflect() protoreflect.Message

func (*IdentityRequest) Reset

func (x *IdentityRequest) Reset()

func (*IdentityRequest) String

func (x *IdentityRequest) String() string

type IdentityResponse

type IdentityResponse struct {
	Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"`
	// An auth provider specific identifier used to authenticate the user.
	Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"`
	// An email address associated with the identity, if available.
	Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
	// Whether the email is thought to have been verified.
	EmailVerified bool `protobuf:"varint,4,opt,name=email_verified,json=emailVerified,proto3" json:"email_verified,omitempty"`
	// A name associated with the identity, if available.
	Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
	// contains filtered or unexported fields
}

Information about the authenticated identity.

func (*IdentityResponse) Descriptor deprecated

func (*IdentityResponse) Descriptor() ([]byte, []int)

Deprecated: Use IdentityResponse.ProtoReflect.Descriptor instead.

func (*IdentityResponse) GetEmail

func (x *IdentityResponse) GetEmail() string

func (*IdentityResponse) GetEmailVerified

func (x *IdentityResponse) GetEmailVerified() bool

func (*IdentityResponse) GetName

func (x *IdentityResponse) GetName() string

func (*IdentityResponse) GetProvider

func (x *IdentityResponse) GetProvider() string

func (*IdentityResponse) GetSubject

func (x *IdentityResponse) GetSubject() string

func (*IdentityResponse) ProtoMessage

func (*IdentityResponse) ProtoMessage()

func (*IdentityResponse) ProtoReflect

func (x *IdentityResponse) ProtoReflect() protoreflect.Message

func (*IdentityResponse) Reset

func (x *IdentityResponse) Reset()

func (*IdentityResponse) String

func (x *IdentityResponse) String() string

type LoginHandler

type LoginHandler func(ctx context.Context, req *LoginRequest) (*LoginResponse, error)

LoginHandler is a function which allows delegation of login requests.

type LoginRequest

type LoginRequest struct {

	// Name of the auth-provider to use to process the creds.
	Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"`
	// Creds contains key/value pairs of provider specific credentials.
	Creds map[string]string `` /* 137-byte string literal not displayed */
	// Whether a token should be returned in the response. If false, a cookie will
	// be set on the API root.
	IssueToken bool `protobuf:"varint,3,opt,name=issue_token,json=issueToken,proto3" json:"issue_token,omitempty"`
	// The URL where the user should be redirected after the cookie is set.
	// Incompatible with `issue_token`.
	RedirectUri string `protobuf:"bytes,4,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"`
	// contains filtered or unexported fields
}

A client request to authenticate the user. For instance:

{ "provider": "magiclink", "creds": {"email": "[email protected]"} }

func (*LoginRequest) Descriptor deprecated

func (*LoginRequest) Descriptor() ([]byte, []int)

Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead.

func (*LoginRequest) GetCreds

func (x *LoginRequest) GetCreds() map[string]string

func (*LoginRequest) GetIssueToken

func (x *LoginRequest) GetIssueToken() bool

func (*LoginRequest) GetProvider

func (x *LoginRequest) GetProvider() string

func (*LoginRequest) GetRedirectUri

func (x *LoginRequest) GetRedirectUri() string

func (*LoginRequest) ProtoMessage

func (*LoginRequest) ProtoMessage()

func (*LoginRequest) ProtoReflect

func (x *LoginRequest) ProtoReflect() protoreflect.Message

func (*LoginRequest) Reset

func (x *LoginRequest) Reset()

func (*LoginRequest) String

func (x *LoginRequest) String() string

type LoginResponse

type LoginResponse struct {

	// Whether the token was issued. False does not necessarily indicate an error,
	// some auth providers may require an additional step. For example, magiclink
	// requires the user follow a URL that was sent to their email.
	Issued bool `protobuf:"varint,1,opt,name=issued,proto3" json:"issued,omitempty"`
	// An auth token which can be used to make subsequently authenticated requests
	// only set if `issue_token` is true.
	Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
	// Destination where the client should be redirected to, if applicable. HTTP
	// headers will be added to GRPC metadata which will cause a 302 redirect if
	// the RPC is called via the GRPC Gateway. Not compatible with `issue_token`
	// set to true.
	RedirectUri string `protobuf:"bytes,3,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"`
	// contains filtered or unexported fields
}

The login response.

func (*LoginResponse) Descriptor deprecated

func (*LoginResponse) Descriptor() ([]byte, []int)

Deprecated: Use LoginResponse.ProtoReflect.Descriptor instead.

func (*LoginResponse) GetIssued

func (x *LoginResponse) GetIssued() bool

func (*LoginResponse) GetRedirectUri

func (x *LoginResponse) GetRedirectUri() string

func (*LoginResponse) GetToken

func (x *LoginResponse) GetToken() string

func (*LoginResponse) ProtoMessage

func (*LoginResponse) ProtoMessage()

func (*LoginResponse) ProtoReflect

func (x *LoginResponse) ProtoReflect() protoreflect.Message

func (*LoginResponse) Reset

func (x *LoginResponse) Reset()

func (*LoginResponse) String

func (x *LoginResponse) String() string

type LogoutRequest

type LogoutRequest struct {

	// The URL where the user should be redirected after a successful logout.
	RedirectUri string `protobuf:"bytes,4,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"`
	// contains filtered or unexported fields
}

The login response.

func (*LogoutRequest) Descriptor deprecated

func (*LogoutRequest) Descriptor() ([]byte, []int)

Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead.

func (*LogoutRequest) GetRedirectUri

func (x *LogoutRequest) GetRedirectUri() string

func (*LogoutRequest) ProtoMessage

func (*LogoutRequest) ProtoMessage()

func (*LogoutRequest) ProtoReflect

func (x *LogoutRequest) ProtoReflect() protoreflect.Message

func (*LogoutRequest) Reset

func (x *LogoutRequest) Reset()

func (*LogoutRequest) String

func (x *LogoutRequest) String() string

type LogoutResponse

type LogoutResponse struct {

	// Destination where the client should be redirected to, if applicable. HTTP
	// headers will be added to GRPC metadata which will cause a 302 redirect if
	// the RPC is called via the GRPC Gateway.
	RedirectUri string `protobuf:"bytes,1,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"`
	// contains filtered or unexported fields
}

The logout response.

func (*LogoutResponse) Descriptor deprecated

func (*LogoutResponse) Descriptor() ([]byte, []int)

Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead.

func (*LogoutResponse) GetRedirectUri

func (x *LogoutResponse) GetRedirectUri() string

func (*LogoutResponse) ProtoMessage

func (*LogoutResponse) ProtoMessage()

func (*LogoutResponse) ProtoReflect

func (x *LogoutResponse) ProtoReflect() protoreflect.Message

func (*LogoutResponse) Reset

func (x *LogoutResponse) Reset()

func (*LogoutResponse) String

func (x *LogoutResponse) String() string

type UnimplementedAuthServiceServer

type UnimplementedAuthServiceServer struct{}

UnimplementedAuthServiceServer must be embedded to have forward compatible implementations.

NOTE: this should be embedded by value instead of pointer to avoid a nil pointer dereference when methods are called.

func (UnimplementedAuthServiceServer) Identity

func (UnimplementedAuthServiceServer) Login

func (UnimplementedAuthServiceServer) Logout

type UnsafeAuthServiceServer

type UnsafeAuthServiceServer interface {
	// contains filtered or unexported methods
}

UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service. Use of this interface is not recommended, as added methods to AuthServiceServer will result in compilation errors.

Directories

Path Synopsis
Package apikey provides an authentication plugin that allows for authentication via apikeys.
Package apikey provides an authentication plugin that allows for authentication via apikeys.
Package fake provides an authentication plugin for testing purposes.
Package fake provides an authentication plugin for testing purposes.
Package Google provides authentication via Google SSO.
Package Google provides authentication via Google SSO.
Package magiclink provides passwordless authentication, allowing users to authenticate using a magic link that is sent to their email address.
Package magiclink provides passwordless authentication, allowing users to authenticate using a magic link that is sent to their email address.
Package pwdauth provides an authentication service plugin that allows users to authenticate via a email and password.
Package pwdauth provides an authentication service plugin that allows users to authenticate via a email and password.

Jump to

Keyboard shortcuts

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