Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Federation and audiences

An audience answers two questions: what version of an event may leave this node, and who may receive it? Every new local mutation is projected into each audience named by federation.default_audiences.

Important

Selected audiences are parallel outputs, not layers of access control. If public and neighbors are both selected, the public representation remains public. A restricted representation does not make fields in the public representation private. Evaluate the most permissive selected audience when explaining the policy to flock members.

Public federation

The default configuration selects one public audience:

[federation]
default_audiences = ["public"]

[federation.audiences.public]
transport = "public"

Public events are signed by the flock and readable by anyone with relay access. The public projection uses exact timestamps, includes notes, tags, media, and all extensions, and excludes location.

Restricted federation

Restricted audiences sign a projected inner event and encrypt a separate NIP-59 gift wrap for each recipient.

[federation]
default_audiences = ["public", "neighbors"]

[federation.audiences.public]
transport = "public"

[federation.audiences.neighbors]
transport = "restricted"
recipients = [
  "<cerulean-public-key>",
  "<sunyshore-public-key>",
]
allowed_senders = [
  "<cerulean-public-key>",
  "<sunyshore-public-key>",
]

[federation.audiences.neighbors.projection]
observed_at_precision = "day"
publication_delay_seconds = 3600
notes = false
tags = true
location = false
media = false
extensions = ["fyi.birdd.birds/count"]

recipients and allowed_senders are intentionally independent. Recipients receive your events. Allowed senders may send events into that audience. A restricted audience can be outbound-only by leaving allowed_senders empty. These lists do not inherit from the trust database.

What leaves the node

Use this matrix when describing the active policy to operators and flock members. It covers observation content, not all federation protocol metadata:

Observation dataPublicRestricted
SubjectAlways includedAlways included
Observation IDAlways includedAlways included
Event creation timeExactExact
Observed timeExactExact, hour, or UTC day
NotesIncludedConfigurable
TagsIncludedConfigurable
LocationOmittedConfigurable
Media referencesIncludedConfigurable
ExtensionsAll envelopesAll or an explicit allowlist

Timestamp precision changes observed_at, not the exact event creation time. Publication delay does not hide that creation time after delivery.

Restricted encryption hides projected content from relays, but not all traffic metadata. A relay can see the recipient key on each gift wrap and when encrypted messages are published. After decryption, a recipient learns the sender key, audience name, sequence, policy epoch, and revision identity in addition to the projected observation.

A media reference identifies an object but does not make the media bytes public. Fetching media requires a signed request from a flock directly trusted by the media’s origin. Restricted media access additionally requires a published representation that disclosed the reference to that recipient.

Extension allowlists include the complete envelope for each selected extension ID. Review the extension’s schema and actual values; an innocent-looking column name does not guarantee that the envelope contains no other sensitive keys. A local extension manifest is not a projection filter; see Extensions.

Corrections and deletions follow the selected audiences too. A deletion updates the current state on conforming nodes but cannot force relays or prior recipients to erase copies. Recipients can also retain or redistribute decrypted restricted data.

Projection controls

A restricted projection can:

  • Reduce observation timestamps to the start of an hour or UTC day
  • Delay publication for up to one year
  • Remove notes, tags, location, or media
  • Include all extensions or an explicit allowlist of extension IDs

The subject and observation identity are always included. Public audiences use the default projection and cannot customize these controls.

An enabled field is preserved only when present on an observation. In particular, current local create and correction commands do not accept location, even though restricted projection policy has a location control.

Preview the current projection of a locally owned observation without publishing it:

birdd --config birdd.toml federation-preview <observation-id>

Preview representative observations containing notes, tags, location, media, and every installed extension. Do not preview only an empty test observation.

Choose a privacy posture

Open public sharing

Use the default public audience only when members understand that observation subjects, exact times, notes, tags, media references, and every extension are publicly readable:

[federation]
default_audiences = ["public"]

[federation.audiences.public]
transport = "public"

Public projections cannot be reduced. If any of those fields should be limited to named flocks, remove public from default_audiences and use a restricted audience instead.

Named recipients with full detail

Select only a restricted audience to preserve the normal observation detail while limiting relay-readable content and delivery to named recipient keys:

[federation]
default_audiences = ["neighbors"]

[federation.audiences.neighbors]
transport = "restricted"
recipients = [
  "<cerulean-public-key>",
  "<sunyshore-public-key>",
]
allowed_senders = []

The default restricted projection still sends exact observed times, notes, tags, media references, and every extension. It omits location. Encryption limits delivery but does not minimize what recipients learn.

Leaving allowed_senders empty makes this audience outbound-only. Add keys only for flocks whose restricted events this node should accept; this does not happen automatically when a key is a recipient or is directly trusted.

Minimized and delayed sharing

For sensitive observations, reduce the data before encryption and delay its release:

[federation]
default_audiences = ["regional-summary"]

[federation.audiences.regional-summary]
transport = "restricted"
recipients = ["<regional-coordinator-public-key>"]
allowed_senders = []

[federation.audiences.regional-summary.projection]
observed_at_precision = "day"
publication_delay_seconds = 86400
notes = false
tags = false
location = false
media = false
extensions = ["fyi.birdd.birds/count"]

This sends the subject, observation ID, exact event creation time, day-level observed time, and the count envelope when present. It does not provide full anonymity: subjects and creation times can still be identifying.

The extension projection must be ["*"] or a non-empty allowlist. There is no explicit deny-all setting. An allowlist containing a reserved namespaced ID that the node never writes, such as invalid.example/not-installed, effectively omits current extensions, but would disclose that ID if it were ever added to an observation. Treat this as a workaround and audit it when installing extensions.

Different policies for different recipients

Define multiple restricted audiences when recipient groups should receive different projections, then select all of them in default_audiences. A recipient key can belong to only one restricted audience, so groups cannot overlap.

Every local observation and later correction or deletion goes to every selected audience. Users cannot select an audience per observation. There is no local-only audience transport. Leaving the relay list empty only postpones delivery: selected representations remain stored and can publish if relays are configured later. A durable “never federate” policy therefore requires a separate operationally isolated deployment and is not enforced by the current audience model.

Changing policy

Projection, transport, and recipient changes create a new stream policy epoch. Pending deliveries made obsolete by the new policy are marked suppressed; already published events cannot be recalled.

Warning

Adding an audience does not backfill existing history. An older observation without a representation for every currently selected audience cannot be corrected or deleted. birdd reports that explicit backfill is required, but this MVP does not yet include a backfill command.

Inspect stream positions, missing sequences, conflicts, manifests, and restricted delivery queues with:

birdd --config birdd.toml federation-status --json

Restricted delivery states are delayed, due, wrapped, published, and suppressed. See Node configuration for every audience option.