Skip to main content

Auth server for secure account registration

The auth server is a powerful application that provides a secure and flexible solution for account registration on the Chromia network. It's part of the account registration framework provided by the FT4 library. It offers various authentication methods to prevent potential attacks, such as account flooding, and ensures a controlled and regulated account creation process. This section provides a comprehensive overview of the auth server's features, setup, and configuration.

Authentication methods

The auth server supports the following authentication methods for account registration. The auth repository contains an application that lets users sign up for Chromia via various methods. As a dapp developer on Chromia, you want to use this to prevent attacks where users flood your dapp with accounts. Currently, the available options are:

  • Staking: Users can register an account if they have enough stake in a particular staking contract. This module allows you to configure custom staking contracts or use the default Chromia staking contracts deployed on Ethereum and Binance Smart Chain.
  • Telegram: Users can register via a Telegram bot by sending a signed message to the correct endpoint. This module integrates with Telegram's API and supports both direct links and bot commands for account registration.
  • Rate limiting: This module allows you to limit the number of accounts that can be created from a single IP address within a specified time period, providing a basic level of protection against account flooding.
  • reCaptcha: Users must pass a Google reCaptcha challenge before registering an account. This module integrates with Google's reCaptcha service and performs the required backend validations, providing an additional layer of security against automated account creation.

The Set up your project with Chromia FT4 topic provides information on configuring which methods you want to support.

Staking

The staking module provides you with the possibility to allow your users to register an account if they have enough stake in a particular staking contract. Contracts are configured in the file staking/contracts/index.ts by updating the contracts map. The structure of the map looks like the following:

const contracts = {
 [contractAddress]: {
  address: string;
  url: string;
  abi: AbiItem[]
 }
}

Where contractAddress is the contract's address, url is the RPC URL of the chain that hosts the contract, and abi is the ABI of the contract (can typically be found by looking at Etherscan or similar). By default, the application uses Chromia's staking contracts, deployed on Ethereum and Binance Smart Chain, but you are free to add your own contracts and add or remove the default ones. So long as the custom staking contracts comply with the same interface.

note

The application will sum the user's stake across all the provided contracts. For example, if the staking limit is 1000 and the user has 200 staked on Ethereum and 800 staked on BSC, then the user's total stake will be 200 + 800 = 1000 and will be considered to have reached the staking limit.

The staking module exposes the following REST APIs:

  • GET /auth/stake/enough?address=<evmAddress>

    Determines if the provided address has enough stake to create an account. Example response:

    { "status": "SUCCESS", "data": { "hasEnoughStake": true } }
  • GET/auth/stake/signing-message

    Retrieves the message to pass to MetaMask for user signing. Example response:

    {
    "data": {
    "message": "Register an account on blockchain 1234"
    },
    "status": "SUCCESS"
    }
  • POST /auth/stake/create

    Creates a new postchain account for the user. The endpoint expects a MetaMask signature of the message returned by /auth/stake/signing-message. If the address corresponding to the private key signing the message has enough total stake, a postchain account will be created. Example request:

    {
    "signature": "0xd8b9bc03ef2384f7fd404c723f702f3426a044191778cd8570a9d9ca0214d5f108a04629f86e6acbdad599a828956b9b0df25fd1768e3c8bedd077a76f9c997d1b"
    }

Telegram

The Telegram module allows registration via Telegram. After sending the signed message to the correct endpoint, the user should be prompted with one of the following:

  • a link to t.me/<bot_username>?start=<address> (for example, t.me/MyRegistrationBot?start=0x0000000000000000000000000000000000000000)
  • the instructions to go to your telegram bot and use either /start <address> or /register <address>

It exposes two endpoints:

  • POST /auth/telegram/

    Adds a signature for an address. The request body must include the address and signature.

    Example:

    {
    "address": "0x1234...",
    "signature": "0x5678..."
    }
  • GET /auth/telegram/:id

    Retrieves the signature for an address. Replace :id with the address in the URL.

    Example:

    GET /auth/telegram/0x1234...

    Rate limiting is implemented on both endpoints to prevent abuse.

Rate limit

The rate limit module limits the number of accounts an IP address can create within a specific time frame. Each IP address can create up to ACCOUNTS_PER_IP accounts per ACCOUNT_TIME_PERIOD seconds.

This module is enabled when ACCOUNTS_PER_IP is set.

The rate limit module exposes the following REST APIs:

  • GET /auth/ratelimit/signing-message

    Retrieves the message to pass to MetaMask for user signing. Example response:

    {
    "data": {
    "message": "Register an account on blockchain 1234"
    },
    "status": "SUCCESS"
    }
  • POST /auth/ratelimit/create

    Creates a new account for the user. The endpoint expects a MetaMask signature of the message returned by /auth/ratelimit/signing-message. If the IP address of the request has not created too many accounts recently, then an account will be created. Example request:

    {
    "signature": "0xd8b9bc03ef2384f7fd404c723f702f3426a044191778cd8570a9d9ca0214d5f108a04629f86e6acbdad599a828956b9b0df25fd1768e3c8bedd077a76f9c997d1b"
    }

reCaptcha

The reCaptcha module allows your users to register accounts if they first pass a Google reCaptcha. Enabling this module will perform the required backend validations specified by the reCaptcha documentation. The frontend part, however, needs to be provided by your client side. The relevant JavaScript part is as follows:

document.getElementById("<your form element>").addEventListener("submit", (e) => {
e.preventDefault();
const resp = window.grecaptcha.getResponse();
fetch("<domain>/auth/captcha/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
["g-recaptcha-response"]: resp,
signature: "<user signature>",
}),
});
});

Where the value returned by reCaptcha is passed to the auth server backend in the g-recaptcha-response parameter, we pass the user's MetaMask signature in the signature parameter.

To use this module, you must register your site with reCaptcha to acquire the API key.

This module is activated by providing the secret GOOGLE_RECAPTCHA_SECRET in the .env file.

The reCaptcha module exposes the following REST APIs:

  • GET /auth/captcha/signing-message

    Retrieves the message to pass to MetaMask for user signing.

    Example response:

    {
    "data": {
    "message": "Register an account on blockchain 1234"
    },
    "status": "SUCCESS"
    }
  • POST /auth/captcha/create

    Creates a new account for the user. The endpoint expects a MetaMask signature of the message returned by /auth/captcha/signing-message and the response value returned by the reCaptcha form. If the signature and reCaptcha are valid, an account corresponding to the address used to sign the request is created.

By combining these authentication methods, you can tailor the account registration process to meet your specific security requirements and mitigate potential risks.

Set up and configure auth server in your Rell project

To include the auth server in your Rell project, follow these steps:

  1. Generate the auth server and the admin keys by running the following commands:

    chr keygen --file .auth.secret | grep pubkey
    chr keygen --file .admin.secret | grep pubkey

    This saves the keys to files named .auth.secret and .admin.secret in the current directory.

  2. Add the following dependencies to your chromia.yml file:

    libs:
     auth:
      registry: https://bitbucket.org/chromawallet/auth-server-ft4.git
      path: rell/src/auth
      tagOrBranch: v2.1.0r
      rid: x"7EC77529149B510F7863BA19CE2A8798AD8492A98A79F8B350FE8D774996F268"
      insecure: false

     ft4:
      registry: https://bitbucket.org/chromawallet/ft3-lib
      path: rell/src/lib/ft4
      tagOrBranch: v0.7.0r
      rid: x"F7C207AA595ABD25FDE5C2C2E32ECD3768B480AD03D1F2341548FF4F37D9B7AF"
      insecure: false
    note

    The auth server Rell module depends on the FT4 library, so you need to include both dependencies.

  3. Add the following module arguments to your chromia.yml file, replacing <auth pubkey> and <admin pubkey> with the public keys generated in step 1:

    moduleArgs:
    lib.ft4.core.admin:
    admin_pubkey: <admin pubkey>

    lib.auth:
    auth_pubkey: <auth pubkey>
  4. Import the auth operations in your main Rell module:

    import lib.auth;
  5. Follow the instructions in the auth server repository to set up and configure the Node.js server:

    • Clone the repository

      git clone git@bitbucket.org:chromawallet/auth-server-ft4.git
    • Install dependencies

      npm ci
    • Create an .env file and configure the necessary variables (e.g., PORT, BLOCKCHAIN_RID, BLOCKCHAIN_URL, AUTH_PRIV_KEY, etc.)

      PORT=3001
      MODE=dev
      BLOCKCHAIN_RID=0F8B260F653457A5C7942018ED31BAE5EF53D6AE04FC4D402EC5F0DE26B5913D
      BLOCKCHAIN_URL=http://localhost:7740
      AUTH_PRIV_KEY=132EC6A758DCAA832DAFE032C4B23ABD9615C56792687ADBC561FCC377430CEC
      STAKE_LIMIT=1000
      TELEGRAM_API_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
    • Start the server

      npm start

By completing these steps, you'll have the auth server integrated into your Rell project, allowing you to leverage its various authentication methods for secure account registration on the Chromia network.

Available configuration options

The auth server provides a range of configuration options to tailor the account registration process to your specific requirements. Some of the notable options include:

Name        Description                                                                                Example                           RequiredDefault value
PORT          The port on which the application will be listening                                                              3001                              no     3001       
MODE          Is this application running in development or in production mode                                                        dev|prod                            no     prod       
BLOCKCHAIN_RID     The blockchain rid of the blockchain on which the application should create accounts                                              0F8B260F653457A5C7942018ED31BAE5EF53D6AE04FC4D402EC5F0DE26B5913Dyes     none      
BLOCKCHAIN_URL     The blockchain url of the blockchain on which the application should create accounts                                              http://localhost:7740                      yes     none      
AUTH_PRIV_KEY     The user private key to perform register account operation                                                           132EC6A758DCAA832DAFE032C4B23ABD9615C56792687ADBC561FCC377430CECyes     none      
AUTH_FLAGS       Comma-separated list of flags used for registering a new account                                                        A,T                               no     A, T       
IS_MANAGED_NETWORK   Is auth server used with a managed network (e.g., testnet)? If true, then the directory chain will be used to discover the blockchain node. BLOCKCHAIN_URL will be used as a system node URLtrue                              no     false      
TIME_BETWEEN_REQUESTS Time which has to pass between each request from a given IP address, in seconds, zero to turn off rate limiting                                 10                               no     5        
ORIGIN_IP_HEADER    HTTP request header to read the origin IP address from will use the actual origin IP address if not set. Use this only when behind a trusted proxy.                x-forwarded-for                         no     none      
SUPPORTED_NETWORKS   Comma separated list of chainIds to check stake on. It is only relevant if a staking module is used.                                          1,56,97                             no     1,56       
STAKE_LIMIT      The minimum value the user needs to stake to create an account. Required to use the staking module.                           100                               no     none      
TELEGRAM_API_TOKEN   Your Telegram API token. Required to use telegram module.                                                           123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11            no     none      
ADMIN_CHAT_ID     The Telegram Chat ID of the admin, who can use the admin commands to debug the bot. If not set, the bot will work normally. Nobody will have admin permissions    76694301                            no     none      
ACCOUNTS_PER_IP    Number of accounts to create for a given IP address per ACCOUNT_TIME_PERIOD seconds. Required to use rate limit module.                           10                               no     none      
ACCOUNT_TIME_PERIOD  Period for account creation rate limiting, in seconds. Required to use rate limit module.                                         3600                              no     none      
GOOGLE_RECAPTCHA_SECRETThe secret value provided when registering your site with reCaptcha.                                                      6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe            no     none      

You can configure these options and more by setting the corresponding environment variables in the .env file.