mcp door: mint workspace-owner service session for team runtime bearer
The runtime template's static clawmates_door bearer is rejected by cm_auth::authenticate() (needs an auth_sessions row). Every per-team agent was getting `unauthorized: missing or invalid bearer token` and `0 tool(s) registered from 0 server(s)`. Add AuthService::mint_service_session + users::owner_of_workspace and mint a 30d service session in try_team_gateway_url; inject it into the freshly-spawned team container's config.toml [[mcp.servers]] clawmates Authorization header via prewrite_daemon_config_with_risk (bearer arg). Follow-up: apply the same pattern to research::spawn (per-topic) and per-loop spawn paths. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
8cd0c7bd01
commit
49f94a5360
@@ -676,12 +676,26 @@ async fn try_team_gateway_url(
|
||||
})
|
||||
.ok()?;
|
||||
let state_root = crate::research_container::team_state_root(team_id);
|
||||
|
||||
// Mint a workspace-owner service session so the team runtime's
|
||||
// clawmates_door MCP calls pass cm-auth (the static bearer baked
|
||||
// into the template config isn't a valid auth_sessions row and
|
||||
// gets 401'd, leaving every agent with 0 tools).
|
||||
let mcp_bearer = mint_workspace_service_token(pool, workspace_id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
eprintln!("try_team_gateway_url: mint MCP bearer failed for team {team_id}: {e}");
|
||||
e
|
||||
})
|
||||
.ok();
|
||||
|
||||
let spawned = crate::research_container::spawn_team(
|
||||
&docker,
|
||||
team_id,
|
||||
std::path::Path::new(&repo_path),
|
||||
&state_root,
|
||||
risk_profile.as_deref(),
|
||||
mcp_bearer.as_deref(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
@@ -705,3 +719,22 @@ async fn try_team_gateway_url(
|
||||
|
||||
Some(spawned.gateway_url)
|
||||
}
|
||||
|
||||
/// Mint a long-lived session token for the workspace owner. Used to
|
||||
/// authorize internal service callers (e.g. per-team ZeroClaw runtimes
|
||||
/// hitting our clawmates_door MCP endpoint) without threading a real
|
||||
/// user session through the runtime template.
|
||||
async fn mint_workspace_service_token(
|
||||
pool: &PgPool,
|
||||
workspace_id: WorkspaceId,
|
||||
) -> Result<String, String> {
|
||||
let owner = cm_db::repo::users::owner_of_workspace(pool, workspace_id)
|
||||
.await
|
||||
.map_err(|e| format!("owner_of_workspace: {e}"))?;
|
||||
let auth = cm_auth::AuthService::new(pool.clone());
|
||||
let token = auth
|
||||
.mint_service_session(owner, time::Duration::days(30))
|
||||
.await
|
||||
.map_err(|e| format!("mint_service_session: {e}"))?;
|
||||
Ok(token.secret().to_string())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user