fix: split WriteAgentStateFile into WriteAgentForgeToken + WriteAgentMatrixToken

Addresses mara's review: each credential type gets its own PrivRequest
variant, making the exact priv surface visible in the wire protocol.
No runtime filename dispatch — the operation name is the gate.

- WriteAgentForgeToken { agent_name, token } → state/forge-token
- WriteAgentMatrixToken { agent_name, token } → state/matrix-token
- priv_client: two typed fns (write_agent_forge_token, write_agent_matrix_token)
- forge.rs: split mint_and_persist_token into mint_and_persist_agent_token
  (priv) + mint_and_persist_core_token (direct write); drop dead token_path fn
- matrix.rs: call write_agent_matrix_token directly
This commit is contained in:
atlas 2026-06-04 13:53:43 +02:00 committed by mara
commit 7022cd3826
5 changed files with 73 additions and 92 deletions

View file

@ -229,29 +229,29 @@ pub enum PrivRequest {
args: Vec<String>,
},
// --- Agent state file writes ---
/// Write a credential file into an agent's bind-mounted state directory.
// --- Agent credential writes ---
/// Write `forge-token` into `AGENT_STATE_ROOT/<agent_name>/state/forge-token`.
///
/// Path resolved by hive-priv: `AGENT_STATE_ROOT/<agent_name>/state/<filename>`.
/// hive-priv validates both the agent name and filename before writing.
///
/// After writing, the file is chowned to the agent user's uid/gid
/// (read from the state directory's owner) and chmoded 0600 so
/// only the agent process can read it.
///
/// Required because hive-c0re runs as the unprivileged `hive-core`
/// user and cannot write to agent-owned (0755) state directories
/// after the privsep that moved c0re from root to a dedicated unix user.
WriteAgentStateFile {
/// hive-priv validates `agent_name`, creates the state dir if absent,
/// writes the file 0600, and chowns it to the state dir's owner so
/// the agent process can read it. Required because hive-c0re runs
/// unprivileged and cannot write to agent-owned state directories.
WriteAgentForgeToken {
/// Logical agent name (validated by `validate_agent_name`).
agent_name: String,
/// Allowlisted credential filename within the state dir.
/// Only `"forge-token"` and `"matrix-token"` are accepted;
/// hive-priv rejects any other value.
filename: String,
/// File content to write. Written as-is; caller is responsible for
/// including any trailing newline.
content: String,
/// Token value. hive-priv appends a trailing newline before writing.
token: String,
},
/// Write `matrix-token` into `AGENT_STATE_ROOT/<agent_name>/state/matrix-token`.
///
/// Same semantics as `WriteAgentForgeToken` — validates name, creates
/// dir, writes 0600, chowns to agent owner.
WriteAgentMatrixToken {
/// Logical agent name (validated by `validate_agent_name`).
agent_name: String,
/// Token value. hive-priv appends a trailing newline before writing.
token: String,
},
}