Appearance
Session Credentials
Every terminal, chat, team member and task run that Clusto starts needs a way to talk back to its daemon: the clusto CLI inside the session, the chat and team tools, the report and notes tools, the hooks. That access is a token in the session's environment (CLUSTO_TOKEN, also set as HIVE_TOKEN).
By default that token is the node's admin token. When a session runs as another operating-system account (a project's Run As, or the node's default_session_user), handing it the admin token would let anything running as that account control the whole node. Session credentials close that gap: a session that runs as a non-root account gets a limited credential that works only on this machine and only while the session lives.
Who gets which credential
| Session | Credential |
|---|---|
| Runs as root, or as the account the daemon itself runs as | The node admin token. That account can read config.toml anyway, so nothing is gained by limiting it |
Runs as any other account (Run As, default_session_user) | A limited agent credential |
| Any Clusto Assistant chat | A narrower assistant credential, whatever account it runs as |
The access file local-daemon.toml of another account | A limited agent credential (see below) |
On Windows every Run As session counts as another account, so it gets a limited credential.
The credential is minted when the session starts and is not stored anywhere. It looks like cst1.<payload>.<signature>: it names the account and the session, and is signed with a key derived from the node admin token and the node id. Rotating the admin token therefore revokes every credential at once, and a credential minted on one node is not accepted by another node of the cluster.
The access file
Clusto writes local-daemon.toml in each account's Clusto config directory (~/.config/clusto/ on Linux) so the clusto CLI works out of the box for that account. For an account other than the daemon's, that file now holds a limited agent credential instead of the admin token, because every process of the account can read it. As a result:
clusto daemon get-tokenprints the credential that account holds. To get the admin token run it withsudo, or read it from the node'sconfig.toml.- Commands that need admin rights (see below) fail for that account until you pass the admin token:
clusto --token "$T" ..., a saved profile, or run them from the Clusto app. - If the credential is re-issued for a different account, the previous one stops working.
What a limited credential can do
Both kinds can list and read: sessions, projects, teams, tasks, reports, notes (read, search and write), and the cluster status. A chat can also rename itself and read its own context.
The agent credential also allows:
- posting and updating reports and attachments;
- reading and proposing lessons (approving lessons is done in the app);
- reading team details and rosters, and setting the session's own attention state;
- managing teams and tasks that run as the same account (below), and killing, renaming or tagging sessions of that account.
The assistant credential also allows reading the cluster configuration, task run history, the GitHub and Azure DevOps snapshots and the daemon log, and proposing an action inside its own chat. Actions still wait for your approval in the app.
A limited credential cannot: open a terminal or send input to one (clusto new, open, send, attach, export, adopt), read or write files or run git operations through the daemon, change projects, agent docs or settings, change the cluster, SSH connections or updates, approve lessons, control chats, or link a node to your account. It receives none of the live broadcast updates other clients get, never receives the cluster token, and sees task environment values masked.
The same-account rule
Anything that starts work must run as the account the credential belongs to, and only on the node the credential was issued by:
- Creating or changing a team requires the team's account to be the same as the session's, every live member to run as that account on this node, and the team's working directory to be owned by that account.
- Creating, changing, triggering or cancelling a task requires the task to belong to this node and its runs to resolve to the same account (the project's Run As, else
default_session_user). Taskenvmay not set loader and runtime variables such asLD_PRELOAD,LD_LIBRARY_PATH,GLIBC_TUNABLES,MALLOC_*orDYLD_*. - Killing, renaming or tagging a session works for the session itself and for sessions of this node that run as the same account.
- Requests aimed at another node are refused.
If an agent needs to start work as a different account, set the project's Run As (or the node's default session user) to the agent's account, or do it from the app.
Where it is accepted, and how it ends
- Local only. The daemon accepts a session credential only from the machine it runs on (loopback or one of the host's own addresses). It is useless from the tunnel, the web relay or another host. A reverse proxy on the same host makes remote clients look local, so do not put one in front of the client port.
- It dies with its session. A credential bound to a session stops working once the session ends (killed, exited or removed). A connection that is already open is closed within about 15 seconds. The access-file credential lasts as long as it is the current one for its account.
- Wrong token versus expired. A leftover helper that presents an ended session's credential gets "session credential expired: its session ended", not "invalid token", and does not count as a failed login.
Messages you may see
| Message | Meaning |
|---|---|
<request> is not permitted with a session credential. ... | The action is on the denied list. Run it from the app or with the admin token |
<request> would run as <account> on this node, but this session credential belongs to <other> | The same-account rule. Set Run As to the session's account, or use the admin token |
<request> is refused: a session credential only controls work on its own node | The target is on another node |
<request> is refused: <dir> is not owned by <account> | A team's working directory belongs to someone else |
session credential expired: its session ended | The session the credential belonged to is gone |
Running admin commands
A limited session cannot do admin work, by design. To run an admin command yourself, use the app, or pass the node admin token explicitly with the global --token flag (it goes before the subcommand) or CLUSTO_TOKEN. Prefer a saved profile that you create once outside the session: a --token value on a command line can be read by other local users in the process list.
bash
clusto profile add admin --token "$ADMIN_TOKEN" # run once, outside the session
clusto --profile admin new --dir /srv/projectDo this only for accounts you trust with the whole node.
The release flag
Minting limited credentials is controlled by the security.session_credentials release flag (node scope). It is off by default: with the flag off every session keeps the admin token exactly as before, and the credentials described above are not issued. Verification and the permission checks are always on, so a limited credential is enforced as soon as one exists.
Turn it on for a node with the [features] table in its config.toml, or remotely through the published flags.json (see Feature Flags):
toml
[features]
"security.session_credentials" = trueSessions started after the change get the new credential. The flag is removed in 1.16, and limited credentials then become the behavior.