IBM · Arazzo Workflow

IBM Cloud IAM Change the Roles on an Existing Policy

Version 1.0.0

Read a policy, resolve the target role CRN from the service, and replace the policy's roles.

1 workflow 1 source API 1 provider
View Spec View on GitHub API ManagementArtificial IntelligenceBillingCloud ComputingContainersData GovernanceDatabasesDevOpsEnterpriseGenerative AIHybrid CloudInfrastructureMachine LearningNetworkingObservabilitySecurityServerlessStorageWatsonWatsonxFortune 100ArazzoWorkflows

Provider

ibm

Workflows

change-policy-roles
Replace an existing policy's roles while preserving its subjects and resources.
Reads the current policy, lists the roles available for the service to confirm the target role CRN is grantable, and replaces the policy with the new role bound to the original subjects and resources.
3 steps inputs: accountId, changeDescription, ifMatch, newRoleCrn, policyId, serviceName outputs: policyId, previousRoles, state, updatedRoles
1
readCurrentPolicy
getPolicy
Read the policy as it stands. The subjects and resources captured here are carried through the replace unchanged — this step is what prevents the replace from silently rebinding or orphaning the grant.
2
resolveTargetRole
listRoles
List the roles the service exposes so the incoming role CRN can be checked against what is actually grantable, rather than discovering it is invalid when the replace rejects the whole policy.
3
replacePolicyRoles
replacePolicy
Replace the policy with the new role, reusing the type, subjects, and resources read from the live policy. Everything not restated in this body is lost, which is why nothing here is reconstructed from assumptions.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: IBM Cloud IAM Change the Roles on an Existing Policy
  summary: Read a policy, resolve the target role CRN from the service, and replace the policy's roles.
  description: >-
    The most common access change there is: someone has Viewer and needs Writer, or
    holds Editor and should be narrowed to Reader. IBM Cloud has no endpoint that
    patches the roles on a policy, so the whole policy must be replaced — which
    makes it dangerously easy to drop the subject or resource by resubmitting an
    incomplete body. This workflow reads the policy first, resolves the role CRN
    against the roles the service genuinely exposes, and replaces the policy while
    carrying the original subject and resource through unchanged. Every step spells
    out its request inline so the flow can be read and executed without opening the
    underlying OpenAPI description.
  version: 1.0.0
sourceDescriptions:
- name: ibmCloudIamApi
  url: ../openapi/ibm-cloud-iam.yml
  type: openapi
workflows:
- workflowId: change-policy-roles
  summary: Replace an existing policy's roles while preserving its subjects and resources.
  description: >-
    Reads the current policy, lists the roles available for the service to confirm
    the target role CRN is grantable, and replaces the policy with the new role
    bound to the original subjects and resources.
  inputs:
    type: object
    required:
    - accountId
    - policyId
    - serviceName
    - newRoleCrn
    - ifMatch
    properties:
      accountId:
        type: string
        description: The IBM Cloud account ID the policy is scoped to.
      policyId:
        type: string
        description: The unique identifier of the policy whose roles are changing.
      serviceName:
        type: string
        description: The service the policy grants access to, used to resolve grantable roles.
      newRoleCrn:
        type: string
        description: >-
          The CRN of the role that should replace the policy's current roles (e.g.
          "crn:v1:bluemix:public:iam::::role:Editor").
      ifMatch:
        type: string
        description: >-
          The entity tag from a previous GET of this policy, used for optimistic
          concurrency control. Note that this API description does not model an
          entity tag on the Policy schema, so the value has to be taken from the
          GET response's ETag header rather than its body.
      changeDescription:
        type: string
        description: A description recording why the role changed and who approved it.
  steps:
  - stepId: readCurrentPolicy
    description: >-
      Read the policy as it stands. The subjects and resources captured here are
      carried through the replace unchanged — this step is what prevents the
      replace from silently rebinding or orphaning the grant.
    operationId: getPolicy
    parameters:
    - name: policy_id
      in: path
      value: $inputs.policyId
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.state == 'active'
      type: jsonpath
    outputs:
      policyType: $response.body#/type
      currentSubjects: $response.body#/subjects
      currentRoles: $response.body#/roles
      currentResources: $response.body#/resources
      lastModifiedAt: $response.body#/last_modified_at
  - stepId: resolveTargetRole
    description: >-
      List the roles the service exposes so the incoming role CRN can be checked
      against what is actually grantable, rather than discovering it is invalid
      when the replace rejects the whole policy.
    operationId: listRoles
    parameters:
    - name: account_id
      in: query
      value: $inputs.accountId
    - name: service_name
      in: query
      value: $inputs.serviceName
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      systemRoles: $response.body#/system_roles
      serviceRoles: $response.body#/service_roles
      customRoles: $response.body#/custom_roles
  - stepId: replacePolicyRoles
    description: >-
      Replace the policy with the new role, reusing the type, subjects, and
      resources read from the live policy. Everything not restated in this body is
      lost, which is why nothing here is reconstructed from assumptions.
    operationId: replacePolicy
    parameters:
    - name: policy_id
      in: path
      value: $inputs.policyId
    - name: If-Match
      in: header
      value: $inputs.ifMatch
    requestBody:
      contentType: application/json
      payload:
        type: $steps.readCurrentPolicy.outputs.policyType
        description: $inputs.changeDescription
        subjects: $steps.readCurrentPolicy.outputs.currentSubjects
        resources: $steps.readCurrentPolicy.outputs.currentResources
        roles:
        - role_id: $inputs.newRoleCrn
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      policyId: $response.body#/id
      updatedRoles: $response.body#/roles
      state: $response.body#/state
      lastModifiedAt: $response.body#/last_modified_at
  outputs:
    policyId: $steps.replacePolicyRoles.outputs.policyId
    previousRoles: $steps.readCurrentPolicy.outputs.currentRoles
    updatedRoles: $steps.replacePolicyRoles.outputs.updatedRoles
    state: $steps.replacePolicyRoles.outputs.state