Skip to content

Node Roles

A NOOSChain node is a running server process with local configuration, a database, node identity, chain state, optional consensus participation, sync behavior, observability, and local encrypted-payload availability.

Node roles describe what that process is allowed to do in the chain. They are not the same thing as user permissions, operator authentication, or bucket access.

NOOSChain stores node roles in the consensus nodes table and may also receive a local runtime override through NOOS_NODE_ROLE.

Role Summary

RoleConsensus participationTransaction admissionSync finalized blocksServe permitted readsStore encrypted payload bytes
validatorYes, depending on configured backendYesYesYesDepends on bucket policy and node credentials
observerNo voting or proposalNoYesYesDepends on bucket policy and node credentials
clientReserved for future useTreated as read-onlyFuture/client-facing pathFuture/client-facing pathFuture/client-facing path

The role controls node-level behavior. It does not bypass deterministic chain execution, bucket permissions, operator API authentication, or payload custody rules.

Validator Nodes

A validator node may admit transactions and participate in block production for the configured consensus backend.

Depending on configuration, a validator may run:

Validators still execute the same deterministic chain rules as every other node. Consensus orders blocks; chain execution applies them. A validator cannot directly mutate users, organizations, buckets, records, contracts, permissions, or state roots outside committed block execution.

Validator status also has a governance dimension. A node can exist in the nodes table while validator governance tracks whether a validator is active, suspended, or retired. Runtime Raft membership may also differ from governance intent until an operator reconciles it.

Observer Nodes

An observer node is a first-class sync, read, verification, and audit node. It does not propose blocks, vote, admit new transactions, or create finalized history.

Observers can:

  • Sync finalized blocks from trusted peers.
  • Execute synced blocks locally.
  • Recompute block hashes and state roots.
  • Run replay and verification checks.
  • Serve permitted read APIs.
  • Export snapshots.
  • Perform availability-layer payload backfill when policy allows it.

Observers are useful for:

  • Read scaling
  • Reporting
  • Audit and verification
  • Backup and snapshot workflows
  • Payload availability in trusted deployments
  • Local development topologies where not every node should produce blocks

An observer is not a security bypass. Application reads still require the resolved actor to have the right bucket permissions. Encrypted payload custody still depends on bucket replication policy and verified node membership credentials.

Client Nodes

client is reserved for future application-facing node identities. In the current implementation it is treated as read-only for transaction admission and block production.

Do not treat client as a fully defined production role yet.

How Runtime Role Is Resolved

Runtime role resolution follows this order:

  1. If NOOS_NODE_ROLE is set, it is authoritative for the running server process.
  2. If NOOS_NODE_ROLE is unset and NODE_ID is configured, the server resolves the role from the local consensus nodes table.
  3. Before a node has synced genesis, the role can be unknown.

Read-only enforcement begins once the role is known or explicitly configured. This lets an empty observer bootstrap by syncing genesis from a validator while still refusing transaction admission once its node row exists.

Node Role, Governance, And Runtime Membership

Three related concepts can diverge:

  • Node role: the node's role in the nodes table, or the local NOOS_NODE_ROLE override.
  • Validator governance: consensus-state intent for whether validator nodes are pending, active, suspended, or retired.
  • Runtime membership: the actual voter/non-voter membership used by the configured consensus backend, such as a Raft runtime voter set.

Validator governance transactions update intended validator state. They do not automatically hot-reconfigure every current Raft backend.

HashiCorp Raft can apply explicit operator-approved runtime membership changes through reconciliation workflows. Noosraft still uses configured voters. Observability reports warnings when governance intent and runtime membership diverge.

Node Role Is Not User Permission

Node role answers what the server process may do. User and bucket permissions answer what an application actor may do.

Important boundaries:

  • Being a validator does not automatically grant operator API access.
  • Being an observer does not bypass bucket permissions.
  • Operator observability requires operator authentication, normally NOOS_OPERATOR_TOKEN.
  • Bucket metadata reads require bucket:read_metadata.
  • Encrypted payload reads require bucket:read_encrypted.
  • Bucket writes require bucket:write.
  • Bucket administration requires bucket:admin.

See Permission Model for actor and principal rules.

Node Role And Payload Custody

Node role also does not decide encrypted payload custody by itself.

Nodes may sync block, transaction, bucket, and record metadata without being allowed to store encrypted payload bytes. Ciphertext placement depends on the bucket replication policy and verified node membership credentials.

For bucket replication:

  • metadata_only prevents future ciphertext replication and backfill.
  • replicate_encrypted_to_authorized_nodes allows ciphertext only for verified active nodes whose organization has bucket:read_encrypted or bucket:admin, or is the bucket creator organization.
  • replicate_encrypted_to_all_nodes allows ciphertext for verified active syncing nodes.

For per_bucket_key buckets, bucket-key envelope sharing follows the same placement boundary. A raw local organizationId value is not enough; payload replication uses organization-signed node membership credentials and node-key proofs.

See Node Membership Credentials and Data Buckets.

Observer Read-Only Rules

Observer nodes reject state-creating node routes.

Rejected requests include:

  • POST /transactions
  • POST /transactions/gossip
  • POST /consensus/propose-block
  • POST /chain/init when the runtime is explicitly configured as an observer
  • Manual block execution through POST /chain/blocks/:height/execute
  • Bucket convenience routes that internally create signed transactions, such as encrypted upload and bucket-key creation/rotation

Rejected state-changing requests return 403 NODE_ROLE_READ_ONLY.

Observers still allow:

  • GET /chain/head, /chain/blocks, /chain/headers, and /chain/info
  • Chain verification and replay verification
  • HTTP block sync from trusted peers
  • Payload backfill, because it updates only local availability-layer columns and never changes blocks, transactions, SMT roots, or consensus state
  • Protected read APIs when the caller has permission
  • Local operational/admin metadata such as peer scores or incident records

Node observability is separate from node role. /node/observability/* is operator-only and requires the observability operator bearer token documented in Observability API. Validator status or normal user authentication is not enough.

Configuration Examples

Single local validator:

dotenv
NODE_ID=node-validator-1
NOOS_NODE_ROLE=validator
NOOS_CONSENSUS_MODE=single_node

Validator in a Raft cluster:

dotenv
NODE_ID=node-a
NOOS_NODE_ROLE=validator
NOOS_CONSENSUS_MODE=raft
RAFT_ENGINE=noosraft
RAFT_NODE_ID=node-a
RAFT_VOTER_NODE_IDS=node-a,node-b,node-c

Observer that syncs from trusted peers:

dotenv
NODE_ID=node-observer-1
NOOS_NODE_ROLE=observer
NODE_SYNC_ENABLED=true

Production deployments should make the intended role explicit instead of depending on an unknown pre-sync role.

Inspect Node Role And Health

Useful operator commands:

powershell
npm run noos -- node overview
npm run noos -- node health
npm run noos -- raft status
npm run noos -- governance validators
npm run noos -- observability sync

For production profile checks:

powershell
npm run noos -- production profile --profile validator
npm run noos -- production profile --profile observer

The profile command checks whether the intended production profile matches the node role, consensus mode, health, and related operational requirements.

Common Deployment Shapes

Single Local Validator

One node runs single_node consensus and builds blocks from its local mempool. This is the simplest local-development shape.

Multi-Validator Raft Cluster

Multiple validators run Raft. The configured backend orders blocks, and every node applies committed blocks through deterministic execution. Current Raft paths are crash-fault-oriented, not BFT.

Observer Read Replica

An observer syncs finalized blocks from validators and serves permitted reads. It does not admit transactions or produce blocks.

Observer For Audit Or Backup

An observer can maintain an independently replayed local copy of finalized history, run verification checks, and export snapshots for recovery workflows.

Future Client-Facing Node

The client role is reserved for future application-facing node identities. Current deployments should use validator or observer roles.

Production Notes

  • Current Raft paths are not Byzantine-fault-tolerant.
  • Observer nodes are read-only for consensus-state creation, not for every HTTP read surface.
  • Operator/admin APIs are protected separately from node role.
  • Payload custody requires bucket policy and verified node credentials, not just local role config.
  • Runtime role, validator governance, and Raft runtime membership should be monitored for divergence.
  • Do not point tests, reset tools, or soak/stability commands at production databases.

Audience-first NOOSChain documentation.