qaauthmw

package module
v0.0.7 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

go-quantumauth-mw

Powered by QuantumAuth

QuantumAuth middleware for Go HTTP servers.

This package allows Go backends to verify QuantumAuth requests signed by the QuantumAuth Client (TPM + Post-Quantum signatures), using either:

  • the hosted QuantumAuth backend (default), or
  • a custom / self-hosted verifier

Supported frameworks:

  • net/http
  • gin
  • chi

Badges

Go Version Build Codecov


Installation

go get github.com/quantumauth-io/go-quantumauth-mw

How QuantumAuth Works (Quick Overview)

  1. A frontend (web app) requests a challenge from the QuantumAuth browser extension
  2. The local QuantumAuth Client:
    • builds a canonical request
    • signs it with TPM + PQ keys
  3. The frontend sends the signed headers to your backend
  4. This middleware:
    • extracts the QuantumAuth headers
    • validates request shape
    • verifies signatures via the QuantumAuth backend
  5. On success, the authenticated user ID is injected into the request context

net/http Usage

Uses the hosted QuantumAuth backend automatically.

import (
    "net/http"

    qaauthmw "github.com/quantumauth-io/go-quantumauth-mw"
)

mux := http.NewServeMux()

mux.Handle("/protected",
    qaauthmw.QaMiddleware()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        userID, ok := qaauthmw.UserIDFromContext(r.Context())
        if !ok {
            http.Error(w, "unauthorized", http.StatusUnauthorized)
            return
        }

        w.Write([]byte("Hello user " + userID))
    })),
)

http.ListenAndServe(":8080", mux)

Gin Usage

import (
    "github.com/gin-gonic/gin"
    qagin "github.com/quantumauth-io/go-quantumauth-mw/gin"
)

r := gin.Default()
r.Use(qagin.QAMiddleware())

r.GET("/protected", func(c *gin.Context) {
    userID, ok := qagin.UserID(c)
    if !ok {
        c.AbortWithStatus(401)
        return
    }

    c.JSON(200, gin.H{
        "user_id": userID,
    })
})

r.Run(":8080")

Chi Usage

import (
    "github.com/go-chi/chi/v5"
    qaauthmw "github.com/quantumauth-io/go-quantumauth-mw"
    qachi "github.com/quantumauth-io/go-quantumauth-mw/chi"
)

r := chi.NewRouter()

r.Use(qachi.Middleware(
    &qaauthmw.RemoteVerifier{},
))

r.Get("/protected", func(w http.ResponseWriter, r *http.Request) {
    userID, ok := qachi.UserID(r.Context())
    if !ok {
        http.Error(w, "unauthorized", http.StatusUnauthorized)
        return
    }

    w.Write([]byte("Hello user " + userID))
})

License

Apache-2.0 © QuantumAuth

Documentation

Index

Constants

View Source
const (
	CtxUserIDKey ctxKey = "quantumauth_user_id"
)
View Source
const DefaultRemoteBaseURL = "https://api.quantumauth.io/quantum-auth/v1"

Variables

View Source
var (
	// ErrUnauthorized means the request was well-formed but failed auth.
	ErrUnauthorized = errors.New("quantumauth: unauthorized")
	// ErrBadRequest means the request could not be verified due to missing/invalid inputs.
	ErrBadRequest = errors.New("quantumauth: bad request")
)

Functions

func Middleware

func Middleware(v Verifier, opts ...Option) func(next http.Handler) http.Handler

func NormalizeHost

func NormalizeHost(host string) string

NormalizeHost makes host deterministic but DOES NOT guess ports. Recommendation: keep port if present; strip only junk.

func QAMiddleware

func QAMiddleware(opts ...Option) func(http.Handler) http.Handler

func QAMiddlewareWithRemote

func QAMiddlewareWithRemote(baseURL string, opts ...Option) func(http.Handler) http.Handler

func UserIDFromContext

func UserIDFromContext(ctx context.Context) (string, bool)

Types

type HostPolicy

type HostPolicy struct {
	// If empty, forwarded headers are NEVER trusted.
	TrustedProxyCIDRs []string

	// If true, also parse RFC 7239 Forwarded header (Forwarded: host=...).
	TrustForwardedHeader bool
}

HostPolicy selects which host is treated as canonical host for signing/verification.

func (HostPolicy) CanonicalHost

func (p HostPolicy) CanonicalHost(r *http.Request) (string, error)

type Option

type Option func(*Options)

func WithBadRequestHandler

func WithBadRequestHandler(f func(w http.ResponseWriter, r *http.Request, err error)) Option

func WithBodyReader added in v0.0.4

func WithBodyReader(f func(r *http.Request) ([]byte, error)) Option

func WithComputeBodySHA256 added in v0.0.4

func WithComputeBodySHA256(v bool) Option

func WithHostPolicy

func WithHostPolicy(p HostPolicy) Option

func WithPathFunc

func WithPathFunc(f func(r *http.Request) string) Option

func WithRequireAuth

func WithRequireAuth(v bool) Option

func WithUnauthorizedHandler

func WithUnauthorizedHandler(f func(w http.ResponseWriter, r *http.Request)) Option

type Options

type Options struct {
	RequireAuth       bool
	PathFunc          func(r *http.Request) string
	ComputeBodySHA256 bool
	BodyReader        func(r *http.Request) ([]byte, error)
	HostPolicy        HostPolicy
	OnUnauthorized    func(w http.ResponseWriter, r *http.Request)
	OnBadRequest      func(w http.ResponseWriter, r *http.Request, err error)
}

type QAHeaderFields

type QAHeaderFields struct {
	SigTPM string
	SigPQ  string
	// Future: challenge, kid, etc.
	Extra map[string]string
}

func ParseAuthorizationQuantumAuth

func ParseAuthorizationQuantumAuth(auth string) (*QAHeaderFields, error)

ParseAuthorizationQuantumAuth parses:

Authorization: QuantumAuth sig_tpm="...", sig_pq="..."

type RemoteVerifier

type RemoteVerifier struct {
	// Example: https://api.quantumauth.io/quantum-auth/v1
	// The middleware will POST {BaseURL}/auth/verify
	BaseURL string

	// Optional: provide a custom client; defaults to a sane one.
	Client *http.Client

	// Optional: allow injecting extra headers to QA backend (api key, etc.)
	ExtraHeaders map[string]string
}

func NewRemoteVerifier

func NewRemoteVerifier() *RemoteVerifier

func (*RemoteVerifier) Verify

type Verifier

type Verifier interface {
	Verify(ctx context.Context, in VerifyInput) (*VerifyResult, error)
}

type VerifyInput

type VerifyInput struct {
	Method    string
	Path      string
	Headers   map[string]string
	Body      []byte
	Encrypted json.RawMessage
}

type VerifyResult

type VerifyResult struct {
	Authenticated bool
	UserID        string
}

Directories

Path Synopsis
Package qachi exists for symmetry with other framework adapters.
Package qachi exists for symmetry with other framework adapters.

Jump to

Keyboard shortcuts

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