> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/TecharoHq/Anubis/llms.txt
> Use this file to discover all available pages before exploring further.

# Anubis Server

> Core server initialization and HTTP handling

## 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.

```go theme={null}
func New(opts Options) (*Server, error)
```

<ParamField path="opts" type="Options" required>
  Server configuration options

  <Expandable title="Options fields">
    <ParamField path="Next" type="http.Handler">
      Upstream HTTP handler to proxy requests to after validation
    </ParamField>

    <ParamField path="Policy" type="*policy.ParsedConfig" required>
      Parsed policy configuration containing bot detection rules
    </ParamField>

    <ParamField path="Target" type="string">
      Upstream target URL
    </ParamField>

    <ParamField path="TargetHost" type="string">
      Override Host header for upstream requests
    </ParamField>

    <ParamField path="TargetSNI" type="string">
      SNI hostname for TLS connections
    </ParamField>

    <ParamField path="TargetInsecureSkipVerify" type="bool">
      Skip TLS certificate verification (insecure)
    </ParamField>

    <ParamField path="CookieDomain" type="string">
      Domain for session cookies
    </ParamField>

    <ParamField path="CookieDynamicDomain" type="bool">
      Automatically set cookie domain to eTLD+1
    </ParamField>

    <ParamField path="CookieExpiration" type="time.Duration">
      Cookie expiration duration
    </ParamField>

    <ParamField path="CookiePartitioned" type="bool">
      Enable cookie partitioning for CHIPS
    </ParamField>

    <ParamField path="CookieSecure" type="bool">
      Require secure (HTTPS) cookies
    </ParamField>

    <ParamField path="CookieSameSite" type="http.SameSite">
      SameSite attribute for cookies (None, Lax, Strict)
    </ParamField>

    <ParamField path="BasePrefix" type="string">
      URL prefix for all Anubis endpoints
    </ParamField>

    <ParamField path="StripBasePrefix" type="bool">
      Remove base prefix before proxying to upstream
    </ParamField>

    <ParamField path="WebmasterEmail" type="string">
      Contact email shown on error pages
    </ParamField>

    <ParamField path="RedirectDomains" type="[]string">
      Allowed domains for redirects (supports glob patterns)
    </ParamField>

    <ParamField path="ED25519PrivateKey" type="ed25519.PrivateKey">
      EdDSA private key for JWT signing (auto-generated if not provided)
    </ParamField>

    <ParamField path="HS512Secret" type="[]byte">
      HMAC-SHA512 secret for JWT signing (alternative to ED25519)
    </ParamField>

    <ParamField path="OpenGraph" type="config.OpenGraph">
      OpenGraph tag caching configuration
    </ParamField>

    <ParamField path="ServeRobotsTXT" type="bool">
      Serve robots.txt file
    </ParamField>

    <ParamField path="Logger" type="*slog.Logger">
      Structured logger instance
    </ParamField>

    <ParamField path="LogLevel" type="string">
      Log level (debug, info, warn, error)
    </ParamField>

    <ParamField path="PublicUrl" type="string">
      Public URL of the Anubis instance
    </ParamField>

    <ParamField path="JWTRestrictionHeader" type="string">
      HTTP header to bind JWT to (for additional security)
    </ParamField>

    <ParamField path="DifficultyInJWT" type="bool">
      Include challenge difficulty in JWT claims
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="server" type="*Server">
  Configured Anubis server instance
</ResponseField>

<ResponseField name="error" type="error">
  Error if server creation fails
</ResponseField>

**Example**

```go theme={null}
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.

```go theme={null}
func LoadPoliciesOrDefault(ctx context.Context, fname string, defaultDifficulty int, logLevel string) (*policy.ParsedConfig, error)
```

<ParamField path="ctx" type="context.Context" required>
  Context for loading policies (may include Thoth client)
</ParamField>

<ParamField path="fname" type="string">
  Path to policy YAML file. If empty, uses built-in default policies
</ParamField>

<ParamField path="defaultDifficulty" type="int" required>
  Default proof-of-work difficulty level (0-64, recommended: 15-25)
</ParamField>

<ParamField path="logLevel" type="string" required>
  Log level: "debug", "info", "warn", or "error"
</ParamField>

<ResponseField name="config" type="*policy.ParsedConfig">
  Parsed and validated policy configuration
</ResponseField>

<ResponseField name="error" type="error">
  Error if policy loading or validation fails
</ResponseField>

**Example**

```go theme={null}
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.

```go theme={null}
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**

```go theme={null}
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.

```go theme={null}
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

```json theme={null}
{
  "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.

```go theme={null}
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-challenge`        | GET    | Validate completed challenge              |
| `/api/check`                 | Any    | Auth check endpoint (returns status only) |
| `/api/imprint`               | GET    | Display impressum/legal page              |
| `/api/make-challenge`        | POST   | Issue new challenge (dev only)            |
| `/api/honeypot/{id}/{stage}` | GET    | Honeypot trap endpoints                   |
| `/static/*`                  | GET    | Static assets (JS, CSS)                   |
| `/robots.txt`                | GET    | Robots file (if enabled)                  |
| `/*`                         | Any    | Main validation middleware                |

***

## Related Types

* [Challenge](/api/challenge) - Challenge data structures and interface
* [Policy](/api/policy) - Bot detection rules and configuration
* [Store](/api/store) - Storage backend interface
