Public identity, server commands, and ACL
Exporting a public identity, whitelisting a player, and declaring restricted server commands behind the access control list.
Server-side Lua commands are typed straight into the CyberM developer terminal in game (²). A
command the client knows stays local; anything else is forwarded to the server over the
authenticated network session, then looked up among the RegisterCommand registrations of the Lua
resources.
Use this guide to whitelist a player, restrict a command to specific people, and understand what identity the server actually trusts.
Exporting your public identity
In the CyberM terminal:
identity.dump
The reply gives the absolute path and the SHA-256 fingerprint:
OK identity_public_dumped path=".../red4ext/plugins/CyberM/exports/identity-<uuid>.json" fingerprint=sha256:...
The file holds the userId, the P-256 public key, its fingerprint, and a ready-to-copy
aclPrincipal object. It never holds the private key, the DPAPI blob, the session proof, or the
%LOCALAPPDATA%/CyberM/identity-v1.dat file. Do not copy that last one to the server.
Whitelisting a player
The server loads the relative file configured in server.jsonc:
"accessControl": {
"file": "acl.jsonc"
}
Copy the exported aclPrincipal value into principals:
{
"version": 1,
"principals": [
{
"name": "owner",
"userId": "00000000-0000-0000-0000-000000000000",
"publicKey": "base64...",
"permissions": [
"command.loot.*"
]
}
]
}
Restart the server, or type acl.reload in its administration console. acl.list reports the path
actually loaded; acl.check <playerId> <permission> is there for diagnosis.
The comparison is made on the 64 bytes of public key certified during the handshake. If the entry
also carries a userId, that must match too. The displayed nickname and the temporary playerId
never take part in authorisation.
Declaring a restricted command
RegisterCommand("garage.delete", function(source, args, rawCommand)
-- source is the playerId of the authenticated session, or 0 for the server console.
end, true)
From a client, this command requires command.garage.delete. An exact permission, *, or a
trailing wildcard such as command.garage.* will grant it. The dedicated console uses source=0
and stays authorised for local administration.
The transport caps a line at 32 tokens and each token at 256 UTF-8 bytes, validates the command
name, and reuses the network limit of 32 events per second. Refusals and results come back to the
CyberM terminal through cyberm:command:result.
For agents and LLMs: this page as Markdown · llms.txt · llms-full.txt
