Every component of Dirless is open source under Apache-2.0, and the protocol between the components is identical whether we run the backend or you do. The hosted service is a convenience, not a dependency: if we disappeared tomorrow, you could run the whole stack yourself. This page explains what that takes - deliberately at the component level, so it fits your infrastructure instead of prescribing ours.
Dirless has three moving parts at runtime, connected by HTTPS and end-to-end encryption:
All four are static-friendly Crystal binaries, released as RPMs in the dirless.com package repository (x86_64 and aarch64) and buildable from source at github.com/dirless.
| Binary | Runs where | Job |
|---|---|---|
dirless-backend |
A server you control | HTTP API that stores encrypted snapshots and serves them to agents. State lives in an embedded database; there is no external database to run. |
dirless-syncer |
Near your IdP (e.g. an EC2 instance) | Pulls users and groups from AWS IAM Identity Center, encrypts them per host, pushes to your backend. Self-enrolls on first run. |
dirless-cli |
Each host, once | Enrollment (keypair + registration), plus export, import, and migration tooling. |
dirless-agent |
Each host, as a daemon | Fetches and decrypts snapshots, serves user/group lookups to glibc through the bundled NSS module. |
| Piece | Requirement |
|---|---|
| A backend server | Any modern Linux box, even a small one - the backend serves and stores ciphertext, it does not crunch. One is enough to start; the login path does not depend on its uptime. |
| TLS in front of it | The backend speaks plain HTTP on localhost and expects a reverse proxy to terminate TLS. Any proxy works: Caddy, nginx, HAProxy, a cloud load balancer. |
| A DNS name | Something like dirless.example.com pointing at the proxy. Agents and the syncer are configured with this URL. |
| IdP read access | The syncer needs read-only access to IAM Identity Center: identitystore:List* and sso:ListInstances. On EC2 an instance role is the natural fit. |
| A shared secret | One long random string, generated by you. It authenticates syncers, agents, and the CLI against your backend and derives your tenant ID. |
The backend is one binary and one TOML file. The repository ships an annotated example config; the essentials are the listen address, a directory for its embedded database, and your shared secret:
[server]
host = "127.0.0.1" # stay on localhost; TLS belongs to your proxy
port = 4000
[storage]
db_dir = "/var/lib/dirless/tenants"
[hmac]
secret = "generate-a-long-random-secret-and-put-it-here"
Run it under whatever supervises processes in your world - systemd, runit, a container, a BSD rc script. It is a single foreground process with no children and no external services. Point your proxy at it and confirm it answers:
curl https://dirless.example.com/v1/health
db_dir, and all of it is ciphertext. Snapshot
that directory with your existing backup tooling and you have backed up
Dirless. For the plaintext escape hatch, there is always
dirless-cli export from any
enrolled host.
The syncer runs wherever it can reach both your IdP and your backend - for AWS IAM Identity Center that usually means a small EC2 instance with a read-only instance role. Configure it with your backend URL and shared secret; it enrolls itself on first run, discovers your identity store, and from then on pushes an encrypted snapshot on every sync interval.
There is nothing sacred about its schedule or lifecycle: run it as a daemon, from a timer, or by hand while testing. Each run is idempotent - pull, encrypt, push.
Hosts are enrolled exactly as they are against the hosted service - the only difference is the URL:
dirless-cli enroll --server https://dirless.example.com --token <your-shared-secret>
Enrollment generates the host's age keypair, registers its public key
with your backend, and writes credentials to /etc/dirless/.
Start dirless-agent, and the host resolves your directory
through standard NSS:
getent passwd alice
alice:x:100001:100000:Alice Anderson:/home/alice:/bin/zsh
From here, everything in the rest of the documentation - the getting-started guide, SSH certificates and host-based access control, export and import - works unchanged against your own backend.
This page stops at the component level on purpose. Which distribution, which proxy, which process supervisor, which cloud, how many backend replicas, how you rotate secrets, how you monitor - those decisions belong to the people who operate the deployment, and your existing conventions will serve you better than a copy of ours. What Dirless guarantees is the contract: open-source components, open formats on the way in and out, and a protocol that does not care who operates the server.
If you get stuck self-hosting, open an issue on the relevant repo at github.com/dirless - real deployments finding rough edges is exactly what we want to hear about.