tessera

Accounts

Registration policy, forgotten passwords

Registration policy

auth.registration is open, invite or closed, set in the admin panel.

invite needs a code an administrator issued. It goes in the registration body as invite_code.

Without mail configured, registering creates the account and signs it in on the spot. With mail configured, the account does not exist until the address is confirmed. See email.

The first account to exist becomes the administrator, which is the one created automatically on first start.

Roles

Permissions come from a role. An account has exactly one, and four are built in:

RoleWhat it can do
ownerEverything
adminAccounts, invites, and looking at what is here. Not deleting accounts, not deleting other people's shares, not editing roles
memberUpload, and manage what you uploaded
guestSigned in, and allowed nothing

New accounts go into auth.default_role, which is member unless you change it. The role has to exist or the server refuses to start, so a typo is caught at boot rather than arriving as a stranger's 500 at registration.

Give people a different role rather than editing member

The built-in roles are locked. To give ordinary users less, point auth.default_role at a role you made.

The last account holding roles:write cannot be deleted or demoted.

Account states

StateWhat it means
activeNormal
disabledSuspended. The person is stopped, their content is not
deletedGone, and the row scrubbed. See where your data lives

Disabling stops somebody signing in. Their shares keep serving, because whoever holds one of those links did nothing wrong. To stop the content too, an administrator disables the shares themselves.

suspend restore delete active disabled deleted

Changing your own account

You can change your own name or address, and remove your own account. Both ask for your current password first.

An API token cannot do either

Neither is possible with an API token, only while signed in.

Removing your account ends everything you uploaded as well, unless you choose to keep the links you handed out working.

Changing your address clears its verification. With mail set up you can ask for a new verification message; the link in it confirms only the address it was sent to, so changing the address again in the meantime makes it worthless.

Passwords

Eight characters minimum by default (auth.password.min_length). The instance can also require mixed case, a digit or a symbol; all three are off by default. The rules apply when a password is set, not when it is used, so tightening them never locks out an existing account.

Checking against known leaks

With auth.pwned.enabled on, every new password is checked against Have I Been Pwned and refused if it appears in a known breach.

What leaves the instance

The first five characters of the password's SHA-1 hash, nothing else. The comparison happens here. If the service cannot be reached within three seconds the password is allowed and a line is logged. auth.pwned.url can point at a mirror you run instead.

Sign-in through GitHub, Discord or your own identity provider is on its own page: signing in with another account.

Two-step verification

Anyone who signs in with a password can add an authenticator app from their account page. Signing in with the password then asks for a six-digit code from the app as well, within five minutes of the password.

  • It takes effect only after one code from the app has been entered, so a botched setup locks nobody out.
  • Ten recovery codes are shown once. Each works once in place of a code. Asking for new ones makes the old ones stop working.
  • Turning it off, or asking for new recovery codes, needs the password or a code. An API token can do neither.
  • Only the password asks. Signing in through GitHub, Discord or your own identity provider does not, because that provider has its own second step.

Wrong codes are counted per account

After too many, the account is refused for a while, from every address. Whoever is guessing already has the password, so change it.

Somebody who has lost both the app and the recovery codes can be reset by an administrator from the admin panel, whose user list shows who has it on. For the only administrator, on the machine:

tessera-server reset-mfa -u admin

It works with the service stopped. The account signs in with its password alone afterwards.

Passkeys

A passkey signs you in with a fingerprint, a face or the device's PIN instead of the password. Add them from your account page. An account can have several, each with a name you can change. A passkey sign-in counts as both steps, so it never asks for a code.

A passkey belongs to one address

It is tied to the host name in server.public_url, or to the address in the browser when that is unset. Move the instance to another domain and every passkey stops working: people sign in another way and add a new one. Set server.public_url before anyone adds a passkey.

An account cannot remove its last way to sign in, and a passkey counts as one.

Forgotten passwords

From the command line

Needs no network, and works with the service stopped. This is what to use when the only administrator is locked out.

tessera-server reset-password -u admin

It prompts for the new password without echoing, twice. Getting the two wrong changes nothing.

Other ways in:

  • --password-stdin reads from a pipe. Use this for automation.
  • --generate prints a generated one and marks the account as owing a change.
  • -p <value> passes it directly.

-p leaks

While the command runs, ps shows the password to every user on the machine, and it stays in shell history. Use --password-stdin in automation.

With no terminal and no flag (a script, a cron job) it generates one and prints it. So piping a password in without --password-stdin sets the generated one instead:

Password for `admin` set to:

    0cae83d5ad2ca901d5163bf712eef39fb355d0fe1a9ebd2ff094c7b0b053816a

Sign in with it and choose a new one — this account is now marked as owing a change.

There was no terminal to ask at, so this one was chosen here.
If you meant to supply one, pass it with --password-stdin.

Anyone who can run this against the database can take any account. Anyone holding the database file could already do the same thing.

By email

Requires mail to be configured. The frontend also needs a /reset-password route for the link to go anywhere.

On this page