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

Introduction

Autha is an account manager, allowing you to decentralize your connection.

You can either self-host Autha or use a public instance. Then, create an account. Finally, create a key pair on your machine and send only the public key to the server.

License

Source code and documentation are released under BSD-3-Clause license.

Database

Autha uses PostgreSQL as database. Database handles account management (including public keys and refresh tokens) and invitations.

Add in config.yaml following code:

postgres:
  address: postgres:5432
  database: autha
  username: postgres
  password: postgres
  pool_size: 25
  ssl: false
ParameterDescription
addressURL of Postgres database.
databaseDatabase name on Postgres.
usernamePostgres’ username.
passwordPostgres’ password.
pool_sizeMaximum number of concurrent connections to database.
sslWether allow or not secure connection.

Password

Autha uses Argon2 to hash users’s passwords. Only change the settings if you know what you are doing.

Add in config.yaml following code:

argon2:
  memory_cost: 65536 # 64 MiB.
  iterations: 4
  parallelism: 2
  hash_length: 32
  zxcvbn: 3
ParameterDescription
memory_costMemory cost of a hash in KiB.
iterationsNumber of iterations.
parallelismParallelism degree.
hash_lengthPassword hash result length. Higher avoid collisions.
zxcvbnDropbox password strength metering. Set to 0 to disable.

Session tokens

When the user creates their account or logs in, a pair of tokens is created. The session token is a 15-minute JWT. The second is a refresh token (64 alphanumeric characters) valid for 15 days.

Refresh token allows you to obtain a new JWT and refresh token. Each new JWT created invalidates the old refresh token.

Add in config.yaml following code:

token:
  key_id: fixed_string_for_this_key
  private_key_pem: |-
    -----BEGIN PRIVATE KEY-----
    MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgg8wQwttCoiBA9yQZ
    Uo+lImtpakc48rw9mHTPhD6k5A+hRANCAATkZYzb0mgzeeckNkE2dKlwX9zxW9Qz
    4JtlLQH76IOhXNObDGrsrsEeo5KDCQe1rrkYT/mTNuWepEEotRd4DRvf
    -----END PRIVATE KEY-----
  public_key_pem: |-
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5GWM29JoM3nnJDZBNnSpcF/c8VvU
    M+CbZS0B++iDoVzTmwxq7K7BHqOSgwkHta65GE/5kzblnqRBKLUXeA0b3w==
    -----END PUBLIC KEY-----
ParameterDescription
key_idJWK ID. Public key retrieving for signature verficiation.
private_key_pem*Private key to sign JWTs. NEVER SHARE IT.
public_key_pem*Public key for signature verficiation.

* Key MUST be ES256.

If your Autha instance is distributed, use a signature key pair for each container.

LDAP

Autha supports LDAP directory integration for user and group resolution. This feature enables compatibility with enterprise identity systems by dynamically resolving user attributes and group memberships through LDAP queries.

Add in config.yaml following code:

ldap:
  address: ldap://127.0.0.1:389
  user: CN=admin,DC=domain,DC=local
  password: admin
  base_dn: DC=domain,DC=local
  additional_users_dn: OU=users
  users_filter: '(&(uid={user_id}))'
  additional_groups_dn: 'OU=groups'
  groups_filter: '(&(member={dn})(objectClass=groupOfNames))'
ParameterDescription
addressURL of the LDAP server. Support ldap:// and ldaps://.
user*DN of admin LDAP account used to create new entries.
password*userPassword for admin account.
base_dnRoot DN for all LDAP searches.
additional_users_dnSub-path under base_dn to locate user entries.
users_filterLDAP filter to find a specific user
additional_groups_dn,Sub-path under base_dn to locate group entries.
groups_filterLDAP filter to find groups containing the user

* You can omit user and password field if you don’t want to create new entires on LDAP via Autha.

Time-based One-Time Password (TOTP)

This extension cannot be disabled. It provides users with additional security (a period-second symmetric token).

Add in config.yaml following code:

totp:
  issuer: autha
  algorithm: sha1
  digits: 6
  period: 30 # in seconds
ParameterDescription
issuerName displayed on the user authentication application.
algorithmMUST be sha1.
digitsNumber of digits for the 30-second token.
periodToken time window.

1. Introduction

Autha is a decentralized authentication system that enables users to authenticate themselves using asymmetric cryptographic keys via WebAuthn. Users are responsible for securely storing and managing their own private keys.

Autha’s role is limited to publishing the users’ corresponding public keys in a verifiable and accessible manner.

1.2 Impact

Any system implementing Autha MUST support user authentication regardless of the specific instance used. In particular, a user MUST be able to authenticate from any Autha-compatible instance, provided their public key is available and their private key is valid.

This ensures cross-instance interoperability and preserves the decentralized nature of the authentication mechanism.

2. Schema

2.1 User Identifier (User ID)

Each user is identified by a unique and stable identifier, referred to as the User ID.

A User ID MUST follow the format:

<vanity>@<server-domain>

For example: alice@auth.example.com.

  • vanity: A user-chosen identifier (MAY be pseudonymous).
  • server-domain: The domain of the Autha-compatible server that exposes the user’s public identity.

A User MUST have exactly one User ID, and this identifier MUST remain consistent across all Autha operations.

2.2 Server

Server exposes user as specified on ActivityPub format.

2.3 Keys

An Autha-compatible server MUST NOT store or have access to any private key. It MUST ONLY store and expose public keys associated with a given user.

A user MAY have multiple active public keys (e.g., to support multiple devices or key rotations). Each key MUST be uniquely identifiable and linked to the owning User ID.

The /users/:USER_ID endpoint MUST return public keys using the following JSON structure:

[
  {
    "id": "0000",
    "owner": "alice@auth.example.com",
    "public_key_pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
    "created_at": "YYYY-MM-DD"
  },
  ...
]
  • id: A unique identifier for the public key.
  • owner: The associated User ID.
  • public_key_pem: The public key in PEM format.
  • created_at: ISO 8601 date when the key was created or registered.

1. Introduction

This document defines a mechanism for generating and verifying identity assertion tokens using Navigator Credentials. These tokens are client-generated cryptographic signatures that bind a user identity to an authentication assertion, leveraging WebAuthn-compatible authenticators.

Tokens are signed using one of the following public-key signature algorithms:

  • Ed25519 (preferred), or
  • RS256 (RSA PKCS#1 v1.5 with SHA-256).

2. Token Format

Tokens are transmitted using POST request to server defined on query parameters redirect.

2.1 Body fields

FieldDescription
signatureCryptographic signature.
idUnique user identifier with server (e.g., id@server.com).
keyIdentifier of the public key used to verify the signature.
authenticatorDataBase64url-encoded data returned by the authenticator, includes flags, counters, etc.
clientDataJSONBase64url-encoded JSON describing the context (challenge, origin, type).

3. Token Generation (Client-Side)

  1. The client obtains credentials via the WebAuthn API.
  2. The authenticator signs a challenge with the user’s private key.
  3. The client builds a token URL with the resulting signature and metadata.
  4. The token is shared with the relying party (e.g., via HTTP redirect or fetch).

4. Token Verification (Server-Side)

To verify the received token, the server MUST:

  1. Parse the fields from the body request.
  2. Reconstruct the signed payload:
    • message = authenticatorData || SHA-256(clientDataJSON)
  3. Retrieve the public key:
    • Use the key and id parameters to fetch the correct key.
    • Validate the authenticity of the server and key material.
  4. Verify the signature using the appropriate algorithm (Ed25519 or RS256).
  5. Validate authenticatorData:
    • Check presence/verification flags.
    • Validate the relying party ID hash.
  6. Parse and validate clientDataJSON:
    • Ensure challenge matches what was sent.
    • Confirm origin matches expected domain.
  7. Create server-side token with expiration.

5. Security Considerations

Token relay on WebAuthn with extras.

  • User ID modification: server MUST get public key from query server using query user ID; if no key corresponds to the user, the connection is invalidated.
  • Replay attack: while WebAuthn have no timestamp or nonce field, it have a challenge one which MUST be used.

NEVER use WebAuthn signature as server-side token. You SHOULD use JWT after verifications. challenge generated by the server MUST have a window shorter than 2 minutes.