IBM Cloud Docs
Creating a S2S authorization to grant access to send logs to IBM Cloud Logs

Creating a S2S authorization to grant access to send logs to IBM Cloud Logs

Use IBM Cloud® Identity and Access Management (IAM) to create an authorization that grants IBM Cloud Logs Routing access to IBM Cloud Logs so the IBM Cloud Logs Routing service can send logs to your IBM Cloud Logs instance destination (target).

The IBM Cloud Logs instance that you plan to configure as a target must be located in the same account where you plan to configure IBM Cloud Logs Routing.

Before you begin

The target service is located always in the account where the authorization is created.

The authorization that you define for the IBM Cloud Logs Routing service requires that you have Administrator role for the IBM Cloud Logs target.

If you have the IAM permission to create policies and authorizations, you can grant only the level of access that you have as a user of the target service. For example, if you have viewer access for the target service, you can assign only the viewer role for the authorization. If you attempt to assign a higher permission such as administrator, it might appear that permission is granted, however, only the highest level permission you have for the target service, that is viewer, will be assigned.

Service access roles

You can select any of the following roles that the source can use to interact with the target. You can grant only the level of access that you have as a user of the target that you selected.

  • Sender: As a sender, you can send logs to your IBM Cloud Logs service instance - but not query or tail logs. This role is meant to be used by agents and routers sending logs.

Creating an authorization in the console

Complete the following steps:

  1. In the IBM Cloud console, click Manage > Access (IAM), and select Authorizations.

  2. Click Create.

  3. Configure the source account. Select This account.

  4. Select Logs Routing as the source service. Then, set the scope of the access to All resources.

  5. Select Cloud Logs as the target service. Then, set the scope of the access to All resources or a single instance by configuring Resources based on selected attributes > Service Instance.

    Other attributes are not supported for this type of authorization.

  6. In the Service Access section, select Sender to assign access to the source service that accesses the target service.

  7. Click Authorize.

If you create an authorization between a service in another account and a target service in your current account, you need to have access only to the target resource. For the source account, you need only the account number. 

Creating an authorization by using the CLI

Run the following command to create an authorization for the IBM Cloud Logs service.

ibmcloud iam authorization-policy-create logs-router logs Sender

You can scope a specific IBM Cloud Logs target instance by using [--target-service-instance-name TARGET_SERVICE_INSTANCE_NAME | --target-service-instance-id TARGET_SERVICE_INSTANCE_ID]. Do not provide any other scope options.

For more information about all of the parameters that are available for this command, see ibmcloud iam authorization-policy-create.

Creating an authorization by using Terraform

Before you can create an authorization by using Terraform, make sure that you have completed the following:

  • Install the Terraform CLI and configure the IBM Cloud Provider plug-in for Terraform. For more information, see the tutorial for Getting started with Terraform on IBM Cloud. The plug-in abstracts the IBM Cloud APIs that are used to complete this task.
  • Create a Terraform configuration file that is named main.tf. In this file, you define resources by using HashiCorp Configuration Language. For more information, see the Terraform documentation.

Use the following steps to create an authorization by using Terraform:

  1. Create an authorization policy between services by using the ibm_iam_authorization_policy resource argument in your main.tf file.

    The following example creates an authorization between services:

    resource "ibm_iam_authorization_policy" "policy" {
      source_service_name = "logs-router"
      target_service_name = "logs"
      roles               = ["Sender"]
      description         = "Authorization Policy"
      transaction_id     = "terraformAuthorizationPolicy"
    }
    

    The ibm_iam_authorization_policy resource requires the source service, target service, and role. The source service is granted access to the target service, and the role is the level of permission that the access allows. Optionally, you can add a description for the authorization and a transaction ID.

  2. After you finish building your configuration file, initialize the Terraform CLI. For more information, see Initializing Working Directories.

    terraform init
    
  3. Provision the resources from the main.tf file. For more information, see Provisioning Infrastructure with Terraform.

    1. Run terraform plan to generate a Terraform execution plan to preview the proposed actions.

      terraform plan
      
    2. Run terraform apply to create the resources that are defined in the plan.

      terraform apply
      

Creating an authorization by using the API

You must have access to the target service to create an authorization between services. You can grant only the level of access that you have as a user of the target service. The autorization that you define for the IBM Cloud Logs Routing service requires that you have Administrator role for the IBM Cloud Logs target service.

To authorize a source service access to a target service, use the IAM Policy Management API.

The supported attributes for creating an authorization policy depend on what each service supports. For more information about the supported attributes for each service, see the documentation for the services that you're using.

curl --request POST \
  --url https://iam.cloud.ibm.com/v1/policies \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "authorization",
    "subjects": [
        {
            "attributes": [
                {
                    "name": "accountId",
                    "value": "<account-id>"
                },
                {
                    "name": "serviceName",
                    "value": "logs-router"
                }
            ]
        }
    ],
    "roles": [
        {
            "role_id": "crn:v1:bluemix:public:logs::::serviceRole:Sender"
        }
    ],
    "resources": [
        {
            "attributes": [
                {
                    "name": "serviceName",
                    "value": "logs"
                },
                {
                    "name": "serviceInstance",
                    "value": "$LOGS_SERVICE_INSTANCE_CRN",
                    "operator": "stringEquals"
                }
            ]
        }
    ]
}'
SubjectAttribute accountSubjectAttribute = new SubjectAttribute.Builder()
      .name("accountId")
      .value(exampleAccountId)
      .build();

SubjectAttribute serviceNameSubjectAttribute = new SubjectAttribute.Builder()
      .name("serviceName")
      .value("logs-router")
      .build();

PolicySubject policySubjects = new PolicySubject.Builder()
      .addAttributes(accountSubjectAttribute)
      .addAttributes(serviceNameSubjectAttribute)
      .build();

PolicyRole policyRoles = new PolicyRole.Builder()
      .roleId("crn:v1:bluemix:public:logs::::serviceRole:Sender")
      .build();

ResourceAttribute accountIdResourceAttribute = new ResourceAttribute.Builder()
      .name("accountId")
      .value(exampleAccountId)
      .operator("stringEquals")
      .build();

ResourceAttribute serviceNameResourceAttribute = new ResourceAttribute.Builder()
      .name("serviceName")
      .value("logs")
      .operator("stringEquals")
      .build();

ResourceAttribute serviceInstanceResourceAttribute = new ResourceAttribute.Builder()
      .name("serviceInstance")
      .value(exampleTargetInstanceId)
      .operator("stringEquals")
      .build();

ResourceAttribute resourceTypeResourceAttribute = new ResourceAttribute.Builder()
      .name("resourceType")
      .value(exampleResourceType)
      .operator("stringEquals")
      .build();

ResourceAttribute resourceResourceAttribute = new ResourceAttribute.Builder()
      .name("resource")
      .value(exampleResourceId)
      .operator("stringEquals")
      .build();

PolicyResource policyResources = new PolicyResource.Builder()
      .addAttributes(accountIdResourceAttribute)
      .addAttributes(serviceNameResourceAttribute)
      .build();

CreatePolicyOptions options = new CreatePolicyOptions.Builder()
      .type("authorization")
      .subjects(Arrays.asList(policySubjects))
      .roles(Arrays.asList(policyRoles))
      .resources(Arrays.asList(policyResources))
      .build();

Response<Policy> response = service.createPolicy(options).execute();
Policy policy = response.getResult();

System.out.println(policy);
const policySubjects = [
  {
    attributes: [
      {
        name: 'accountId',
        value: exampleAccounId,
      },
      {
        name: 'serviceName',
        value: "logs-router",
      }
    ],
  },
];
const policyRoles = [
  {
    role_id: 'crn:v1:bluemix:public:logs::::serviceRole:Sender',
  },
];
const accountIdResourceAttribute = {
  name: 'accountId',
  value: exampleAccountId,
  operator: 'stringEquals',
};
const serviceNameResourceAttribute = {
  name: 'serviceName',
  value: "logs",
  operator: 'stringEquals'
};

const policyResources = [
  {
    attributes: [
      accountIdResourceAttribute,
      serviceNameResourceAttribute
    ],
  },
];
const params = {
  type: 'authorization',
  subjects: policySubjects,
  roles: policyRoles,
  resources: policyResources,
};

iamPolicyManagementService.createPolicy(params)
  .then(res => {
    examplePolicyId = res.result.id;
    console.log(JSON.stringify(res.result, null, 2));
  })
  .catch(err => {
    console.warn(err)
  });
policy_subjects = PolicySubject(
    attributes=[SubjectAttribute(name='accountId', value=example_account_id),
                SubjectAttribute(name='serviceName', value="logs-router")
                ])
policy_roles = PolicyRole(
    role_id='crn:v1:bluemix:public:logs::::serviceRole:Sender')
account_id_resource_attribute = ResourceAttribute(
    name='accountId', value=example_account_id)
service_name_resource_attribute = ResourceAttribute(
    name='serviceName', value="logs")
policy_resources = PolicyResource(
    attributes=[account_id_resource_attribute,
                service_name_resource_attribute])

policy = iam_policy_management_service.create_policy(
    type='authorization',
    subjects=[policy_subjects],
    roles=[policy_roles],
    resources=[policy_resources]
).get_result()

print(json.dumps(policy, indent=2))
accountSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
    Name:  core.StringPtr("accountId"),
    Value: &exampleAccountID,
    Operator: core.StringPtr("stringEquals"),
}
serviceNameSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
    Name:  core.StringPtr("serviceName"),
    Value: "logs-router",
    Operator: core.StringPtr("stringEquals"),
}
policySubjects := &iampolicymanagementv1.PolicySubject{
    Attributes: []iampolicymanagementv1.SubjectAttribute{*accountSubjectAttribute,
        *serviceNameSubjectAttribute},
}
policyRoles := &iampolicymanagementv1.PolicyRole{
    RoleID: core.StringPtr("crn:v1:bluemix:public:logs::::serviceRole:Sender"),
}
accountIDResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
    Name:     core.StringPtr("accountId"),
    Value:    core.StringPtr(exampleAccountID),
    Operator: core.StringPtr("stringEquals"),
}
serviceNameResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
    Name:     core.StringPtr("serviceName"),
    Value:    core.StringPtr("logs"),
    Operator: core.StringPtr("stringEquals"),
}
policyResources := &iampolicymanagementv1.PolicyResource{
    Attributes: []iampolicymanagementv1.ResourceAttribute{
        *accountIDResourceAttribute, *serviceNameResourceAttribute},
}

options := iamPolicyManagementService.NewCreatePolicyOptions(
    "authorization",
    []iampolicymanagementv1.PolicySubject{*policySubjects},
    []iampolicymanagementv1.PolicyRole{*policyRoles},
    []iampolicymanagementv1.PolicyResource{*policyResources},
)

policy, response, err := iamPolicyManagementService.CreatePolicy(options)
if err != nil {
    panic(err)
}
b, _ := json.MarshalIndent(policy, "", "  ")
fmt.Println(string(b))