Skip to content

Choosing Your Directory Setup

Not sure which Directory setup you need? Walk through the questions below, then find the matching configuration — each shown as its own topology.

  1. Who needs to discover your records? Only you → keep going · your team or organization → Networked · other organizations → Federated.
  2. (Only you) Should others be able to pull them from a public registry? No → Private · Yes → Public-store.

The configurations below cover the useful combinations. In every diagram dashed lines mean discovery (only CIDs/labels move), solid lines mean retrieval (record bytes move).

Private node

Keep records to yourself. Store locally, no network.

You store, search, sign, and pull locally. You can still pull records inbound, both from a public registry and from a remote Directory node you authenticate to.

What stays true either way: nobody else can discover or retrieve your records.

flowchart LR
  user(["You · dirctl"]) -->|"push · search · pull"| api
  user -->|"🔑 logged in"| peer
  subgraph node["Your node"]
    api["API server"] --> store[("Local store<br/>not network-reachable")]
  end
  reg[("Public OCI registry")] -->|"sync create --registry"| api
  peer["Remote Directory node"] -->|"sync create"| api

Choose when:

  • Discovery = only you
  • Store = bundled/local

See Local Deployment for more details.

Public-store node

Let others retrieve, without a network.

The store is a public registry (GHCR, Docker Hub). Anyone who knows the registry can pull records straight from it — a specific CID or all of them — with dirctl sync create --registry; your node need not even be online. This still isn't network discovery: there's no DHT, so consumers point sync at your registry rather than finding you across a network.

flowchart LR
  subgraph node["Your node"]
    api["API server"]
  end
  api -->|"records stored here"| reg[("Public OCI registry<br/>GHCR · Docker Hub")]
  other(["Another node"]) -->|"sync create --registry"| reg

Choose when:

  • Discovery = only you
  • Store = public registry

See Local Deployment and Store for more details.

Networked node

Be discoverable.

A bootstrap connection puts the node on the DHT: it announces its records and can search for records held by other nodes.

Being networked also enables autosync — direct node-to-node transfer over libp2p. Autosync is receiver-controlled: each node automatically pulls only from the peers in its own trusted allow-list. So you autosync records from peers you list, and a peer that lists you autosyncs yours. It is opt-in and off by default.

Because it is receiver-controlled, your own autosync setting changes what you can pull in — not what others can take from you:

Your store Your autosync Can others retrieve your records? Can you retrieve others' records?
Local off Only a peer that lists you in its own allow-list, over libp2p On-demand sync create only
Local on Same — your autosync does not change this Yes, from peers in your own allow-list (+ on-demand)
Public off Yes — anyone pulls from the registry On-demand sync create only
Public on Yes — anyone pulls from the registry Yes, from peers in your own allow-list (+ on-demand)
flowchart TB
  subgraph node["Your node · bootstrapped"]
    api["API server"] --> store[("store · local or public")]
  end
  dht{{"P2P network · DHT"}}
  peer(["Peer that trusts you"])
  api -. "1 · announce CIDs" .-> dht
  dht -. "2 · discovers your CIDs" .-> peer
  peer -->|"3 · autosync pulls record (direct, libp2p)"| api

Choose when:

  • Discovery = within your team or organization
  • Store = local or public

See Local Deployment, Connecting to a Remote Directory, and Routing for more details.

Federated

Exchange across organizations.

Multiple production nodes peer under a shared trust root. Organizations discover each other's records over a shared DHT and retrieve them with authenticated, authorized access (SPIFFE mTLS + authorization policies). Establishing that shared trust root takes a one-time SPIRE federation step, where each organization's SPIRE server exchanges trust bundles with the others (see Federation Bundle Profiles).

flowchart LR
  dht{{"Shared DHT · GossipSub"}}
  subgraph orgA["Organization A"]
    a(["Node A"])
  end
  subgraph orgB["Organization B"]
    b(["Node B"])
  end
  dht <-. "announce + discover" .-> a
  dht <-. "announce + discover" .-> b
  a <-->|"retrieve · SPIFFE mTLS + authz"| b

Choose when:

  • Discovery = other organizations

See Federation and Trust Model for more details.