Access and roles

Using your node: access and roles.

A single Semurg node ships as a sovereign appliance. It listens on plaintext HTTP at port 4000 and, by default, does not authenticate callers, does not terminate TLS, and does not install a firewall.

Read and write endpoints are reachable by anyone who can reach the port, so you must run the node behind your own network perimeter: bind it to localhost or a private interface, put TLS and access control in front of it, and firewall the port. The one hard guarantee the engine enforces itself is single-writer safety: a POSIX file lock prevents a second process from opening the write log and corrupting your data, so only one writer is ever live.

Write access today is an instance-level licence capability, not a per-user permission: the free single-node build is fully writable by design, and the node does not yet distinguish read-only, read-write, or admin clients at the request boundary. Administration is performed on the host itself through systemd and the node's control shell, which anyone with operating-system access to the machine controls. Per-user and per-scope authorization is on the roadmap and is not enforced in this release.

Treat network reachability to port 4000 as full access to the node.
The real protection today

Run it behind your perimeter.

The node does not protect itself at the network. Your perimeter is the access control that actually exists on the day you download it, so put it in place before you expose the port.

  • Bind the node to 127.0.0.1 or a private interface, not a public one.
  • Put TLS and an authenticating reverse proxy in front of it.
  • Firewall port 4000 so only trusted hosts can reach it.
  • Restrict operating-system access and the node's control credentials to the operator.
Enforced at the port

What the node actually distinguishes today.

At the request boundary, one node makes exactly the distinctions below. Everything marked no is your perimeter's job, not the node's.

At the request boundaryEnforced by the node today
Read-only vs read-write vs admin user classesno
Authentication, session, or API keyno
TLS terminationno
Firewall on the portno
Single-writer safety (a second process cannot open the write log and corrupt the store)yes, POSIX file lock
Whether the instance accepts writes at all (a licence capability, instance-wide)yes, not per-caller
The one hard guarantee is single-writer safety. It is a durability guard that stops a second writer process from corrupting your data. It is not a request authorization, and it does not distinguish one caller from another.
Role 1 · Admin

Administers the host, not an app role.

How you interact today

Administration happens on the machine, not through an application login. You manage the service with systemd (systemctl start / stop / restart / status semurg) and read its logs with journalctl. You change configuration by editing /etc/semurg/semurg.env. The node's control shell, bin/r11 remote, is a full administrative console with total control over the running node, gated only by operating-system permissions on the node's control credentials. SEMURG_BENCH_ADMIN_TOKEN gates dataset-load.

What is enforced

The enforced control boundary is operating-system access to the box: the login shell plus the node's control credentials. Anyone with OS access to the machine controls it.

Honest gap. There is no admin identity and no admin login at the HTTP boundary. The in-app admin console is not wired in this release.
Role 2 · Non-admin user

Someone on the same network who is not the operator.

How you interact today

A non-operator on the same network reaches the same :4000 routes as everyone else, with no session, no token, and no API key.

What is enforced

Nothing distinguishes them from the operator at the request boundary. The request rate-limiter is denial-of-service protection, not authentication.

Honest gap. On a node reachable over the network, a non-operator is indistinguishable from the operator. Your network perimeter is the boundary.
Role 3 · Read-only user

The read surface, and why read-only is not a per-client class.

How you interact today

The read surface is GET /v1/status, POST /v1/query (fetch, resolve, search, histogram), and the GET /api/* reads.

What is enforced

Read-only is not a per-client class today. Whether a node accepts writes is an instance-wide property of its licence, not a per-caller permission.

Honest gap. You cannot issue a read-only credential to a person on a single node yet. The node is read-write for every caller, or (a build without the write capability) read-only for every caller.
Role 4 · Read-write (full) user

Full access, and why every reachable client has it.

How you interact today

Writes go through POST /v1/ingest, a batch of uniform containers appended to the store.

What is enforced

The write path checks one instance-level licence capability, and the free build ships that capability on by design, so the endpoint is writable by any caller that can reach the port. The single-writer file lock prevents a second writer process from corrupting the store, but it is a durability guard, not a request authorization.

Honest gap. Full-user is not a per-user class. Every reachable client is a full user.
On the roadmap

Designed, not yet enforced.

Not enforced in this release
  • Per-request capability tokens that derive read, write, and admin rights, deny by default.
  • Localhost binding by default, so a fresh node is not reachable off the box until you open it.
  • Per-scope stores, so a capability is scoped to one store.

These are on the roadmap and are not enforced in this release. Until they ship, the distinctions above do not exist at the port, and your perimeter is the boundary.