• v3.0.0-rc1 d5f7ddc770

    Activity-Relay 3.0.0-rc1
    All checks were successful
    Container / Container and Caddy validation (push) Successful in 47s
    Debian Package / Debian package validation (push) Successful in 2m27s
    Test / Go, Redis, and Python validation (push) Successful in 2m9s
    Pre-release

    alan released this 2026-09-01 18:01:36 +00:00 | 28 commits to master since this release

    Activity-Relay v3.0.0-rc1

    • Application version: 3.0.0-rc1
    • Debian package version: 3.0.0~rc1-1

    Important

    This is the first Activity-Relay 3.0 release candidate. It is intended for
    controlled interoperability and Directory integration testing, not stable
    production promotion. The omitted/default outbound signature profile remains
    legacy until the mixed-profile interoperability gate is complete.

    Summary

    Activity-Relay 3.0 modernizes HTTP message authentication, adds explicit
    destination-aware signature negotiation, introduces a configurable public
    address-distribution policy, and adds the opt-in Activity-Relay Directory v1
    client and lifecycle scheduler.

    The release candidate preserves the existing relay actor ID, #main-key
    identity, Redis deployment model, existing subscription state, and the legacy
    outbound-signature default. Automatic Directory lifecycle behavior is disabled
    unless both a Directory entry and the lifecycle scheduler are explicitly
    enabled; manual lifecycle commands remain explicit operator actions.

    HTTP message signatures

    3.0 RC1 adds RFC 9421 HTTP Message Signatures and RFC 9530 Content-Digest
    alongside the established Fediverse Signature/Digest profile.

    Inbound requests with Signature-Input are verified through the modern
    profile with bounded time validation, actor/key binding, digest verification,
    Redis-backed nonce replay protection, and bounded metrics. Requests without
    Signature-Input continue through the legacy verifier; malformed modern
    requests do not fall back to legacy verification.

    OUTBOUND_SIGNATURE_PROFILE accepts:

    • legacy for the established wire profile;
    • rfc9421 for fixed modern signing; and
    • dual for destination-aware selection.

    dual keeps fetch and delivery evidence separate. Unknown authenticated GETs
    start with RFC 9421 and may make one bounded legacy fallback only after
    recognized compatibility evidence. Delivery POSTs never fall back or get
    re-sent under another signature grammar. New queued deliveries persist the
    selected concrete wire profile across delayed retries, while old two-argument
    tasks remain readable.

    The RC1 default remains legacy. Selecting the stable 3.0 default is explicitly
    deferred until the mixed Mastodon, Friendica, NodeBB, WordPress, and two-relay
    interoperability matrix is complete.

    Public address distribution

    PUBLIC_ADDRESS_DISTRIBUTION_POLICY accepts:

    • explicit_public_only; or
    • public_and_unlisted.

    Fresh example configurations select explicit_public_only, where ActivityStreams
    Public must appear in the primary to audience for public fan-out. Public only
    in cc remains acknowledged and publisher-accounted without relay fan-out.

    For upgrade compatibility, an omitted value retains the pre-3.0
    public_and_unlisted behavior. Operators upgrading an existing deployment
    should set the desired value explicitly.

    /status.json schema version 5 exposes the effective policy and human-readable
    label, and the generated website presents the effective policy.

    Activity-Relay Directory client

    The opt-in Directory v1 client supports up to eight independently enabled
    canonical HTTPS Directory origins and provides:

    • relay directory status;
    • relay directory register;
    • relay directory heartbeat;
    • relay directory unregister; and
    • relay directory sync.

    Lifecycle requests use the Directory-specific RFC 9421/RFC 9530 profile with
    strict bounded responses and redirect refusal.

    The API-process scheduler is disabled by default. When explicitly enabled it
    reconciles startup state, schedules stable-jittered heartbeats, persists closed
    state, applies bounded retry including validated Retry-After, and coordinates
    with manual unregister through renewable Redis leases and fencing tokens.
    Workers do not schedule Directory traffic.

    File-backed unregister durably disables the selected entry before network
    traffic, preserves unrelated YAML and file metadata, and retains a recoverable
    backup.

    Compatibility and upgrade notes

    The RC1 preparation does not rotate actor.pem, change the relay actor ID,
    change the #main-key key ID, require a Redis data migration, or invalidate
    existing subscription state.

    Existing configurations that omit OUTBOUND_SIGNATURE_PROFILE continue to use
    legacy. Existing configurations that omit PUBLIC_ADDRESS_DISTRIBUTION_POLICY
    continue to use public_and_unlisted. Directory configuration remains empty
    and its scheduler remains false by default.

    The new delivery task carries a concrete signature-profile argument, but workers
    remain compatible with previously queued two-argument tasks.

    NodeBB 4.15.1 retest gate

    Activity-Relay 2.5 validation found that NodeBB 4.14.x could accept a signed
    relay delivery and then fail with HTTP 424 because its application-context
    canonical-object fetch was unsigned when the remote object required authorized
    fetch.

    NodeBB upstream changed that path in commit
    8e61543b0ae19fd741bd4175d478aab6c79982ca, restoring key loading and signing
    for application actor ID 0. RC1 acceptance requires a fresh NodeBB 4.15.1
    retest.

    If the retest still fails, retain NodeBB's outgoing Date, Signature, and
    keyId so the remaining failure can be classified as key
    discovery/interoperability rather than missing request signing.

    RC1 validation and promotion gates

    Before creating tag v3.0.0-rc1:

    1. run the normal Forgejo source, race, Python, package, Caddy, and container
      validation on the exact preparation commit;
    2. run Canonical Release Candidate Artifacts with the exact full commit,
      version 3.0.0-rc1, and confirmation BUILD 3.0.0-rc1;
    3. inspect the retained Debian, CycloneDX SBOM, multi-architecture OCI,
      checksum, Lintian, build-metadata, and OCI-index evidence; and
    4. prove that accepted artifact bytes can be published without rebuilding them.

    After tagging and publishing the accepted RC1 bytes:

    1. deploy the accepted RC1 application code first to relay2.argentwolf.org;
    2. retest NodeBB 4.15.1 and the mixed Mastodon, Friendica, NodeBB, and WordPress
      paths;
    3. upgrade relay.argentwolf.org to the accepted 3.0 RC code; and
    4. exercise both relays against directory.argentwolf.org, including
      registration, heartbeat, scheduler restart, unregister/re-register, public
      projection, and the existing two-relay no-reflection invariant.

    These deployment and interoperability checks are gates for stable v3.0.0
    promotion, not for creating the RC1 tag itself. A runtime/default-policy change
    discovered during this testing requires another release candidate rather than
    stable promotion.

    Repository and release authority

    Forgejo at forgejo.argentwolf.org/alan/activity-relay is the repository, CI,
    and release authority. GitHub remains the downstream public mirror and
    independent validation surface.

    The RC tag must not be created until the canonical Forgejo artifact gate has
    passed and the exact accepted artifact bytes have been identified. Passing the
    candidate build is not itself publication or deployment.

    Downloads