# What Is the RNACOS_CLUSTER_TOKEN? Authenticating r-nacos Cluster Nodes

> Understand RNACOS_CLUSTER_TOKEN for r-nacos cluster node authentication. Learn how this secret token secures gRPC traffic and Raft consensus for authorized instances.

- Repository: [Nacos Group/r-nacos](https://github.com/nacos-group/r-nacos)
- Tags: internals
- Published: 2026-03-07

---

**The RNACOS_CLUSTER_TOKEN environment variable acts as a shared secret that authenticates all gRPC traffic between r-nacos nodes, ensuring only authorized instances can participate in Raft consensus and cluster operations.**

In distributed systems like r-nacos—the Rust implementation of Alibaba's Nacos service discovery platform—securing inter-node communication is critical to prevent unauthorized nodes from joining the cluster or interfering with Raft replication traffic. The **RNACOS_CLUSTER_TOKEN** provides this security layer by functioning as a mandatory bearer token for all internal gRPC requests between cluster members.

## How RNACOS_CLUSTER_TOKEN Secures Inter-Node Communication

### Token Initialization and Configuration

The token is read at startup by `AppSysConfig::init_from_env` in [`src/common/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/common/mod.rs). If the environment variable is set, its value is stored in `AppSysConfig.cluster_token` as an `Arc<String>`; otherwise, the system initializes with an empty string, effectively disabling token validation for that node.

```rust
// src/common/mod.rs (lines 200-204)
let cluster_token = std::env::var("RNACOS_CLUSTER_TOKEN")
    .map(Arc::new)
    .unwrap_or(constant::EMPTY_ARC_STRING.clone());

```

### Outbound Request Authentication

When a node sends Raft-related requests to peers, the `RaftClusterRequestSender::send_request` method in [`src/raft/network/factory.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/raft/network/factory.rs) automatically injects the token. If `cluster_token` is non-empty, it inserts the `"ClusterToken"` header—defined as the constant `CLUSTER_TOKEN` in [`src/grpc/handler/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/grpc/handler/mod.rs)—into the gRPC metadata.

```rust
// src/raft/network/factory.rs (lines 43-48)
if !self.sys_config.cluster_token.is_empty() {
    if let Some(meta) = payload.metadata.as_mut() {
        meta.headers.insert(
            CLUSTER_TOKEN.to_string(),
            self.sys_config.cluster_token.as_str().to_string(),
        );
    }
}

```

### Inbound Token Validation

The receiving node's gRPC server extracts and validates the token in two phases. First, `GrpcServer::handle_meta` in [`src/grpc/server.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/grpc/server.rs) parses the `"ClusterToken"` header from incoming metadata and sets `request_meta.cluster_token_is_valid` to `true` only if the header matches the local `cluster_token`.

```rust
// src/grpc/server.rs (lines 57-65)
if !self.app.sys_config.cluster_token.is_empty() {
    if let Some(Some(token)) = payload.metadata.as_ref()
        .map(|e| e.headers.get(CLUSTER_TOKEN)) {
        request_meta.cluster_token_is_valid =
            token == self.app.sys_config.cluster_token.as_ref();
    }
}

```

Second, `InvokerHandler::handle` in [`src/grpc/handler/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/grpc/handler/mod.rs) enforces the policy: if the token is configured, the request is a cluster-type request, and `cluster_token_is_valid` is `false`, the handler returns a 500 error with the message "request cluster token is invalid".

```rust
// src/grpc/handler/mod.rs (lines 30-40)
if !self.app.sys_config.cluster_token.is_empty()
    && self.is_cluster_request(url)
    && !request_meta.cluster_token_is_valid {
    return Ok(HandlerResult::error(
        500u16,
        "request cluster token is invalid".to_string(),
    ));
}

```

## Configuring the Cluster Token in Production

### Environment Variable Setup

Set the token before starting the r-nacos process. The value should be a cryptographically random string to prevent brute-force attacks:

```bash
export RNACOS_CLUSTER_TOKEN="secure-random-token-string-min-32-chars"

```

### Configuration Loading

As shown in [`src/common/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/common/mod.rs), the startup sequence loads this value exactly once during initialization. Changes to the environment variable after startup have no effect until the process restarts.

## Security Implications of RNACOS_CLUSTER_TOKEN

### Protection Against Unauthorized Cluster Joins

Without a configured token, any node that can reach the gRPC port could potentially send Raft messages to cluster members. The token acts as a preshared key, ensuring that only nodes possessing the secret can initiate cluster communication and participate in consensus operations.

### Failure Modes

If the token is set on one node but not on others, or if values mismatch, the cluster will experience a split-brain scenario. Nodes will log errors like "request cluster token is invalid" and refuse to process Raft requests, leading to leader election failures or replication stalls. Consistency across all nodes is mandatory.

## Summary

- **RNACOS_CLUSTER_TOKEN** is an environment variable that configures a shared secret for r-nacos cluster authentication.
- The token is stored in `AppSysConfig.cluster_token` and injected into outbound gRPC requests via the `ClusterToken` header in [`src/raft/network/factory.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/raft/network/factory.rs).
- Receiving nodes validate the token in [`src/grpc/server.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/grpc/server.rs) and reject unauthorized requests with a 500 error in [`src/grpc/handler/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/grpc/handler/mod.rs).
- Configuring a consistent token across all nodes is mandatory for secure Raft consensus and prevents unauthorized nodes from joining the cluster.

## Frequently Asked Questions

### What happens if I don't set RNACOS_CLUSTER_TOKEN?

If the environment variable is omitted, r-nacos starts with an empty token string. In this mode, the `ClusterToken` header is not added to outbound requests, and inbound token validation is skipped. While the cluster will function, it will accept gRPC traffic from any source, exposing Raft operations to potential interference from unauthorized nodes.

### How long should the RNACOS_CLUSTER_TOKEN value be?

The source code treats the token as an arbitrary string, but for security, use a cryptographically random string of at least 32 characters. The token is transmitted in plaintext inside gRPC metadata, so its strength depends on entropy rather than length alone. Avoid short or predictable values like "password" or "123456".

### Can I rotate the RNACOS_CLUSTER_TOKEN without downtime?

No, token rotation requires a rolling restart of all cluster nodes. Because the token is loaded once at startup via `AppSysConfig::init_from_env` in [`src/common/mod.rs`](https://github.com/nacos-group/r-nacos/blob/main/src/common/mod.rs), changing the environment variable on disk does not affect running processes. To rotate securely, update the token on all nodes and restart them sequentially, ensuring a majority remains available if using Raft consensus.

### Does the cluster token encrypt the gRPC traffic?

No, the `RNACOS_CLUSTER_TOKEN` provides authentication, not encryption. The token is sent as a plaintext header in the gRPC metadata. For transport-layer encryption, you must configure TLS separately on the gRPC endpoints. The token verifies node identity but does not protect against eavesdropping or man-in-the-middle attacks on the network layer.