Overview
The Anubis package provides the core Server implementation for bot detection and challenge management. Use lib.New() to create a new server instance, and lib.LoadPoliciesOrDefault() to load policy configurations.
Functions
New
Creates a new Anubis server instance with the specified options.
func New ( opts Options ) ( * Server , error )
Server configuration options Upstream HTTP handler to proxy requests to after validation
Policy
*policy.ParsedConfig
required
Parsed policy configuration containing bot detection rules
Override Host header for upstream requests
SNI hostname for TLS connections
Skip TLS certificate verification (insecure)
Domain for session cookies
Automatically set cookie domain to eTLD+1
Cookie expiration duration
Enable cookie partitioning for CHIPS
Require secure (HTTPS) cookies
SameSite attribute for cookies (None, Lax, Strict)
URL prefix for all Anubis endpoints
Remove base prefix before proxying to upstream
Contact email shown on error pages
Allowed domains for redirects (supports glob patterns)
EdDSA private key for JWT signing (auto-generated if not provided)
HMAC-SHA512 secret for JWT signing (alternative to ED25519)
OpenGraph tag caching configuration
Structured logger instance
Log level (debug, info, warn, error)
Public URL of the Anubis instance
HTTP header to bind JWT to (for additional security)
Include challenge difficulty in JWT claims
Configured Anubis server instance
Error if server creation fails
Example
package main
import (
" context "
" log/slog "
" net/http "
" time "
" github.com/TecharoHQ/anubis/lib "
)
func main () {
ctx := context . Background ()
// Load policy configuration
policy , err := lib . LoadPoliciesOrDefault ( ctx , "policy.yaml" , 20 , "info" )
if err != nil {
panic ( err )
}
// Create upstream handler
upstream := http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
w . Write ([] byte ( "Hello, verified human!" ))
)
// Create Anubis server
server , err := lib . New ( lib . Options {
Next : upstream ,
Policy : policy ,
CookieExpiration : 24 * time . Hour ,
CookieSecure : true ,
CookieSameSite : http . SameSiteLaxMode ,
Logger : slog . Default (),
)
if err != nil {
panic ( err )
}
// Serve requests
http . ListenAndServe ( ":8080" , server )
}
LoadPoliciesOrDefault
Loads policy configuration from a file or uses the built-in default policies.
func LoadPoliciesOrDefault ( ctx context . Context , fname string , defaultDifficulty int , logLevel string ) ( * policy . ParsedConfig , error )
Context for loading policies (may include Thoth client)
Path to policy YAML file. If empty, uses built-in default policies
Default proof-of-work difficulty level (0-64, recommended: 15-25)
Log level: “debug”, “info”, “warn”, or “error”
Parsed and validated policy configuration
Error if policy loading or validation fails
Example
ctx := context . Background ()
// Load custom policy file
policy , err := lib . LoadPoliciesOrDefault ( ctx , "/etc/anubis/policy.yaml" , 20 , "info" )
if err != nil {
log . Fatal ( err )
}
// Use built-in default policies
policy , err = lib . LoadPoliciesOrDefault ( ctx , "" , 20 , "info" )
if err != nil {
log . Fatal ( err )
}
Server Type
The Server type implements http.Handler and manages bot detection, challenge issuance, and request validation.
Server Methods
ServeHTTP
Implements the http.Handler interface. Routes requests to static assets, API endpoints, or the validation middleware.
func ( s * Server ) ServeHTTP ( w http . ResponseWriter , r * http . Request )
Behavior:
Static assets (.within.website/static/*) are served directly
API endpoints (.within.website/api/*) handle challenges and validation
All other requests go through the bot detection and challenge flow
Validated requests with valid JWT cookies are proxied to the upstream handler
Example
server , _ := lib . New ( opts )
// Use as HTTP handler
http . ListenAndServe ( ":8080" , server )
// Or wrap with middleware
http . Handle ( "/" , loggingMiddleware ( server ))
MakeChallenge
API endpoint that issues a new challenge for client-side solving. Only available in development builds.
func ( s * Server ) MakeChallenge ( w http . ResponseWriter , r * http . Request )
Request Parameters:
redir (query string): Redirect URL after challenge completion
Response: JSON with challenge data
{
"rules" : {
"algorithm" : "fast" ,
"difficulty" : 20
},
"challenge" : "hexadecimal random data" ,
"id" : "challenge UUID"
}
See lib/anubis.go:361-432
PassChallenge
API endpoint that validates a completed challenge and issues a JWT cookie upon success.
func ( s * Server ) PassChallenge ( w http . ResponseWriter , r * http . Request )
Request Parameters:
redir (query string, required): Redirect URL after successful validation
id (query string, required): Challenge ID
Challenge-specific validation parameters (varies by algorithm)
Response:
On success: HTTP 302 redirect with JWT cookie set
On failure: Error page with details
Security:
Validates redirect domain against RedirectDomains whitelist
Prevents double-spend attacks (challenges can only be solved once)
Binds JWT to HTTP header if JWTRestrictionHeader is set
See lib/anubis.go:434-585
HTTP Endpoints
Anubis registers the following endpoints (all prefixed with BasePrefix, default /.within.website):
Endpoint Method Purpose /api/pass-challengeGET Validate completed challenge /api/checkAny Auth check endpoint (returns status only) /api/imprintGET Display impressum/legal page /api/make-challengePOST Issue new challenge (dev only) /api/honeypot/{id}/{stage}GET Honeypot trap endpoints /static/*GET Static assets (JS, CSS) /robots.txtGET Robots file (if enabled) /*Any Main validation middleware
Challenge - Challenge data structures and interface
Policy - Bot detection rules and configuration
Store - Storage backend interface