Summary
When a deployment task is triggered with a bot token, the resulting deployment_tasks row records no acting identity at all. There is no acting_bot_id column, and the two columns that do exist are both left null for bots — so a bot's actions are unattributable in the audit trail / History tab.
Details
deployment_tasks has only two "acting" columns: acting_user_id and acting_deployment_id. The task-create handler populates them straight from the identity:
// api/src/routes/v2/deployment_tasks.rs
let task = NewDeploymentTask {
// ...
acting_user_id: identity.inner().user_id(),
acting_deployment_id: identity.inner().deployment_id(),
// ...
};
But Identity only exposes user_id() and deployment_id(), both of which return None for the Bot variant:
// db/src/identity.rs
pub enum Identity { User(Uuid), Bot(Uuid), Deployment(Uuid) }
// user_id() -> Some only for User
// deployment_id() -> Some only for Deployment
So a Bot-triggered task gets acting_user_id = NULL and acting_deployment_id = NULL: it isn't tied to the bot, or to anything. The bot's id exists (bots table, and bot_tokens.bot_id), but it's never written onto the task.
Impact
- No per-actor audit trail for automation that uses bot tokens — you can't answer "which bot deployed this?".
- Undercuts a primary reason to use bots over shared user tokens.
Suggested fix
- Add an
acting_bot_id uuid column to deployment_tasks (nullable, FK to bots(id)), plus the matching cancel column if relevant (canceled_by_bot_id).
- Add
Identity::bot_id() and populate acting_bot_id in the task-create (and cancel) handlers.
- Surface the bot actor in the History UI alongside user/deployment actors.
Related (separate, but adjacent)
api/src/permissions/deployments.rs verify_deployment_maintainer has a // TODO: Add bot permissions and currently lets any valid bot token through the maintainer check. Worth tracking the per-bot permission model alongside this, though the audit-attribution gap above can be fixed independently.
References
api/src/routes/v2/deployment_tasks.rs (task create — acting_* assignment)
db/src/identity.rs (Identity, user_id(), deployment_id())
db/src/schema/deployment_task.rs (columns)
api/src/permissions/deployments.rs (related bot-permission TODO)
Summary
When a deployment task is triggered with a bot token, the resulting
deployment_tasksrow records no acting identity at all. There is noacting_bot_idcolumn, and the two columns that do exist are both left null for bots — so a bot's actions are unattributable in the audit trail / History tab.Details
deployment_taskshas only two "acting" columns:acting_user_idandacting_deployment_id. The task-create handler populates them straight from the identity:But
Identityonly exposesuser_id()anddeployment_id(), both of which returnNonefor theBotvariant:So a
Bot-triggered task getsacting_user_id = NULLandacting_deployment_id = NULL: it isn't tied to the bot, or to anything. The bot's id exists (botstable, andbot_tokens.bot_id), but it's never written onto the task.Impact
Suggested fix
acting_bot_id uuidcolumn todeployment_tasks(nullable, FK tobots(id)), plus the matching cancel column if relevant (canceled_by_bot_id).Identity::bot_id()and populateacting_bot_idin the task-create (and cancel) handlers.Related (separate, but adjacent)
api/src/permissions/deployments.rsverify_deployment_maintainerhas a// TODO: Add bot permissionsand currently lets any valid bot token through the maintainer check. Worth tracking the per-bot permission model alongside this, though the audit-attribution gap above can be fixed independently.References
api/src/routes/v2/deployment_tasks.rs(task create —acting_*assignment)db/src/identity.rs(Identity,user_id(),deployment_id())db/src/schema/deployment_task.rs(columns)api/src/permissions/deployments.rs(related bot-permission TODO)