apiward

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

README

APIWard

A lightweight security policy gateway for REST APIs, written in Go.

It checks every request against one policy before forwarding it. One binary: HTTP server, reverse proxy, database and admin Dashboard.

Features

  • JWT authentication: RS256 tokens from your identity provider
  • Role-based access control, plus an instant blocked-accounts list
  • Rate limiting: sliding window, per account or per client address
  • Request validation: JSON body and headers against a JSON Schema
  • Security log: a request is forwarded only after its record is on disk
  • Default deny: a request that fails any check never reaches an API
  • Safe policy changes: a new policy runs on trial and rolls back unless confirmed
  • Dashboard and Admin API, on a loopback-only listener
  • Per-API options: path rewrite, host and header conditions, CORS, response headers, address allow lists, TLS to upstreams
  • Signed identity: upstreams can verify that a request passed the gateway
  • OpenAPI import and export
  • Embeddable in a Go program; custom checks as compile-time modules
  • No external services: one SQLite file; Prometheus metrics, /livez, /readyz

Quick start

Run the Fetch demonstration: a shop with five APIs behind the gateway.

Requires Go 1.26+ and Node.js 24.

git clone https://github.com/Alex-Zechariah-02/apiward
git clone https://github.com/Alex-Zechariah-02/fetch
cd fetch
go run ./cmd/demo up
Open Address
Dashboard http://127.0.0.1:9440/
Shop, through the gateway http://127.0.0.2:9480/
Metrics http://127.0.0.1:9450/metrics

Build

Requires Go 1.26+ (go.mod selects the 1.27.4 toolchain).

Gateway only:

go build -trimpath -o apiward ./cmd/apiward

With the Dashboard inside the binary (also requires Node.js 24):

cd dashboard && npm ci && npm run build && cd ..
rm -rf internal/adminui/dist && cp -r dashboard/dist internal/adminui/dist
go build -trimpath -tags embedui -o apiward ./cmd/apiward

Container image (docs/container.md):

docker build -t apiward:dev .

Run

apiward install --config apiward.json --admin <name>
apiward run --config apiward.json
  1. install prints a one-time enrolment secret. Keep it private.
  2. Open the Dashboard and choose First Sign-In with an Enrolment Secret.
  3. Establish the first policy. Until then the gateway forwards nothing.

The settings file is described in docs/settings.md.

Command Purpose
run Run the gateway
install Create the first administrator
enrol Add or reset an administrator
backup, restore Back up or restore the database
migrate Upgrade a database from an earlier version
health Exit 0 when the gateway is ready
jwks Print the public key of the signed identity
policy import-openapi Make a policy file from an OpenAPI description
policy export-openapi Write one API of a policy as OpenAPI
version Print the version and compiled-in checks
  • All commands except version and policy take --config <file>.
  • Stop the gateway before install, enrol, backup, restore or migrate.

How it works

  • Policy: one document lists upstreams, APIs, operations, roles and permits.
  • Request path: ingress checks → route → token → roles → rate limit → validation → security log → forward. The first failing stage answers.
  • One version per request: a request is decided against exactly one policy version and forwarded once.
  • Policy changes: a new policy is provisional until confirmed; unconfirmed, the previous one returns. Temporary overrides expire by themselves.
  • Identity: the gateway verifies tokens and never issues them. Upstreams receive the verified account and roles.
  • Listeners:
    • data: your APIs
    • admin: Dashboard and Admin API, loopback only
    • metrics: Prometheus, /livez, /readyz
  • Storage: one SQLite database. Requests read in-memory snapshots, never the database.

Documentation

Page Contents
docs/policy.md Policy document and policy changes
docs/settings.md Settings file
docs/openapi.md OpenAPI import and export
docs/embedding.md Embedding and modules
docs/container.md Container image
docs/development.md Code layout, builds, checks
docs/dashboard.md Dashboard pages and behaviour
dashboard/README.md Dashboard build and tests

Tests

go mod verify
gofmt -l $(git ls-files '*.go')
go vet ./...
go vet -tags faultinject ./...
go test ./... -count=1
  • gofmt -l must print nothing.
  • The stack tests need Fetch checked out as ../fetch.
  • EAT_PORT_OFFSET (for example 1000) moves every test port.

Not covered

The full OWASP API Security Top 10, distributed deployments, Kubernetes, automatic certificates (ACME).

Licence

Apache-2.0 (LICENSE). Third-party components: THIRD_PARTY_NOTICES.

Documentation

Overview

Package apiward runs the APIWard security gateway inside a Go program.

The host program owns the data-plane listener and mounts the gateway's handler on its own server, at the root or under a prefix with http.StripPrefix. The gateway keeps everything else: its Admin API and metrics listeners, its database, its audit log, startup recovery and its stop. Every request the handler receives runs the full pipeline the standalone binary runs; nothing here publishes policy or skips a stage.

A gateway is loaded, opened, started once and stopped once:

cfg, err := apiward.LoadConfig(path)
gw, err := apiward.New(cfg, logger)
err = gw.Start()
mux.Handle("/api/", http.StripPrefix("/api", gw))
gw.ServerSettings().Apply(server)
...
err = gw.Stop(ctx)

The host must apply ServerSettings to its server (header size and timeouts bound slow and oversized clients; the HTTP/1 and HTTP/2 protocols and HTTP/2 stream limits are set too) and must not rewrite a request's RemoteAddr from client-supplied headers: address lists and per-address rate limits read it.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrConfig     = core.ErrConfig     // the configuration, or a file it names, is refused
	ErrLocked     = core.ErrLocked     // another process holds the deployment
	ErrStorage    = core.ErrStorage    // the database or the audit log cannot be used
	ErrListen     = core.ErrListen     // the admin or metrics address cannot be bound
	ErrStarted    = core.ErrStarted    // Start was called again
	ErrStopped    = core.ErrStopped    // Start was called after Stop
	ErrIncomplete = core.ErrIncomplete // Stop could not finish every step in time
)

Kinds of failure. Every error from LoadConfig, New, Start and Stop matches exactly one with errors.Is; its text names the setting or file involved. Request refusals are HTTP responses, never Go errors.

Functions

This section is empty.

Types

type Config

type Config = core.Settings

Config is a configuration file checked as the standalone binary's run command checks it. Only LoadConfig makes one; New refuses the zero value. The file's data.listen is still required and checked, but a gateway run here never binds it.

func LoadConfig

func LoadConfig(path string) (Config, error)

LoadConfig reads and strictly checks the configuration file at path.

type Gateway

type Gateway = core.Embedded

Gateway is one running gateway; it is the data plane's http.Handler. Before Start completes and from Stop on, every request is refused with 503 gateway_unavailable and recorded. Its methods are safe for concurrent use.

func New

func New(cfg Config, logger *slog.Logger) (*Gateway, error)

New opens the deployment cfg names: it takes the deployment lock, opens the database and the audit log and recovers the stored authority. It binds no listener; Start does. When it fails, nothing stays open.

type ServerSettings

type ServerSettings = core.ServerSettings

ServerSettings are the configured limits for the host's server; Apply sets them.

Directories

Path Synopsis
cmd
apiward command
Command apiward runs the security policy gateway on its own Go HTTP server, from one strict native configuration file, and its local operator commands.
Command apiward runs the security policy gateway on its own Go HTTP server, from one strict native configuration file, and its local operator commands.
testfixture command
Command testfixture runs one controlled API used by gateway regression tests (orders, inventory or reports) on a loopback address.
Command testfixture runs one controlled API used by gateway regression tests (orders, inventory or reports) on a loopback address.
examples
embed command
Command embed is a small host program that runs the gateway inside itself: it serves its own page at / and mounts the gateway at /api/, so every API request passes the gateway's checks before it reaches the upstream the policy binds.
Command embed is a small host program that runs the gateway inside itself: it serves its own page at / and mounts the gateway at /api/, so every API request passes the gateway's checks before it reaches the upstream the policy binds.
internal
admin
Package admin is the Admin API: its routes, administrator authentication and sessions, the Host, Origin and CSRF checks, the sign-in throttle, password hashing, the status, history, monitoring and security log reads, and the handlers that ask the controller for changes.
Package admin is the Admin API: its routes, administrator authentication and sessions, the Host, Origin and CSRF checks, the sign-in throttle, password hashing, the status, history, monitoring and security log reads, and the handlers that ask the controller for changes.
adminui
Package adminui holds the Dashboard's built files for a release build.
Package adminui holds the Dashboard's built files for a release build.
audit
Package audit is the gateway's durable security log: one JSON record per request decision, administrator action and log event, appended to rotating files and synced to disk.
Package audit is the gateway's durable security log: one JSON record per request decision, administrator action and log event, appended to rotating files and synced to disk.
compile
Package compile turns a policy document into an immutable generation: the route table, permits, rate rules and compiled body and header schemas that every request is decided against.
Package compile turns a policy document into an immutable generation: the route table, permits, rate rules and compiled body and header schemas that every request is decided against.
controller
Package controller is the only authority that changes what the gateway enforces: it owns the database and the audit log of a deployment, compiles policy generations and publishes them, runs Confirmed Policy Activation and Temporary Policy Overrides with their deadlines and startup recovery, and publishes trust keys, blocked accounts and blocked addresses.
Package controller is the only authority that changes what the gateway enforces: it owns the database and the audit log of a deployment, compiles policy generations and publishes them, runs Confirmed Policy Activation and Temporary Policy Overrides with their deadlines and startup recovery, and publishes trust keys, blocked accounts and blocked addresses.
demoports
Package demoports applies the process's EAT_PORT_OFFSET to fixed local demonstration addresses.
Package demoports applies the process's EAT_PORT_OFFSET to fixed local demonstration addresses.
fault
Package fault holds the fault-injection points that tests use to crash, delay or fail the gateway at exact places.
Package fault holds the fault-injection points that tests use to crash, delay or fail the gateway at exact places.
forward
Package forward sends an admitted request to the one upstream it is bound to, through the standard library's reverse proxy, and names what a failed exchange means for the gateway's answer.
Package forward sends an admitted request to the one upstream it is bound to, through the standard library's reverse proxy, and names what a failed exchange means for the gateway's answer.
gateway
Package gateway is the security policy gateway: its HTTP server and reverse proxy, the request pipeline that applies the five security controls (token verification, role permits, rate limits, request validation and the security event log), the policy compiler and controller with confirmed policy activation and temporary overrides, the SQLite store, the protected Admin API and the local operator commands.
Package gateway is the security policy gateway: its HTTP server and reverse proxy, the request pipeline that applies the five security controls (token verification, role permits, rate limits, request validation and the security event log), the policy compiler and controller with confirmed policy activation and temporary overrides, the SQLite store, the protected Admin API and the local operator commands.
gatewaytest
Package gatewaytest is the test harness for the gateway: it builds the gateway, fixture and demo programs once per test binary, runs each test's gateway as its own process with a disposable deployment (database, security log, configuration file, listeners and upstream receivers), and gives tests clients for the data plane and the Admin API, readers for the security log and the database, and the policies the tests share.
Package gatewaytest is the test harness for the gateway: it builds the gateway, fixture and demo programs once per test binary, runs each test's gateway as its own process with a disposable deployment (database, security log, configuration file, listeners and upstream receivers), and gives tests clients for the data plane and the Admin API, readers for the security log and the database, and the policies the tests share.
issuertest
Package issuertest is the token issuer tests stand in for: it generates an RSA signing key in memory for each run, never writes it anywhere, and signs the tokens the gateway's verifier is tested against.
Package issuertest is the token issuer tests stand in for: it generates an RSA signing key in memory for each run, never writes it anywhere, and signs the tokens the gateway's verifier is tested against.
monitor
Package monitor observes the gateway without deciding anything: the bounded window of recent requests and its live views, request metrics, traffic summaries, the fixed advice checks, impact previews and the security log search.
Package monitor observes the gateway without deciding anything: the bounded window of recent requests and its live views, request metrics, traffic summaries, the fixed advice checks, impact previews and the security log search.
openapi
Package openapi turns an OpenAPI 3.0 or 3.1 description, in JSON or YAML, into a candidate policy document and a report of what it mapped, assumed, changed and refused.
Package openapi turns an OpenAPI 3.0 or 3.1 description, in JSON or YAML, into a candidate policy document and a report of what it mapped, assumed, changed and refused.
operator
Package operator runs the gateway's local operator commands: install, enrol, migrate, backup and restore.
Package operator runs the gateway's local operator commands: install, enrol, migrate, backup and restore.
pipeline
Package pipeline is the data-plane request pipeline: it decides every request against the one generation it captures and forwards only a request that passed every stage, after its audit record is durable.
Package pipeline is the data-plane request pipeline: it decides every request against the one generation it captures and forwards only a request that passed every stage, after its audit record is durable.
policy
Package policy defines the policy document an administrator writes: its types, its strict JSON decoding and the limits and identifier formats every policy must meet.
Package policy defines the policy document an administrator writes: its types, its strict JSON decoding and the limits and identifier formats every policy must meet.
session
Package session holds the administrator sessions of the Admin API in memory and makes the random tokens the Admin API and the operator commands hand out.
Package session holds the administrator sessions of the Admin API in memory and makes the random tokens the Admin API and the operator commands hand out.
store
Package store is the gateway's one authoritative database: policy versions, draft changes and trials, temporary rules, blocked accounts, administrators and the durable receipt of every change, in SQLite with write-ahead logging.
Package store is the gateway's one authoritative database: policy versions, draft changes and trials, temporary rules, blocked accounts, administrators and the durable receipt of every change, in SQLite with write-ahead logging.
storetest
Package storetest is test support only, never imported by production code: it seeds a disposable gateway database whose confirmed revision is a given policy, optionally with a provisional revision and its deadline and an administrator, reads single values back for assertions, and builds the small test policies the seeds use.
Package storetest is test support only, never imported by production code: it seeds a disposable gateway database whose confirmed revision is a given policy, optionally with a provisional revision and its deadline and an administrator, reads single values back for assertions, and builds the small test policies the seeds use.
testfixture
Package testfixture implements the three controlled REST APIs that sit behind the gateway in its security, proxy, concurrency and crash regressions: orders, inventory and reports.
Package testfixture implements the three controlled REST APIs that sit behind the gateway in its security, proxy, concurrency and crash regressions: orders, inventory and reports.
Package module is the contract for controls compiled into the gateway binary.
Package module is the contract for controls compiled into the gateway binary.
Package policy is the policy document an administrator writes for the gateway: its types, strict decoding, the canonical encoding (one byte form per meaning, so two policies compare byte for byte) and an offline check of how a policy decides a described request.
Package policy is the policy document an administrator writes for the gateway: its types, strict decoding, the canonical encoding (one byte form per meaning, so two policies compare byte for byte) and an offline check of how a policy decides a described request.

Jump to

Keyboard shortcuts

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