Config
Auth

Authentication

Each project can have one or more authentication strategies enabled. When any authentication strategy is defined all requests towards the project must comply with at least one of the strategies.

Config

The appropriate strategy will be activated based on request payload. For example if "token" is present as a query string then "secret" strategy will be activated. These are currently supported strategies:

erpc.yaml
logLevel: debug
projects:
  - id: frontend
    auth:
      strategies:
      # Define a simple secret token for authentication of this project:
      - type: secret
        rateLimitBudget: free-tier
        secret:
          value: "some-random-secret-value"
      # Define another secret token, that can also be used, but with higher rate limit:
      - type: secret
        rateLimitBudget: premium
        secret:
          value: "some-other-random-secret-value"
    upstreams:
    # ...
rateLimiters:
  # ...

Method filtering

You can allow or disallow certain methods when a client is authenticated by a specific strategy. For example you can limit types of method available for a certain IP (or token), or define multiple secret tokens with different allowed methods.

allowMethods takes precedence over ignoreMethods. For example if you only want to allow eth_getLogs for a certain IP, you can:

Both allowMethods and ignoreMethods support wildcard * anywhere in the method name.

erpc.yaml
projects:
  - id: main
    auth:
      strategies:
      - type: secret
        ignoreMethods:
        - eth_getLogs
        - alchemy_*
        allowMethods:
        - alchemy_getAssetTransfers
        # ...
    upstreams:
    # ...
rateLimiters:
  # ...

Rate limiter

For each strategy item defined for a project you can enforce a separate rate limit budget. For example to limit users providing secret A to 100 requests per second, and users providing secret B to 1000 requests per second.

⚠️

At the moment, rate limit budgets apply across all clients authenticated by a specific strategy, and NOT per user.

For example in sample below, no matter how many actual clients use the premium secret token, all of them together cannot exceed 1000 requests per second.

erpc.yaml
projects:
  - id: main
    auth:
      strategies:
      - type: secret
        rateLimitBudget: free-tier
        # ...
      - type: jwt
        rateLimitBudget: premium
        # ...
    upstreams:
    # ...
rateLimiters:
  budgets:
  - id: low-tier
    rules:
    - method: '*'
        maxCount: 10
        period: 1s
  - id: premium
    rules:
    - method: '*'
        maxCount: 1000
        period: 1s

secret strategy

A simple strategy that allows you to define a secret value that will be checked against a token provided via query string, or via X-ERPC-Secret-Token header.

This strategy is mainly recommended for backend to backend communication. Exposing this token on your frontend allows users to impersonate the requests from anywhere.

If you still want to use this strategy on frontend, make sure CORS configuration are defined to reduce the potential abuse.

erpc.yaml
projects:
  - id: main
    auth:
      strategies:
      - type: secret
        ignoreMethods:
        - eth_getLogs
        - alchemy_*
        allowMethods:
        - alchemy_getAssetTransfers
        rateLimitBudget: premium
        secret:
          value: "some-random-secret-value" # To use env vars: ${MY_SECRET_VALUE}
    upstreams:
    # ...
rateLimiters:
  budgets:
  - id: premium
    rules:
    - method: '*'
        maxCount: 1000
        period: 1s

The client must provide this value either via a query string parameter:

curl -X POST https://localhost:4000/main/evm/42161?token=some-random-secret-value \
  # ...

Or via a header:

curl -X POST https://localhost:4000 \
  -H "X-ERPC-Secret-Token: some-random-secret-value"
  # ...

network strategy

To prevent requests based on IP address of the client, use network strategy:

erpc.yaml
projects:
  - id: main
    auth:
      strategies:
      - type: network
        network:
          # To allow requests coming from the same host (localhost, 127.0.0.1, ::1)
          allowLocalhost: true
 
          # To allow requests coming from the specific IPs
          allowedIPs:
          - "89.123.123.123"
 
          # To allow requests coming from the specific CIDR ranges
          allowedCIDRs:
          - "78.13.0.0/16"
 
          # When requests carry X-Forwarded-For header, you can define trusted proxies
          # that are allowed to override the client's IP address.
          #
          # These will evaluate X-Forwarded-For value from the left to the right,
          # and will use the first IP address that is not in the trustedProxies list.
          #
          # Example 1:
          #   X-Forwarded-For: 192.168.1.123, 22.22.22.22, 33.33.33.33
          #   trustedProxies:
          #   - "192.168.1.123"
          #   \_____ Detected client IP: 22.22.22.22
          #
          # Example 2:
          #   X-Forwarded-For: 11.11.11.11, 22.22.22.22, 33.33.33.33
          #   trustedProxies:
          #   - "192.168.1.123"
          #   \_____ Detected client IP: 11.11.11.11
          trustedProxies:
          - "192.168.1.123"
    upstreams:
    # ...
rateLimiters:
  # ...

jwt strategy

Use JWT (opens in a new tab) strategy to only allow requests carrying a JWT token signed by you or a trusted party. The main requirement for this strategy is public key(s) that you trust.

For frontend dApps this strategy is the most recommended because it allows control over how many users can hit your RPC endpoint and the "expiration" prevents users from abusing the RPC by copying the jwt token in multiple places.

If you already use a JWT for your frontend, you can use the same token for eRPC, only providing the proper public key(s).

This strategy respects the JWT token's expiration (exp claim) and will reject the request if token has expired.

erpc.yaml
projects:
  - id: main
    auth:
      strategies:
      - type: jwt
        jwt:
          # At least one public key must be provided, you can either provide the public key PEM as plain value,
          # or provide a path to the file containing the public key.
          #
          # The for each verification key you can use their "kid" (e.g. rsa-kid-1) as a key, and provide the PEM as a value.
          verificationKeys:
            "rsa-kid-1": "file:///Users/aram/www/0xflair/erpc/test/aux/public_key.pem"
            "rsa-kid-2": "${MY_RSA_KEY_2_PEM}"
          
          # Optional list of issuers that are allowed, if token has a different "iss" claim it will be rejected.
          allowedIssuers:
            - "https://erpc.web3-project.xyz"
 
          # Optional list of audiences that are allowed, if token has a different "aud" claim it will be rejected.
          allowedAudiences:
            - "https://frontend.web3-project.xyz"
 
          # Optional list of algorithms that are allowed, if token has a different "alg" header it will be rejected.
          allowedAlgorithms:
            - "RS256"
            - "HS256"
 
          # Optional list of claims that are required to be present in the token, otherwise the token will be rejected.
          requiredClaims:
            - "sub"
            - "role"
    upstreams:
    # ...
rateLimiters:
  # ...

siwe strategy

Many frontend dApps already use Sign-in with Ethereum (opens in a new tab) (SIWE) to authenticate wallets. You can use siwe strategy to allow requests from your dApp by providing the signature and signed message:

Message (which includes your statement, domain, expiration, etc) must be provided as base64 encoded string.

erpc.yaml
projects:
  - id: main
    auth:
      strategies:
      - type: siwe
        siwe:
          # A list of domains from which SIWE messages are allowed to be signed.
          allowedDomains:
            - "my-web3-project.xyz"
    upstreams:
    # ...
rateLimiters:
  # ...

Message and signature can be provided via query string parameters:

curl -X POST https://localhost:4000/main/evm/42161?message=my_message_base64_ecnoded&signature=0x123456 \
  # ...

or via X-ERPC-SIWE-Message and X-ERPC-SIWE-Signature headers:

curl -X POST https://localhost:4000 \
  -H "X-ERPC-SIWE-Message: my_message_base64_ecnoded"
  -H "X-ERPC-SIWE-Signature: 0x123456"
  # ...

Roadmap

On some doc pages we like to share our ideas for related future implementations, feel free to open a PR if you're up for a challenge:


  • Allow defining rate-limits per user (vs across all users), for more granular control over usage.