Witness permission separation

Use TRON's Account Permission Management to keep an SR's owner key offline while a hot key signs blocks.

ℹ️

Witness permission separation

Part of SR best practices — this page is the deep-dive walkthrough for the Witness permission separation practice.

📘

Prerequisites

By default, an SR account's witness_permission, active_permission, and owner_permission all authorize the same key — the SR's own address. A single private key therefore signs both blocks (validated against witness_permission) and balance-moving transactions (validated against owner / active). Leaking that key compromises block production and reward funds at once. TRON's Account Permission Management lets you split block production into a dedicated key — the owner key can stay on cold storage while a hot signing key only ever signs blocks.

This guide covers the on-chain permission update, the matching localwitness configuration on the node, and how to verify the delegation is working.

📘

Witness permission scope

Witness permission itself covers only block signing. If the same address also appears in an Owner or Active permission, that key has those additional capabilities. Fund movement and account changes are controlled by Owner/Active permissions. Use separate keys, and protect Owner/Active keys to a cold-storage standard. See Account permission management for the full permission model.

Why separate block production

  • Owner key stays offline. With witness permission delegated, the owner key is not involved in routine block production and is normally used only for owner-level operations, such as updating account permissions. Routine fund or governance operations can use separately scoped Active keys.
  • Hot signing key has a limited scope. If the Witness key is not reused in an Owner or Active permission, a leak cannot authorize TRX transfers, voting, or permission updates. If compromise is suspected, stop block production and use a currently available authorization path to replace the address in witness_permission.
  • Standard practice. SRs operating in production typically delegate block production. See SR best practices.

Update the SR's account permissions

⚠️

Stop block production first

Stop the block-producing node before updating witness permission. Producing blocks while permissions are being changed risks signing with a key the network has just stopped accepting.

⚠️

The transaction replaces the complete owner and active permission configuration, and an SR account must also submit its Witness permission. If the updated owner permission cannot meet its threshold and no usable active permission enables AccountPermissionUpdateContract (ID 46), the account permissions cannot be changed again. Whether TRX, rewards, or block production remain accessible depends on the remaining active and Witness permissions. Read the checklist under Updating permissions first.

You can update the SR's permissions either through TRONSCAN's permission UI or by submitting an AccountPermissionUpdateContract:

Verify the witness_permission entry

Query the SR account with wallet/getaccount and inspect the witness_permission block:

BASE_URL=https://api.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST "${BASE_URL}/wallet/getaccount" \
  -H 'Content-Type: application/json' \
  -d '{"address":"TTxrh32VJveqiYRwbLEX2wLTMFCfbpAUQj","visible":true}'
{
    "address": "TTxrh32VJveqiYRwbLEX2wLTMFCfbpAUQj",
    ...
    "witness_permission": {
        "type": "Witness",
        "id": 1,
        "threshold": 1,
        "keys": [
            {
                "address": "TXXvArisGf7YL9TfUbwYj5i16htm8ZjMUs",
                "weight": 1
            }
        ]
    },
    ...
}

The response above shows that SR TTxrh3...AUQj authorizes TXXvAr...jMUs to sign blocks, and that the signing address does not appear in the account's Owner or Active permissions. Before configuring your node, query your own SR account and inspect the complete permission object to make sure the signing address is not reused by another permission.

Point the node at the delegated key

Set two fields in the SR node's config.conf:

# When the SR has delegated witness permission, set:
#   localWitnessAccountAddress = the SR account address
#   localwitnesskeystore       = an encrypted keystore for the delegated signing key

localWitnessAccountAddress = TTxrh32VJveqiYRwbLEX2wLTMFCfbpAUQj

localwitnesskeystore = [
  "localwitnesskeystore.json"
]
FieldSet to
localWitnessAccountAddressThe SR's account address (the one ranked in the active 27 by votes).
localwitnesskeystoreEncrypted keystore containing the delegated signing key. Production deployments should prefer this (see SR best practices: protect keystore files).
localwitnessRaw private key of the delegated signing address. Configure it only when an encrypted keystore cannot be used.

If you did not delegate witness permission — meaning the SR account's witness_permission still authorizes its own address, the same key as owner_permission — leave localWitnessAccountAddress empty and configure localwitness (or localwitnesskeystore) with the SR account's own private key.

Start the node

Start a Fullnode with the --witness flag to enable block production. Select the JDK and JVM options for the host CPU architecture. The following examples use the recommended 64 GB SR host configuration:

# x86_64 / amd64: JDK 8
java -Xms9G -Xmx24G -XX:+UseConcMarkSweepGC -jar FullNode.jar --witness -c config.conf

# ARM64 / aarch64: JDK 17
java -Xmx24G -XX:+UseZGC -jar FullNode.jar --witness -c config.conf

For long-running operation, also configure the complete JVM options for the host architecture. See Deploy a Fullnode or Super Representative node.

When the node is scheduled to produce a block, it uses the Witness key loaded through localwitness or localwitnesskeystore and writes the signature into block_header.witness_signature.

Verify block production

Confirm the delegation is actually being used:

  • Node log. Look for produce block successfully lines emitted at your scheduled slots.
  • On-chain query. Use wallet/getblockbylimitnext to fetch recent blocks and check that the witness_address in blocks produced by your slot matches the SR account address.
  • TronScan. The SR's TronScan profile shows recent block production rate and detailed block production information.

Related resources