Provision a dedicated service account for autonomous triggers

What does this MR do and why?

Sets autonomous_service_account_id when a catalog trigger carries only autonomous event types, so a scheduled trigger and an interactive trigger can live on the same flow. The shared account keeps composite identity and is untouched.

  • The dedicated account is provisioned on demand and joins the project as Planner. Choosing a different role, and the ceiling that constrains it, are in !253667.
  • Accounts may be shared between triggers. Project access is revoked once no autonomous trigger points at the account.
  • An account acting alone derives Duo entitlement from the namespace, since it cannot hold an add-on seat.
  • Behind the autonomous_service_account_execution feature flag, which already gates the scheduled event type on master.

Design rationale, alternatives considered, and the path to SA+SA are in #617178 (comment 3751492736).

Related: #594180

Stack

  1. !251852 — column and model
  2. This MR — provisioning services and the entitlement policy
  3. !253667 — choosing the role, and the ceiling
  4. !253636serviceAccountAccessLevel GraphQL argument

Testing

ee/spec/services/ai/flow_triggers/dedicated_autonomous_service_account_spec.rb covers the behaviour end to end: an interactive and a scheduled trigger on one flow, composite identity on for the shared account and off for the dedicated one, the Planner default, account reuse on update, rollback when the trigger fails validation, revocation on delete, and rejection when the flag is off.

409 examples pass across ee/spec/services/ai/flow_triggers/ and the model spec.

Query

Ai::FlowTrigger.autonomous_for_service_account? is the only new query. It runs from DestroyService and from the duo_workflow_available policy condition, and the policy only reaches it for a service account with composite_identity_enforced == false under the feature flag. Human users return earlier. Plans are in !251852, which adds the index.

Edited by Eduardo Bonet

Merge request reports

Loading
Loading