Automate User, Group, and Access Management from Inside Flows

For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append .md to any kestra.io/docs/* URL for plain Markdown.

Automate Identity and Access Management (IAM) operations from inside a Kestra flow using the io.kestra.plugin.kestra.ee.iam task family.

These tasks let you manage users, groups, roles, bindings, service accounts, invitations, and tenant access programmatically — enabling event-driven onboarding from HR webhooks, scheduled access reviews, and automated service account provisioning.

Authentication

All IAM tasks inherit kestraUrl and auth from AbstractKestraTask.

  • kestraUrl defaults to {{ kestra.url }}, which resolves to the current Kestra instance. Omit it when targeting the same instance.
  • auth is required. Use an API token stored as a secret:
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"

The API token must belong to a user or service account with the appropriate IAM permissions for the operations the flow performs.

Onboard a user

This flow is triggered by a webhook — for example, from an HRIS system when a new employee is added. It invites the user to the tenant and assigns them to an existing group in a single task.

id: onboard_user
namespace: company.iam
editions: ["EE", "Cloud"]
inputs:
- id: email
type: STRING
description: New user's email address
- id: group_id
type: STRING
description: ID of the group to assign the user to
tasks:
- id: invite
type: io.kestra.plugin.kestra.ee.iam.invitations.Create
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
email: "{{ inputs.email }}"
groupIds:
- "{{ inputs.group_id }}"
triggers:
- id: from_hris
type: io.kestra.plugin.core.trigger.Webhook
key: "{{ secret('ONBOARD_WEBHOOK_KEY') }}"

The task outputs invitationId, which you can chain into downstream tasks if needed. If an email server is configured in Kestra, the user receives an invitation email automatically. Otherwise, retrieve the invitation link from the IAM page to share manually.

Offboard a user

This flow removes a user from a group and revokes their tenant access. Both steps require the user’s internal userId — retrieve it from the IAM Users page or via your IdP integration.

id: offboard_user
namespace: company.iam
inputs:
- id: user_id
type: STRING
description: Internal Kestra user ID
- id: group_id
type: STRING
description: ID of the group to remove the user from
tasks:
- id: remove_from_group
type: io.kestra.plugin.kestra.ee.iam.groups.RemoveMember
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
groupId: "{{ inputs.group_id }}"
userId: "{{ inputs.user_id }}"
- id: revoke_access
type: io.kestra.plugin.kestra.ee.iam.tenantAccess.Delete
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
userId: "{{ inputs.user_id }}"
triggers:
- id: from_hris
type: io.kestra.plugin.core.trigger.Webhook
key: "{{ secret('OFFBOARD_WEBHOOK_KEY') }}"

Provision a service account for CI/CD

This flow creates a service account and attaches a role to it. It outputs the service account ID so you can use it in downstream automation — for example, to generate an API token or configure a CI/CD secret.

id: provision_service_account
namespace: company.iam
inputs:
- id: name
type: STRING
description: Service account name
- id: role_id
type: STRING
description: Role ID to assign
tasks:
- id: create_sa
type: io.kestra.plugin.kestra.ee.iam.serviceAccounts.Set
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
name: "{{ inputs.name }}"
- id: bind_role
type: io.kestra.plugin.kestra.ee.iam.bindings.Set
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
subjectType: USER
externalId: "{{ outputs.create_sa.id }}"
roleId: "{{ inputs.role_id }}"
outputs:
- id: service_account_id
type: STRING
value: "{{ outputs.create_sa.id }}"

serviceAccounts.Set upserts by name — running the flow again with the same name updates the existing service account rather than creating a duplicate.

Create and manage groups

Use groups.Set to create or update a group, then manage membership with groups.AddMember and groups.RemoveMember.

tasks:
- id: create_group
type: io.kestra.plugin.kestra.ee.iam.groups.Set
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
name: data-engineering
groupDescription: "Data Engineering team"
- id: add_member
type: io.kestra.plugin.kestra.ee.iam.groups.AddMember
auth:
apiToken: "{{ secret('KESTRA_API_TOKEN') }}"
groupId: "{{ outputs.create_group.id }}"
userId: "{{ inputs.user_id }}"

Like serviceAccounts.Set, groups.Set upserts by name and outputs the group id for chaining.

Available IAM tasks

TaskPurpose
io.kestra.plugin.kestra.ee.iam.invitations.CreateInvite a user; optionally assign to groups
io.kestra.plugin.kestra.ee.iam.invitations.ListList pending invitations
io.kestra.plugin.kestra.ee.iam.invitations.DeleteCancel a pending invitation
io.kestra.plugin.kestra.ee.iam.groups.SetCreate or update a group (upsert by name)
io.kestra.plugin.kestra.ee.iam.groups.ListList groups
io.kestra.plugin.kestra.ee.iam.groups.DeleteDelete a group by ID
io.kestra.plugin.kestra.ee.iam.groups.AddMemberAdd a user to a group
io.kestra.plugin.kestra.ee.iam.groups.RemoveMemberRemove a user from a group
io.kestra.plugin.kestra.ee.iam.roles.SetCreate or update a role (upsert by name)
io.kestra.plugin.kestra.ee.iam.roles.ListList roles
io.kestra.plugin.kestra.ee.iam.roles.DeleteDelete a role by ID
io.kestra.plugin.kestra.ee.iam.bindings.SetAttach a role to a user or group (use USER for service accounts)
io.kestra.plugin.kestra.ee.iam.serviceAccounts.SetCreate or update a service account (upsert by name)
io.kestra.plugin.kestra.ee.iam.serviceAccounts.ListList service accounts
io.kestra.plugin.kestra.ee.iam.serviceAccounts.DeleteDelete a service account by ID
io.kestra.plugin.kestra.ee.iam.tenantAccess.SetGrant a user access to the tenant by email
io.kestra.plugin.kestra.ee.iam.tenantAccess.DeleteRevoke a user’s tenant access by user ID

For full property reference, see the plugin-kestra documentation.

Was this page helpful?