Skip to main content

Overview

Anubis uses pluggable storage backends to persist client state, challenge tokens, and bot detection metadata. The storage configuration determines which backend to use and its parameters.

Store

Storage backend configuration struct.

Type Definition

type Store struct {
    Backend    string          `json:"backend"`
    Parameters json.RawMessage `json:"parameters"`
}

Fields

Backend
string
required
Storage backend type. Must be a registered store backend.Built-in backends:
  • "memory" - In-memory storage (default, not persistent)
  • "bbolt" - BoltDB embedded database
  • "valkey" - Valkey/Redis compatible server
  • "s3api" - S3-compatible object storage
Parameters
json.RawMessage
Backend-specific configuration as raw JSON. The structure depends on the selected backend.

Validation Rules

  • Backend must be non-empty
  • Backend must be a registered store implementation
  • Parameters must be valid according to the backend’s validation rules

Errors

var (
    ErrNoStoreBackend      = errors.New("config.Store: no backend defined")
    ErrUnknownStoreBackend = errors.New("config.Store: unknown backend")
)

Backend-Specific Parameters

Memory Backend

The memory backend requires no parameters. State is stored in-process and lost on restart.
store:
  backend: memory

BoltDB Backend

Embedded database stored in a local file.
store:
  backend: bbolt
  parameters:
    path: "./var/anubis.db"
    mode: 0600
Parameters:
  • path (string, required): Filesystem path to the database file
  • mode (int, optional): File permissions in octal (default: 0600)

Valkey/Redis Backend

Connect to a Valkey or Redis server.
store:
  backend: valkey
  parameters:
    address: "localhost:6379"
    password: "secret"
    db: 0
    poolSize: 10
Parameters:
  • address (string, required): Server address (host:port)
  • password (string, optional): Authentication password
  • db (int, optional): Database number (default: 0)
  • poolSize (int, optional): Connection pool size
  • tls (bool, optional): Enable TLS

S3 Backend

Use S3-compatible object storage (AWS S3, MinIO, etc.).
store:
  backend: s3api
  parameters:
    bucket: "anubis-state"
    region: "us-east-1"
    endpoint: "https://s3.amazonaws.com"
    accessKeyId: "AKIAIOSFODNN7EXAMPLE"
    secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
Parameters:
  • bucket (string, required): S3 bucket name
  • region (string, required): AWS region
  • endpoint (string, optional): Custom S3 endpoint (for S3-compatible services)
  • accessKeyId (string, required): AWS access key ID
  • secretAccessKey (string, required): AWS secret access key
  • sessionToken (string, optional): AWS session token

Default Configuration

When no store is specified, Anubis defaults to in-memory storage:
Store: &Store{
    Backend: "memory",
}

StatusCodes

HTTP status codes returned for different actions.

Type Definition

type StatusCodes struct {
    Challenge int `json:"CHALLENGE"`
    Deny      int `json:"DENY"`
}

Fields

Challenge
int
default:"200"
HTTP status code to return when presenting a challenge. Valid range: 100-599.Common values:
  • 200 - OK (default, challenge rendered in response body)
  • 403 - Forbidden
  • 429 - Too Many Requests
Deny
int
default:"200"
HTTP status code to return when denying a request. Valid range: 100-599.Common values:
  • 200 - OK (default, denial message in response body)
  • 403 - Forbidden
  • 429 - Too Many Requests
  • 503 - Service Unavailable

Validation Rules

  • Both Challenge and Deny must be set
  • Both must be in range 100-599

Errors

var (
    ErrStatusCodeNotValid = errors.New("config.StatusCode: status code not valid, must be between 100 and 599")
)

Example

status_codes:
  CHALLENGE: 429
  DENY: 403

DnsTTL

DNS cache TTL settings for reverse DNS lookups.

Type Definition

type DnsTTL struct {
    Forward int `json:"forward"`
    Reverse int `json:"reverse"`
}

Fields

Forward
int
default:"300"
TTL in seconds for forward DNS lookups (hostname to IP). Must be >= 0.
Reverse
int
default:"300"
TTL in seconds for reverse DNS lookups (IP to hostname). Must be >= 0.

Example

dns_ttl:
  forward: 600
  reverse: 600

Logging

Logging configuration for Anubis.

Type Definition

type Logging struct {
    Sink       string             `json:"sink"`
    Level      *slog.Level        `json:"level"`
    Parameters *LoggingFileConfig `json:"parameters"`
}

Fields

Sink
string
default:"stdio"
Logging output sink. Valid values: "stdio", "file".
Level
*slog.Level
Log level. If set, overrides the level from command-line flags.Valid levels:
  • slog.LevelDebug (-4)
  • slog.LevelInfo (0)
  • slog.LevelWarn (4)
  • slog.LevelError (8)
Parameters
*LoggingFileConfig
File logging configuration. Required when Sink is "file".

Validation Rules

  • If Sink is "file", Parameters must be set
  • Parameters must pass its own validation

Errors

var (
    ErrMissingLoggingFileConfig = errors.New("config.Logging: missing value parameters in logging block")
    ErrInvalidLoggingSink       = errors.New("config.Logging: invalid sink")
)

LoggingFileConfig

File-based logging configuration with log rotation.

Type Definition

type LoggingFileConfig struct {
    Filename     string `json:"file"`
    MaxBackups   int    `json:"maxBackups"`
    MaxBytes     int64  `json:"maxBytes"`
    MaxAge       int    `json:"maxAge"`
    Compress     bool   `json:"compress"`
    UseLocalTime bool   `json:"useLocalTime"`
}

Fields

Filename
string
required
Path to the log file.
MaxBackups
int
default:"3"
Maximum number of old log files to retain. Must be >= 0.
MaxBytes
int64
default:"104857600"
Maximum size in bytes before rotating the log file (default: 100 MiB).
MaxAge
int
default:"7"
Maximum number of days to retain old log files. Must be >= 0.
Compress
bool
default:"true"
Compress rotated log files using gzip.
UseLocalTime
bool
default:"false"
Use local time for log file timestamps instead of UTC.

Validation Rules

  • Filename must be set
  • MaxBackups must be >= 0
  • MaxAge must be >= 0

Errors

var (
    ErrInvalidLoggingFileConfig = errors.New("config.LoggingFileConfig: invalid parameters")
    ErrOutOfRange               = errors.New("config: error out of range")
)

Example

logging:
  sink: file
  parameters:
    file: "./var/anubis.log"
    maxBackups: 5
    maxBytes: 209715200  # 200 MiB
    maxAge: 14
    compress: true
    useLocalTime: false

OpenGraph

OpenGraph metadata configuration for social media previews.

Type Definition

type OpenGraph struct {
    Override     map[string]string `json:"override,omitempty" yaml:"override,omitempty"`
    TimeToLive   time.Duration     `json:"ttl" yaml:"ttl"`
    Enabled      bool              `json:"enabled" yaml:"enabled"`
    ConsiderHost bool              `json:"considerHost" yaml:"enabled"`
}

Fields

Enabled
bool
default:"false"
Enable OpenGraph tag caching and customization.
ConsiderHost
bool
default:"false"
Include the request hostname when caching OpenGraph tags.
TimeToLive
time.Duration
Duration to cache OpenGraph tags (e.g., "5m", "1h", "24h").
Override
map[string]string
Custom OpenGraph tags to inject. Keys are tag names (e.g., "og:title").Required tags when using overrides:
  • "og:title" - Page title

Example

openGraph:
  enabled: true
  considerHost: true
  ttl: "1h"
  override:
    og:title: "My Protected Site"
    og:description: "Protected by Anubis"
    og:image: "https://example.com/og-image.png"

Complete Configuration Example

store:
  backend: valkey
  parameters:
    address: "localhost:6379"
    db: 0
    poolSize: 20

status_codes:
  CHALLENGE: 429
  DENY: 403

dns_ttl:
  forward: 300
  reverse: 300

logging:
  sink: file
  parameters:
    file: "./var/anubis.log"
    maxBackups: 3
    maxBytes: 104857600
    maxAge: 7
    compress: true
    useLocalTime: false

openGraph:
  enabled: true
  ttl: "30m"
  override:
    og:title: "Protected Site"

bots:
  # Bot rules here...

Build docs developers (and LLMs) love