Tiers and encryption

Every repo has exactly one tier, chosen when you create it. The tier decides one thing above all others: what the server can read.

amadan states that in plain language everywhere a tier appears, because "private" on every other forge means "other users can't see it" and says nothing about the operator. Here the difference is labelled rather than implied.

Public#

Plaintext on the server. Readable by anyone.

This is ordinary open-source git hosting: stock git over HTTPS, nothing to install, server-rendered browsing, working search and diffs. Anonymous reads are rate-limited per IP. Pushes always need a token and a writer role.

The operator can read it. So can everybody else — that's the point.

Private#

Plaintext on the server. Readable by members and by the operator.

This is GitHub's model, and reproducing it deliberately is the point. The host can read your code, and in exchange everything is boring and compatible: stock git plus a personal access token, server-rendered browsing, nothing to install, full-text everything.

If that trade was acceptable to you on GitHub, it's acceptable here. The difference is that here it's written down.

This is the default tier for a new repo.

Private, end-to-end encrypted#

Ciphertext on the server. Readable by members holding a key, and not by the operator.

This is the reason amadan exists. Your machines do all the encrypting and decrypting — including in the browser, where pages decrypt client-side. The server holds names, membership, public keys, and sealed bytes it cannot open.

The cost is real and worth stating before you choose it:

  • Every reader needs the amadan CLI and git-remote-amadan installed, and a registered key.
  • There is no anonymous access.
  • There is no server-side rendering, because the server has nothing readable to render.
  • Lose every copy of the key and the repo is gone. Nobody can reset it for you. That is what "the operator cannot read it" means when it's true.

What "the server gets nothing" actually means#

The claim is not a policy promise. It is enforced by a test.

A canary test pushes a repo containing a known marker string, then greps the raw bytes of the server's SQLite databases — both hub and repo instance — and fails if the marker appears anywhere. Repo content, browse indexes, discussion posts, CI logs: all of it arrives sealed.

Everything the server stores is one of: a public key, a signature, membership metadata, or ciphertext.

Choosing between them#

Pick public for open source.

Pick private when you want GitHub's convenience and GitHub's trust model, honestly labelled. Most repos, most of the time.

Pick private, end-to-end encrypted when the operator being able to read your code is genuinely unacceptable — and when everyone who needs access can install a CLI and hold a key.

Don't pick the encrypted tier by reflex. It costs anonymous access, server-side rendering, and recoverability, and those are real costs. Its value is precisely that you can't get the code back out of the server, which is also its danger.

Moving between tiers#

public to private, and back is a server-side flag flip. Instant, either direction:

amadan visibility <ns/repo> public|private

Into or out of the encrypted tier is always client-driven. Run the same command and it prints the steps for your machine to perform. The server never does this move for you, because doing it server-side would mean the server briefly holding your key — and a rule with an exception in it is not the rule this product is built on.

  • Getting started — cloning at each tier.
  • The CLIkeygen, share add, and the encrypted-tier commands.
  • CI — how CI stays identical across tiers.