Security Settings

📘

Note:

The current security settings are only valid for the HTTP interface.

Allowlists

You can use the following project-specific security settings to better control how your API Keys are used:

  • AllowLists - set limits on request types that are allowed
  • JWT - Authentication

AllowList User-Agents

If you are distributing products embedded with API keys and can set up custom User-Agent (e.g. an Electron app, iOS or Android app), then we would recommend adding the known User-Agent to your allowlist. When a User-Agent is added to the allowlist, any API requests originated from other platforms will be rejected.

User-Agent allowlist utilizes partial string matching. If a string that is allowed to list exists in the request's full User-Agent, it is registered as a match.

Example:

Allowlist entry:com.example.dapp

Request:

curl -X POST \
  https://api.trongrid.io/wallet/createtransaction \
  -H 'User-Agent: com.example.dapp/v1.2.7 (Linux; Android 8.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36' \
  -H 'Content-Type: application/json' \
  -H 'TRON-PRO-API-KEY: 25f66928-0b70-48cd-9ac6-da6f8247c663' \
  -d '{
    "to_address": "41e9d79cc47518930bc322d9bf7cddd260a0260a8d",
    "owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292",
    "amount": 1000
}'

Result: Request is allowed while all other user-agent requests are rejected.

AllowList Origin

To prevent a third party from using your API Key on their website, you can list HTTP Origins that are allowed to use HTTP.
If you are deploying your application to mydapp.example.com, adding mydapp.example.com to your HTTP Origin allowlist will ensure that Origin is not included in HTTP requests: all traffic from mydapp.example.com will be rejected.

Similar to TLS certificates, HTTP Origin matching supports wildcard subdomain patterns, where the left-most sub-domain may be replaced with the special wildcard to match any such subdomain. The matches a single sub-domain, and can only appear as the left-most portion of an entry.
The URL schema is optional, and can be http://, https:// or any other schema you want to limit to. If the schema is included in the allowlist entry, the Origin must have the same schema. Furthermore, an entry with only one schema will limit requests to Origins of that schema.

Allowlist entry:https://*.example.com

Request's Origin Header:
curl -X POST \
  https://api.trongrid.io/wallet/createtransaction \
  -H 'TRON-PRO-API-KEY: 25f66928-0b70-48cd-9ac6-da6f8247c663' \
  -H 'Origin: https://myapp.example.com' \
  -H 'Content-Type: application/json' \
  -d '{
    "to_address": "41e9d79cc47518930bc322d9bf7cddd260a0260a8d",
    "owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292",
    "amount": 1000
}'

Result: Request is allowed, because the Origin Header matches the schema.

AllowList Contract Addresses

If you know your application will query data only from specific smart contracts or address sources, please add those addresses to your Contract Address Allowlist.
When an address is added to the allowlist, any API requests with query addresses beyond that will be rejected.

The following interfaces use contract address parameters:

/v1/contracts/contract_address/events
/(event)|(events)/contract/contract_address
/(event)|(events)/contract/[a-zA-Z0-9]+/[a-zA-Z0-9]+
/(event)|(events)/contract/[a-zA-Z0-9]+/[a-zA-Z0-9]+/[a-zA-Z0-9]+
/walletsolidity/triggerconstantcontract
/wallet/triggersmartcontract
/wallet/triggerconstantcontract

Example:

Allowlist entry: TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t

Request:
curl --request GET \
  --url https://api.trongrid.io/v1/contracts/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t/events \
  --header 'TRON-PRO-API-KEY: 25f66928-0b70-48cd-9ac6-da6f8247c663' 
  
Result: Request is allowed. Any compatible request methods with non-allowlisted addresses alone as parameters will be rejected.

AllowList Requested Api

You can restrict requests to specific TronGrid methods through your API Key. If the list is not empty, any unspecified method calls on it will be rejected.

Example:

Allowlist entry: walletsolidity_getTransactionById

Request:
curl --request GET \
  --url https://api.trongrid.io/v1/accounts/TUD4YXYdj2t1gP5th3A7t97mx1AUmrrQRt \
  --header 'TRON-PRO-API-KEY: 25f66928-0b70-48cd-9ac6-da6f8247c663' \
  
Result: Request is rejected, because the method is not walletsolidity_getTransactionById.

JWT

What is JWT

Json Web Tokens (JWT) is an open standard for JSON to transfer claims between web application environments. JWT statements are generally used to pass authenticated user identity information between identity providers and service providers.

How to use JWT

If the JWT switch is on, each request needs to include token information for TronGrid to verify. Requests that failed the verification will not be responded. Each account can create up to 3 JWTs. When creating a JWT, the public key created by the user is required (RS256 is now supported). ID and Fingerprint will be generated after the public key is filled in.

Example

1.Generate RSA key pair

In order to use JWT in the project, you need to generate a public/private key pair first. TronGrid currently supports the algorithm RS256. Please make sure you keep the private key secret!

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

You need to enter an easy-to-understand name to identify the key and the text in the key file. It should be a PEM-encoded file (for example, generated by OpenSSL). It usually looks like this:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvGek2v/H/TEzB+mnfbJ5
m7wgon0u/JjFQY3kYr6E0N4cRBQm8sy6ikNKi5x/1YxmhBqn6HvF9xD/p72eCBVe
RFh863pjWpF1C5yjOq3OEks00ayRP1ukATG8LtoUnWoPisXrh5/wVe4fHDPeNwe4
5RXOp6svO860o/ckAxt8yO/ZczqtN8cNA7unGawJ3cn8VeL+pa4a6f8DNfp32QUY
Y//HjPFvrTxcfJ4cM6E74L913P2CDuiSVVXMk0iyX/blh6M4h7dGAlcmHEHno9OW
5jrrAKobZZT1quc6qT43sTJviqc24Ndgas5jTOPhEV7bgkgQbTbtpgorHjUpqAIm
+wIDAQAB
-----END PUBLIC KEY-----

2.Generate token

Method 1: Java code
Import the jjwt package

compile 'io.jsonwebtoken:jjwt-api:0.11.2'
runtime 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtime 'io.jsonwebtoken:jjwt-jackson:0.11.2'

Call createSignedJwtRsa256 to generate token

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.spongycastle.util.encoders.Base64;
  
public class JwtTest {
  
 private static PublicKey getRSAPublicKey(String inputKey)
    throws NoSuchAlgorithmException, InvalidKeySpecException {
  String rsaPublicKey = inputKey.replace("-----BEGIN PUBLIC KEY-----", "");
  rsaPublicKey = rsaPublicKey.replace("-----END PUBLIC KEY-----", "");
  rsaPublicKey = rsaPublicKey.replace("\n", "");
 
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(rsaPublicKey));
  KeyFactory kf = KeyFactory.getInstance("RSA");
  return kf.generatePublic(keySpec);
 }
 
 
public void createSignedJwtRsa256() {
  /**
   * {
   *   "alg": "RS256",
   *   "typ": "JWT",
   *   "kid": "bdbd8dabcb8d49f3ae9732c14c9940ea"
   * }
   *
   * {
   *   "exp": 1617736153,
   *   "aud": "trongrid.io",
   * }
   * */
 
  try {
    PrivateKey privateKey = getRSAPrivateKey(privateKeyStr);
 
    JwtBuilder builder = Jwts.builder()
        .setHeaderParam("alg", "RS256") 
        .setHeaderParam("typ", "JWT") 
        .setHeaderParam("kid", "XXXXXXXXXXX") // your jwt key id
        .claim("exp", 1617736153) 
        .claim("aud", "trongrid.io") 
        .signWith(privateKey, SignatureAlgorithm.RS256);
 
    String token = builder.compact();
    System.out.println(token);
 
  } catch (Exception e) {
    e.printStackTrace();
    assert false;
  }
}
  
}

Method 2: Jwt website

  1. Go to the website: https://jwt.io/

  2. Select RSA256 algorithm

  3. Enter header, kid is the id of JWT; after adding JWT to the key, view it from the key configuration

{  "alg": "RS256",
   "typ": "JWT",
   "kid": "XXXXXXX" // id of jwt
}
  1. Enter payload,If exp has no expiration time, you can leave it blank
{
   "exp": 1617736153,
   "aud": "trongrid.io" 
}
  1. In VERIFY SIGNATURE, enter the public key and private key respectively.

  2. In ENCODED, you can see the generated token.

3. Use token

Add an Authorization field to the request header with the value: Bearer XXXXXX,
where XXXX is a token, and there is a space between token and Bearer.

Examples:

curl -X POST \
  https://api.trongrid.io/wallet/createtransaction \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer xxxxxx' \
  -H 'TRON-PRO-API-KEY: 25f66928-0b70-48cd-9ac6-da6f8247c663' \
  -d '{
    "to_address": "41e9d79cc47518930bc322d9bf7cddd260a0260a8d",
    "owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292",
    "amount": 1000
}'
import requests

url = "https://api.trongrid.io/wallet/createtransaction"

payload = "{\n    \"to_address\": \"41e9d79cc47518930bc322d9bf7cddd260a0260a8d\",\n    \"owner_address\": \"41D1E7A6BC354106CB410E65FF8B181C600FF14292\",\n    \"amount\": 1000\n}"
headers = {
    'Authorization': "Bearer xxxxxx",
    'Content-Type': "application/json",
    'TRON-PRO-API-KEY': "25f66928-0b70-48cd-9ac6-da6f8247c663"
    }
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
var request = require("request");

var options = { method: 'POST',
  url: 'https://api.trongrid.io/wallet/createtransaction',
  headers: {  
     'Authorization': 'Bearer xxxxxx',
     'TRON-PRO-API-KEY': '25f66928-0b70-48cd-9ac6-da6f8247c663',
     'Content-Type': 'application/json' 
},
  body: { 
      to_address: '41e9d79cc47518930bc322d9bf7cddd260a0260a8d',
     owner_address: '41D1E7A6BC354106CB410E65FF8B181C600FF14292',
     amount: 1000 
},
  json: true 
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

4.Attention
The "typ" in the header is fixed to "JWT".
Currently only RS256 is supported; ES256 will be supported in future versions.
Therefore, the alg field in the header is currently fixed to RS256.
The "aud" in the playload is fixed to "trongrid.io".

//Header:
{
     "alg": "RS256",
     "typ": "JWT",
     "kid": "bdbd8dabcb8d49f3ae9732c14c9940ea" // your jwt id
}
//Body
{
   "exp": 1617736153,
   "aud": "trongrid.io"
}