No description
Find a file
2026-04-15 19:02:22 +02:00
data/config/oauth Wire OAuth 2.0 routes in main.go - implementation complete 2026-03-25 07:29:49 +01:00
DOC deploy: add split-domain and traefik examples 2026-04-10 14:16:45 +02:00
internal feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
releases build: add release packaging workflow 2026-04-08 22:10:43 +02:00
scripts feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
static/assets feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
tools ops: separate s2s retry queues and workers 2026-04-10 16:38:29 +02:00
.dockerignore chore: add container build and traefik compose example 2026-03-27 17:00:44 +01:00
.env.example feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
.gitignore feat: enforce admin federation policies and filters 2026-04-08 18:20:08 +02:00
api.go hardening: tighten storage and oauth handling 2026-04-09 11:38:36 +02:00
docker-compose.yml feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
Dockerfile chore: add container build and traefik compose example 2026-03-27 17:00:44 +01:00
go.mod feat: enforce admin federation policies and filters 2026-04-08 18:20:08 +02:00
go.sum feat: enforce admin federation policies and filters 2026-04-08 18:20:08 +02:00
INSTALL.md feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
LICENSE.txt docs: prepare beta-0.9.000 release 2026-04-08 21:13:25 +02:00
main.go refactor: enforce auditable EAL contracts across Go codebase 2026-03-26 13:14:24 +01:00
Makefile ops: add backup restore and docker smoke tooling 2026-04-10 14:01:39 +02:00
models.go refactor: remove libp2p runtime and define http-first s2s roadmap 2026-04-01 17:28:46 +02:00
oauth.go hardening: tighten storage and oauth handling 2026-04-09 11:38:36 +02:00
oauth_test.go API Cleaning 2026-03-29 18:05:47 +02:00
README.md feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
ROADMAP.md docs: update backend roadmap sequencing 2026-04-01 17:40:50 +02:00
routes_protected_core.go feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
routes_protected_core_test.go feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
routes_public.go feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
routes_public_test.go feat: add admin-managed registration approvals 2026-04-15 19:02:22 +02:00
routes_status_timeline.go feat: add protected v2 statuses create alias 2026-03-27 17:57:10 +01:00
routes_status_timeline_test.go refactor: remove libp2p runtime and define http-first s2s roadmap 2026-04-01 17:28:46 +02:00
server.go feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
server_test.go feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
SPEC.md feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00
startup.go ops: separate s2s retry queues and workers 2026-04-10 16:38:29 +02:00
startup_test.go ops: add startup self-check and queue inspection 2026-04-10 11:51:46 +02:00
STATUS.md feat: bootstrap sole admin from env 2026-04-15 13:29:21 +02:00

Aktor

Aktor is a headless, Mastodon-compatible ActivityPub server.

It is meant to be used through existing clients such as Tusky on mobile, and web clients such as Elk or Pinafore on desktop. The goal is not to build yet another full web-social frontend first, but to provide a deployable federated backend with a clear architecture, strong compatibility goals, and operational simplicity.

Why another fediverse server?

Part of the answer is political in the most basic sense: this project refuses to make ideological alignment a prerequisite for technical cooperation. I do not want to build software inside environments where political identity matters more than code quality, compatibility, or operational honesty.

There is also a technical answer.

Many existing fediverse servers are tightly shaped by assumptions that do not fit the deployment model I want:

  • heavy dependence on databases, often with operational expectations that become awkward on shared storage
  • frequent reliance on commercial object storage or CDN patterns while presenting an anti-centralization narrative
  • weak treatment of private-message confidentiality despite strong rhetoric about surveillance and censorship

Aktor is an attempt to make different choices.

Current direction

The project is moving in phases.

Phase 1: compatibility first

The first goal is compatibility with other fediverse software, starting from practical interoperability with systems such as snac2, GoToSocial, and eventually Mastodon itself.

This phase is intentionally conservative. The point is not to invent a new social protocol. The point is to be usable.

Some design choices already visible in Aktor:

  • A separate instance vanity name, so the public instance name is not forced to be the same thing as the network address.
  • A link_only federation policy mode for remote instances. This keeps the existence of remote posts visible while replacing hosted content with a link to the original post, for operators who do not want to mirror potentially illegal or high-risk content locally.
  • No SQL database requirement. Aktor avoids depending on SQLite, PostgreSQL, or similar systems as a hard architectural assumption, because shared-storage deployments over NFS can make that painful or outright unreliable.

Phase 2: decentralized media delivery

Many fediverse deployments speak about decentralization while ultimately relying on commercial object storage or CDN infrastructure.

Aktor aims to offer a different path. In a later phase, the intention is to support media delivery through IPFS for operators who want a two-service stack and a less centralized content-distribution model. If IPFS proves insufficient for some use cases, BitTorrent-style distribution remains a possible future direction.

The guiding idea is simple: if the project claims to care about decentralization, it should not default to handing all media distribution to large centralized platforms.

Phase 3: private-message confidentiality

Private messaging across the fediverse is still far too easy to intercept or inspect at the server level.

Aktor already carries PGP-oriented key material in its architecture, and the long-term goal is to use that foundation to improve private-message confidentiality. In a later phase, an additional transport such as I2P is intended to be explored for deployments that want stronger resistance to interception.

No, the current plan is not to rely on Tor by default.

Current status

Aktor already provides:

  • Mastodon-compatible C2S APIs aimed at existing clients
  • working S2S federation flows for the current beta scope
  • a lightweight admin surface with YAML-backed persistent instance configuration
  • configurable federation policy enforcement
  • embedded Lua-based inbound message filters
  • no mandatory SQL database

This is still active software under development, but it is no longer just a sketch.

Admin and federation policy

The current beta includes an admin model built around one sole administrator:

  • the sole admin is bootstrapped at startup from AKT_BOOTSTRAP_ADMIN_USERNAME and AKT_BOOTSTRAP_ADMIN_PASSWORD
  • public registration no longer auto-promotes any newly created account to admin
  • admin-managed instance state is persisted in YAML
  • the admin can manage:
    • instance icon
    • instance description
    • Terms of Service
    • public admin contact
    • banned instances
    • limited instances
    • inbound Lua filter pipeline

Federation restriction modes currently include:

  • text_only
  • link_only
  • follow_required
  • mutual_follow_required
  • deny_all

Inbound filters are executed sequentially inside the async S2S processor through an embedded Lua runtime, with timeout enforcement and no dependency on external interpreters in Docker images.

Build and test with make

The repository ships with a Makefile. These are the main targets:

make help
make build
make run
make dev
make test
make fmt
make fmt-check
make lint
make sec
make audit-eal
make qa
make curl-test
make prepush-check
make releases VERSION=beta-0.9.001
make publish-releases VERSION=beta-0.9.001
make release-clean VERSION=beta-0.9.001
make tidy
make vendor

What they do:

  • make build: build the aktor binary
  • make run: build and run the server
  • make dev: run the server directly with go run .
  • make test: run the repository test sweep
  • make fmt: format the code with gofumpt
  • make fmt-check: fail if formatting is not clean
  • make lint: run golint
  • make sec: run gosec
  • make audit-eal: check EAL-style contract comments and auditability rules
  • make qa: run formatting, lint, security checks, EAL audit, and tests
  • make curl-test: build Aktor, boot an ephemeral server, and run the live curl smoke suite
  • make prepush-check: run the full pre-push validation path used in active development
  • make releases: cross-build common real-world targets and write releases/<version>/aktor_<version>_GOOS_GOARCH.tgz
  • make publish-releases: commit and push an already generated releases/<version>/ folder
  • make release-clean: remove a generated releases/<version>/ folder
  • make tidy: run go mod tidy
  • make vendor: regenerate vendor/

If you only want one command before a commit or deploy candidate, use:

make prepush-check

Quick start

For installation and environment setup, start with:

Typical local workflow:

make build
./aktor

Or:

make dev

If you want to exercise the live smoke suite:

make curl-test

Documentation

The main project documents are:

  • INSTALL.md: installation and environment setup
  • SPEC.md: persistent functional and architectural requirements
  • ROADMAP.md: project direction and milestone ordering
  • STATUS.md: implementation progress log
  • DOC: reference material, including external compatibility references
  • DOC/deploy: reverse-proxy and split-domain deployment examples for Caddy, Nginx, and Traefik

Deployment notes

Aktor is being shaped so it can be deployed in practical environments without assuming a heavyweight database stack from day one.

The long-term target is a stack that can be deployed with:

  • docker-compose
  • Docker Swarm
  • Kubernetes / Helm

Potential future companion services may include:

  • IPFS for media distribution
  • I2P for harder-to-intercept communication paths

Those are roadmap goals, not statements that every part is complete today.

Philosophy

Aktor tries to be honest about infrastructure, honest about compatibility, and honest about operator control.

That means:

  • compatibility before novelty
  • simple deployment over fashionable architecture
  • explicit moderation and federation controls
  • no fake decentralization story built on opaque commercial dependencies
  • security and auditability as engineering concerns, not marketing language

License and contribution style

If you are evaluating the project, the safest current assumption is:

  • read the spec first
  • run the checks locally
  • treat compatibility and tests as mandatory, not optional

The project follows a spec-first, test-heavy workflow with EAL5+-inspired discipline around contracts, invariants, and reviewability.

Credits

  • GoToSocial, for the Swagger / OpenAPI reference used while aligning API behavior and compatibility expectations
  • snac2, for serving as a reference point during the first implementation phase
  • Mastodon, for the API documentation that helped guide compatible endpoint behavior