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
| Parameter | Description |
|---|---|
address | URL of Postgres database. |
database | Database name on Postgres. |
username | Postgres’ username. |
password | Postgres’ password. |
pool_size | Maximum number of concurrent connections to database. |
ssl | Wether 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
| Parameter | Description |
|---|---|
memory_cost | Memory cost of a hash in KiB. |
iterations | Number of iterations. |
parallelism | Parallelism degree. |
hash_length | Password hash result length. Higher avoid collisions. |
zxcvbn | Dropbox 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-----
| Parameter | Description |
|---|---|
key_id | JWK 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))'
| Parameter | Description |
|---|---|
address | URL 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_dn | Root DN for all LDAP searches. |
additional_users_dn | Sub-path under base_dn to locate user entries. |
users_filter | LDAP filter to find a specific user |
additional_groups_dn, | Sub-path under base_dn to locate group entries. |
groups_filter | LDAP 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
| Parameter | Description |
|---|---|
issuer | Name displayed on the user authentication application. |
algorithm | MUST be sha1. |
digits | Number of digits for the 30-second token. |
period | Token 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
| Field | Description |
|---|---|
signature | Cryptographic signature. |
id | Unique user identifier with server (e.g., id@server.com). |
key | Identifier of the public key used to verify the signature. |
authenticatorData | Base64url-encoded data returned by the authenticator, includes flags, counters, etc. |
clientDataJSON | Base64url-encoded JSON describing the context (challenge, origin, type). |
3. Token Generation (Client-Side)
- The client obtains credentials via the WebAuthn API.
- The authenticator signs a challenge with the user’s private key.
- The client builds a token URL with the resulting signature and metadata.
- 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:
- Parse the fields from the body request.
- Reconstruct the signed payload:
message = authenticatorData || SHA-256(clientDataJSON)
- Retrieve the public key:
- Use the
keyandidparameters to fetch the correct key. - Validate the authenticity of the server and key material.
- Use the
- Verify the signature using the appropriate algorithm (Ed25519 or RS256).
- Validate
authenticatorData:- Check presence/verification flags.
- Validate the relying party ID hash.
- Parse and validate
clientDataJSON:- Ensure
challengematches what was sent. - Confirm
originmatches expected domain.
- Ensure
- 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.