SPEKTRA Edge IAM Service API

Understanding the IAM service API.

The Identity and Access Management (IAM) service provides an authentication and authorization endpoint for both end-user clients such as the cuttle command and other services that require permission checks.

In IAM, organization or project administrators can manage members assigned permissions via role bindings across managed projects, as below:

An example organization hierarchy managed by IAM service.

An example organization hierarchy managed by IAM service.

During the authentication process, backend services extract the Actor (Who) from JWT tokens. During Authorization, backend services are checking in which scopes (Where) actions are happening, what permissions/roles are required (What), and whether an authenticated Actor has necessary RoleBindings (which binds an Actor with Scope with Role).

Apart from that, Organization admins can create so-called Service Projects, in which they can create their Services. Services on their own are additional IAM Scopes, where administrators also can manage RoleBindings.

Full API Specifications (with resources):

Resources

Groups

A group is a set of other members. It facilitates authorization management, admins can assign roles to groups instead of individual principals, groups, nor domains.

Members

A member is a similar concept of principal, but it can also represent a groups of users, e.g. group, domain, or wildcard principals, e.g. any one of them. You can think of it as:

Every principals is a member, but not every member is a principal.

Known member types are:

  • users:$EMAIL

    A Member of User type (also an principal), where $EMAIL is equal to User Email.

  • serviceAccounts:$EMAIL

    A member of service account type (also an principal), where $EMAIL is equal to ServiceAccount E-mail.

  • allUsers

    all principals.

  • allAuthenticatedUsers

    all authenticated principals.

  • domain:$DOMAIN

    Describes all users whose email matches the domain

  • group:$EMAIL

    A member of group type, where $EMAIL is equal to group E-mail.

When project/organization/service administrators manage a role binding, they are binding roles with members, not principals. This allows assigning permissions to individual principal, as well as groups of them (bulk).

Organizations

An organization is a hierarchical grouping of sub-organizations and projects that enables the easier resource management and the visibility across entire hierarchies. Granting or revoking permissions through the creation or deletion of role bindings allows access control to be inherited to all sub-organizations and projects.

Permissions

A permission is an atomic and unique resource that identifies the unit of permittable action.

For example, services/devices.edgelq.com/permissions/devices.get corresponds to GetDevice method of devices.edgelq.com service.

Current SPEKTRA Edge supports three types of Permissions:

  1. verb permissions

    It’s usually an one-to-one mapped to gRPC method, e.g., services/devices.edgelq.com/permissions/devices.get.

    Method either succeeds or fails depending on the presence of required permission.

  2. attach permissions

    With IAM, relationships between resources are protected both ways.

    Role bindings allow the system to control which resources the user is allowed to refer to (or “attach”). For example, the user may have permission to update Device record, but if they try to update spec.serviceAccount, which points to ServiceAccount resource, then the user needs special attach permission on the ServiceAccount itself.

  3. field-level Set/Read permissions

    Annotating resource with ntt.annotations.iam.auth_checks.read_checks or ntt.annotations.iam.auth_checks.set_checks will protect single field. Unless the user has this permission, it will:

    • censor (unset) it to get/list responses; or
    • ignore it in update/create requests.

Principals

A principal represents any single entity interacting with the SPEKTRA Edge system.

IAM service and middleware allow all SPEKTRA Edge services to verify Authentication data attached to incoming requests and ensure security by enforcing Access Controls.

IAM recognizes three types of actors: Users, Service Accounts, and Anonymous.

  1. A user is actual human who interact with our endpoints (most often through Web dashboards or command-line tools).
  2. A service account is usually assigned to a program, like agents, controllers, API servers.
  3. An anonymous principal is any unauthenticated request (not JWT token), on rare occasions, it is still valid to allow such traffic. Disabled by default.

Users identify themselves through authentication providers using their IDs, emails, passwords, or SSOs, while service accounts use cryptographic asymmetric key pairs (RSA).

In many cases, users are subject to the multi-factor authentication.

Each user and service account is represented by IAM resource: User/ServiceAccount.

Projects

A project is a logical container for most of the resources present in the system. All devices, applications, and telemetry have a project attached to them.

The project may define the parent organization and inherit all access control from it.

Unlike sub-organizations switching parent organizations, resources within a given project, like devices or pods, cannot easily move to different projects, so make sure you have large-scale [deployments][] well-planned.

Roles

A role is a set of grants with permissions and optional conditions. Typically, administrators should not assign to members individual permissions, as it would require too much work. Instead, we have Roles that contains set of grants, each has an optional sub-scope, conditions, and list of permissions.

Role Bindings

A role binding follows the general principles of RBAC: Role-Based Access Control.

A role can be granted to a member on a scope by creating a corresponding role binding resource.

This results in all matching principals defined in the member field to be able to perform actions defined in roles on the resource in a given scope and its descendant scopes.

Scopes

A scope provides system wide resource groupings. There are four levels of scopes:

  1. system-wide

    when resource name pattern doesn’t start with either projects/ or organizations/ or services/.

    Normally users don’t interact very often with system-level resources.

  2. organization-scoped

    when the resource name pattern starts with organizations/.

    The organization is a resource in IAM, and it can refer to the parent organization, meaning organizations can form “trees”. Role Bindings are inherited in child organizations. Example: NTT, NTT America, NTT America: Network Innovations

  3. project-scoped

    when the resource name pattern starts with projects/ - projects may point to the parent organization.

    Role Bindings from the parent Organization are inherited too.

  4. service-scoped

    when the resource name pattern starts with services/ - each service should point to a service project.

    Role Bindings from Service projects are inherited too. If the Service Project has a parent organization, then all Role Bindings are inherited from the whole ancestry path.

Service Projects

A service project is a type of project, in which administrators can create [services][]. A service project is responsible for managing the service accounts that are the service administrators of the project, or for storing usage metrics for the project.

Sub-organizations

A sub-organization is an organization under the parent organization which might contain other organizations. All access permissions granted to higher-level organizations are implicitly inherited to the lower-level organizations and/or projects.

This allows the modeling divisions within a company or the logical groupings for managed customers. Organization administrators can move sub-organization to another organization without delay, so long as they have required permissions on both organizations.

There is no hard limit on the depth of hierarchy, but we recommend keeping it ten or less.

Tenant management

Almost all resources on SPEKTRA Edge are managed based on Project. For example, resources such as Devices and Pods are managed by being tied to a Project. A grouping of resources commonly referred to as a “tenant” is called a Project in SPEKTRA Edge.

Organization is a resource for organizing multiple projects, and a project can be a child of Organization if necessary (projects that do not belong to Organization can also exist). Since an Organization itself can also be a child of an Organization, an Organization and a Project form a tree structure.

Projects are managed by the system or a higher level Organization administrator. Users who are only authorized to operate on specific project cannot perform operations such as creating the project itself.

Creating a project

To create a new Project in an Organization, a user must be assigned the role containing permission services/iam.edgelq.com/permissions/projects.create. Well-known roles that satisfy this condition are:

  • services/iam.edgelq.com/roles/scope-admin because it is special Owner role (wildcard)
  • services/iam.edgelq.com/roles/admin-operator administrator of SPEKTRA Edge project or organization (core services only).

To create a new project, use the cuttle iam create project command:

Options Description
--multi-region-policy Specify the region name to be used for multi-region. Specify eu1 for commercial environment and us-west2 for staging environment. This parameter is required.
--enabled-services Specify “services/watchdog.edgelq.com” if you use Service Experience Insights (SEI).
cuttle iam create project \
  --title "<project name for humans>" \
  --organization $ORGANIZATION \
  --multi-region-policy '{"enabledRegions": ["eu1"], "defaultControlRegion": "eu1"}' \
  --enabled-services 'services/watchdog.edgelq.com' \
  $PROJECT.

Role Bindings management

The RoleBinding is a resource used to assign privileges to specific users, service accounts, or groups within a Project or Organization. Role Binding itself is also a resource within a Project or Organization, and only users with specific privileges (such as the services/iam.edgelq.com/roles/scope-admin role) can manipulate Role Binding resources.

The privileges granted by Role Binding are dictated by the Role resource. For example, scope-admin is defined as the Role of an owner in an IAM scope (project, organization, service). This role serves as a wildcard (all permissions are granted within scope). Otherwise, in practice, a Role is a collection of multiple Permissions, such as services/iam.edgelq.com/permissions/roleBinding.create, that allows to create RoleBinding (but within scope predicted by RoleBinding).

Permission is a resource that represents the permissions needed to perform the actual operation. As in the previous example, services/iam.edgelq.com/permissions/projects.create is the Permission required to create a Project resource. Note that a Permission may be shared by multiple Roles.

When a user performs an operation, they must possess the necessary Permission to ultimately perform that operation. In practice, a user obtains Permission through a Role by being given a Role Binding in a particular Project.

Note that single user may have multiple roles assigned. In this case, the final Permission granted to the user will be the sum of the Permissions derived from all assigned Roles.

Frequently used roles

Default service roles can be listed by using the cuttle iam list roles --service <service> command. It is advisable to add category filter. For example, to see list of Core SPEKTRA Edge roles for users, we can execute the following:

cuttle iam list roles --service iam.edgelq.com --filter \
  'category IN ["USER","OWNER"]'

In SPEKTRA Edge core services (IAM, devices, applications, monitoring, logging,…), we put all user-relevant roles in service iam.edgelq.com. Third party services, including watchdog, have own list.

Currently, user-facing roles in SPEKTRA Edge core services are:

Roles Description
services/iam.edgelq.com/roles/scope-admin Users granted this role can perform all operations in the scope.
services/iam.edgelq.com/roles/admin-operator Users granted this role is administrator of core SPEKTRA Edge services (excludes 3rd party)
services/iam.edgelq.com/roles/devices-operator Users granted this role can perform all operations relevant for Edge devices and applications (pods)
services/iam.edgelq.com/roles/apps-operator Users granted this role can perform all operations relevant for Edge applications (pods)

Creating Role Binding

Role assignments can be performed for users, user groups, and service accounts using the Role Binding resource on IAM.

The following example command assigns devices-operator to a user with an email address of example@edgelq.com. Note that the --member option is in addition to the email address, and that user: is present as a prefix.

cuttle iam create role-binding \
  --role services/iam.edgelq.com/roles/devices-operator \
  --member "user:example@edgelq.com"

Note that the --member option prefix must be serviceAccount: for assigning Role Binding to a service account or group: for a group.

When a Role Binding is created for a group, another one is automatically created for each member in the group. Therefore, multiple Role Bindings may be created even if only one is created from the user’s perspective.

Checking Role Bindings

A list of Role Bindings can be obtained with the following commands:

cuttle iam list role-bindings --organization $ORGANIZATION # for organization
cuttle iam list role-bindings --project $PROJECT # for project
cuttle iam list role-bindings --service $SERVICE # for service (available for service developers)

Checking your access

Check for projects to which you are authorized to access

The command that lists the Project resources present on the system (cuttle iam list projects) cannot be executed by ordinary users for security reasons. If you want to see the projects to which you are entitled, use cuttle iam list-my projects (this command requires -o json, use -o json in combination with jq).

cuttle iam list-my projects -o json | jq .

Check for organizations to which you are authorized to access

The command that lists the Organizations resources present on the system (cuttle iam list organizations) cannot be executed by ordinary users for security reasons, just like for projects. If you want to see the organizations to which you are entitled, use cuttle iam list-my organizations (this command requires -o json, use -o json in combination with jq).

cuttle iam list-my organizations -o json | jq .

Check the roles assigned to you

To check the roles you hold within a particular project, use the cuttle iam check-my role-bindings --project $PROJECT command (this command requires -o json, use jq in combination).

Some example for organization:

cuttle iam check-my role-bindings --parent 'organizations/testing' -o json | jq .
{
  "resolvableGrants": [
    {
      "roleBinding": {
        "name": "roleBindings/edgelq-public-all",
        "role": "services/iam.edgelq.com/roles/edgelq-public"
      },
      "grants": [
        {
          "permissions": [
            "services/meta.goten.com/permissions/regions.batchGet"
            # SKIP lots of other permissions...
          ]
        }
      ]
    },
    {
      "roleBinding": {
        "name": "organizations/testing/roleBindings/fr45545ffffFC",
        "role": "services/iam.edgelq.com/roles/scope-admin",
        "ownedObjects": [
          "-"
        ]
      },
    }
 ]
}

We can use this method to check our RoleBindings in projects and services too. It shows all RoleBindings, including inherited from parent organizations (if exist) and system scope (Role services/iam.edgelq.com/roles/edgelq-public is assigned to all on the system level).

If RoleBinding has ownedObjects, it means we are owners of specified, and we are granted all permissions. Sign - is a wildcard, so we are admins in the whole organization, and we can do whatever we like.

Roles management with conditions

Understanding the Role and its Grants is crucial for effective and secure management of authorization. In the simplest form, The role may look like this:

- name: services/devices.edgelq.com/roles/some-role-name
  displayName: Some Display Name
  category: USER
  grants:
  - permissions:
    - services/devices.edgelq.com/permissions/devices.batchGet
    - services/devices.edgelq.com/permissions/devices.get
    - services/devices.edgelq.com/permissions/devices.list

It allows to read Devices using various methods. Combined with RoleBinding:

- name: projects/test/roleBindings/test
  member: "user:someone@example.com"
  role: services/devices.edgelq.com/roles/some-role-name

Default roles are defined by each service. In core SPEKTRA Edge services, we define all user-facing roles in service iam.edgelq.com.

Project/Organization admins can create their own roles if defualts are not satisfying. Organization and Project administrator will need access to a Service before they are able to create a role with that service permissions.

This will allow a user with a given email to view devices using BatchGet, Get, and List methods in the project test.

However, we can also define some role that allows viewing only a specific device:

- name: services/devices.edgelq.com/roles/single-device-viewer
  displayName: Some Display Name
  category: USER
  scopeParams:
  - name: region
    type: STRING
  - name: device
    type: STRING
  grants:
  - subScope: "regions/{region}/devices/{device}"
    permissions:
    - services/devices.edgelq.com/permissions/devices.batchGet
    - services/devices.edgelq.com/permissions/devices.get

Then we can create RoleBinding:

- name: projects/test/roleBindings/test
  member: "user:someone@example.com"
  role: services/devices.edgelq.com/roles/single-device-viewer
  scopeParams:
  - name: region
    string:
      value: us-west2
  - name: device
    string:
      value: specific-id

This will restrict the user to a specific device: projects/test/regions/us-west2/devices/specific-id. Note that in this case “list” permission makes no sense. Be aware that subScope is APPENDED to the RoleBinding parent name.

We can also give access to multiple devices if we modify the role:

- name: services/devices.edgelq.com/roles/multi-devices-viewer
  scopeParams:
  - name: region
    type: STRING
  - name: device
    type: ARRAY_OF_STRINGS
  ## Other params

RoleBinding could then look like this:

- name: projects/test/roleBindings/test
  member: "user:someone@example.com"
  role: services/devices.edgelq.com/roles/multi-devices-viewer
  scopeParams:
  - name: region
    string:
      value: us-west2
  - name: device
    strings:
      values:
      - specific-id-1
      - specific-id-2

If we wanted to restrict users to some set of devices depending on some condition, we could do something like:

- name: services/devices.edgelq.com/roles/devices-condition-viewer
  displayName: Some Display Name
  category: USER
  scopeParams:
  - name: region
    type: STRING
  - name: tag
    type: STRING
  grants:
  - subScope: "regions/{region}"
    permissions:
    - services/devices.edgelq.com/permissions/devices.batchGet
    - services/devices.edgelq.com/permissions/devices.get
    - services/devices.edgelq.com/permissions/devices.list
    resourceFieldConditions:
    - path: metadata.tags
      value: "{tag}"

The above role will restrict the user to see devices only if their metadata.tags contain a specific tag. Service automatically can detect that field path metadata.tags is an array of strings. If it was a single string, then Role would allow us to see Devices where the tag is EQUAL to the specified value. If you combine ARRAY_OF_STRINGS scope param with the field path containing the array, it will effectively work like CONTAINS ANY.

When it comes to resource field conditions, SPEKTRA Edge Service can automatically detect referenced resources from specified requests. For updates, it will verify two resource states: before and after the update (the user could potentially modify the resource that would match the required condition, but the previous state still matters).

There are more condition types than resource field types, for example, we can reference requests directly:

scopeParams:
- name: service
  type: STRING
grants:
- permissions:
  - services/audit.edgelq.com/permissions/activityLogs.create
  requestFieldConditions:
  - path: activity_logs.service.name
    value: "{service}"

Note that scope params also are used for condition values.

There is a method CreateActivityLogs, which request contains field path activity_logs.service.name, where activity_logs is an array field!

This condition will ensure that for each record in activity_logs array field path service.name has a specified value (both service and name fields are single ones, not arrays).

Note this is a bit of a different behavior compared to resource field conditions: For resources, if the field path contains an array, then it works effectively as CONTAINS condition. In request conditions, each value must satisfy the condition.

TODO: It was more convenient this way, but we will add “allValues” condition separately.

There is also a possibility to use CEL conditions, where we can specify CEL code to execute.

In this example, we allow direct access to internet quality metrics, so a viewing party may request internet quality data per Internet Service Provider for each Province in Japan, but we don’t allow for too narrow filtering or grouping, which could potentially de-anonymize the data, like the exact agent identifier or its location.

First, we need to create iam.edgelq.com/Condition resource:

name: services/watchdog.edgelq.com/conditions/anonymous-time-series
displayName: Watchdog Anonymous Time Series
description: >-
  Inspects Time Series requests to ensure that the user doesn't filter or retrieve private information
  from probe metric labels like name, ID or precise geo-coordinates  
expression: |
  // restrict only Probe/Host Time Series
  (!(request.body.filter.satisfies('resource.type="watchdog.edgelq.com/probe"')) ? true :
   // reduce without identifiable information
   (!request.body.filter.specifies("resource.labels.probe_id") &&
    !request.body.filter.specifies("resource.labels.admin_area3_id") &&
    !request.body.filter.specifies("resource.labels.admin_area3") &&
    !request.body.filter.specifies("resource.labels.admin_area4_id") &&
    !request.body.filter.specifies("resource.labels.admin_area4") &&
    !request.body.filter.specifies("resource.labels.geohash4") &&
    !request.body.filter.specifies("resource.labels.geohash5") &&
    !request.body.filter.specifies("resource.labels.geohash6") &&
    !request.body.filter.specifies("resource.labels.geohash7") &&
    has(request.body.aggregation.cross_series_reducer) &&
    request.body.aggregation.group_by_fields.all(gbf, gbf in [
       "resource.labels.project_id",
       "resource.labels.region_id",
       "resource.labels.probe_group_id",
       "resource.labels.continent",
       "resource.labels.continent_id",
       "resource.labels.country",
       "resource.labels.country_id",
       "resource.labels.admin_area1",
       "resource.labels.admin_area1_id",
       "resource.labels.admin_area2",
       "resource.labels.admin_area2_id",
       "resource.labels.geohash2",
       "resource.labels.geohash3",
       "resource.labels.asn",
       "resource.labels.asn_name",
       "metric.labels.target",
       "metric.labels.target_id",
       "metric.labels.target_group",
       "metric.labels.target_group_id",
       "metric.labels.target_category",
    ])))  
parameterDeclarations: []

CEL Spec: https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md.

Then, we can define a Role with grants like:

grants:
- permissions:
  - services/monitoring.edgelq.com/permissions/timeSeries.query
  executableConditions:
  - condition: services/watchdog.edgelq.com/conditions/anonymous-time-series

In the future though (TODO), this condition will be possible to be specified by inline conditions:

scopeParams:
- name: filterCondition
  type: ARRAY_OF_STRINGS
  defaultValues:
  - resource.labels.probe_id
  - ...
  - resource.labels.geohash7
- name: groupByProbeLabels
  type: ARRAY_OF_STRINGS
  defaultValues:
  - resource.labels.project_id
  - ...
  - metric.labels.target_category
grants:
# Access to time series for probes only 
- permissions:
  - services/monitoring.edgelq.com/permissions/timeSeries.query
  requestFieldConditions:
  - path: filter
    doesSatisfy: 'resource.type="watchdog.edgelq.com/probe"'
  - path: filter
    doesNotSpecify: "{filterCondition}"
  - path: aggregation.crossSeriesReducer
    notValue: REDUCE_NONE
  - path: aggregation.groupBy
    valuesAll: "{groupByProbeLabels}"

# Allow for non-probe
- permissions:
  - services/monitoring.edgelq.com/permissions/timeSeries.query
  requestFieldConditions:
  - path: filter
    doesNotSatisfy: 'resource.type="watchdog.edgelq.com/probe"'

SubScopes for collection and single resource actions

When defining subscopes in roles, collection-type actions (list, watch for plural!) must accept subScope without final collection name and resource ID.

For example, all these grants are legal:

# Permissions for non-collection actions and specific device
- subScope: regions/{region}/devices/{device}
  permissions:
  - services/devices.edgelq.com/devices.get
  - services/devices.edgelq.com/devices.batchGet
  - services/devices.edgelq.com/devices.update
  - services/devices.edgelq.com/devices.delete

# Permissions for collection actions and specific region (parent):
- subScope: regions/{region}
  permissions:
  - services/devices.edgelq.com/devices.list
  - services/devices.edgelq.com/devices.create

# Permissions for non-collection actions for specific region
- subScope: regions/{region}
  permissions:
  - services/devices.edgelq.com/devices.get
  - services/devices.edgelq.com/devices.batchGet
  - services/devices.edgelq.com/devices.update
  - services/devices.edgelq.com/devices.delete

But these grants would be not working (illegal):

# Permissions for non-collection actions and specific device
- subScope: regions/{region}/devices/{device}
  permissions:
  - services/devices.edgelq.com/devices.list
  - services/devices.edgelq.com/devices.create

The reason is, that ListDevices and CreateDevice are collection types, and they have “parent” resource field as the primary field for authorization. Name pattern for device parent is projects/{project}/regions/{region}, therefore it will never match subScope. Keep this in mind when defining subScopes!

Watch permissions

Permission for watches is a bit ambiguous. For example, we have two watch requests for each resource type, for example for devices we can specify:

  • WatchDevice - for single device (singular resource method)
  • WatchDevices - for collection of devices (collection method)

However, both of these actions are represented by single permission: services/devices.edgelq.com/devices.watch.

This means, that the following grants will apply to BOTH cases:

# Grants both WatchDevice and WatchDevices
- permissions:
  - services/devices.edgelq.com/devices.watch

# Grants both WatchDevice and WatchDevices, as long as we are restricting
# to a specific region:
- subScope: regions/{region}
  permissions:
  - services/devices.edgelq.com/devices.watch

However, if we specify subScope for a single device, then this grant will only work for a single resource watch:

# Because we specified the device in sub-scope, this grant will never apply
# to plural WatchDevices!
- subScope: regions/{region}/devices/{device}
  permissions:
  - services/devices.edgelq.com/devices.watch

Attach permissions

In the IAM, establishing relationships requires extra permissions - so-called attach checks. For example, if we are updating the Device resource from the devices.edgelq.com service, which has a reference to ServiceAccount via the spec.service_account field (Service iam.edgelq.com), we need two permissions:

  • services/devices.edgelq.com/permissions/devices.update

    We require this permission on the Device resource.

  • services/iam.edgelq.com/permissions/serviceAccounts!attach

    We require this permission on the ServiceAccount resource.

To ensure the user can execute such an update, we may need a role with grants like:

name: <RoleName>
grants:
- permissions:
  - services/devices.edgelq.com/permissions/devices.update
  - services/iam.edgelq.com/permissions/serviceAccounts!attach

If we want to have more granular management, we may separate them by using subScopes and & or resource field conditions:

name: <RoleName>
scopeParams: ... # just regular params...
grants:

- subScope: "regions/{region}/devices/{device}"
  permissions:
  - services/devices.edgelq.com/permissions/devices.update
  resourceFieldConditions:
  - path: metadata.annotations.key
    value: "{value}"

- subScope: "regions/{region}/serviceAccounts/{serviceAccount}"
  permissions:
  - services/iam.edgelq.com/permissions/serviceAccounts!attach
  resourceFieldConditions:
  - path: metadata.tags
    value: "{tagValue}"

Request field conditions do not make sense for attach checks - they apply for a whole call only, affecting the main permission for a method (device.update in this case).

Managing Users (User Resources)

SPEKTRA Edge manages users as independent resources. In other words, a user is not tied to a specific Project or Organization, but exists on its own. In other words, a user can “access” multiple Projects and Organizations, but there is no concept of “belonging” to a Project or Organization. The relationship between a user and a Project or Organization is done as Role Binding.

Note that the SEI dashboard displays Role Binding resources as pseudo “users” so that users can manage user privileges without understanding the detailed IAM specifications. Note that deleting a “user” on the SEI dashboard does not delete the user’s information from the system. What is deleted is the Role Binding resource that the user holds on the relevant Project.

Users usually sign up using an individual email address (called a local user) or register with the system using SSO, which is linked to a Google account, etc. If SSO is used, the user’s registration information is handled by the SSO provider. For local users, password registration and MFA settings are done on SPEKTRA Edge.

The following operations on local users currently require a request to the system administrator.

  • Reset MFA access settings
  • Complete deletion of user information

Service Account and Service Account Key

Service accounts are used to authenticate for M2M. For example, when accessing SPEKTRA Edge’s API with scripts for API integration or various automation tools, a service account can be used instead of a specific user. Service accounts exist as Service Account resources on IAM.

For IAM authorization processing, service accounts are treated much the same as regular users. In other words, in order to allow a service account to access the API, it must be assigned a role. Please refer to the above explanation for how to assign roles.

To create a new service account, use the cuttle iam create service-account command.

cuttle iam create service-account --project $PROJECT \
    $SVCACCNT_NAME

To actually use a service account, a service account key must be created as a credential. Service account keys are created as child resources of the service account. Multiple service account keys can be created for a single service count.

The service account key supports multiple key algorithms. Normally, a 2048-bit key pair using RSA (--algorithm RSA_2048) is used. This key pair can be used for API calls with gRPC and authentication with the cuttle command. On the other hand, if you want to use a short string used as a Bearer token in the Authorization header of a REST request as a key, use the API KEY (--algorithm API_KEY).

The following example shows how to generate a service account key using RSA. When this command is executed, a file named credentails.json containing the freshly generated key will be created in the directory where the command was executed

cuttle iam create service-account-key --project $PROJECT \
  --service-account $SVCACCNT_NAME \
  --algorithm RSA_2048 \
  $SVCACCNT_KEY_NAME

To use the generated key with the cuttle command, load it with the following command

cuttle config account add-service-account credentials.json

The following command is an example of using the loaded service account in the default context (if you are using a staging environment, etc., change it accordingly). (The name of the context can be obtained with the cuttle config context list command). For the account name, enter the email address of the service account as it appears when the above command is read.

cuttle config context set default \
  --account sa@exmaple.eu1.serviceaccounts.iam.edgelq.com

The following example shows how to generate a key using API_KEY.

cuttle iam create service-account-key --project $PROJECT \
    --service-account $SVCACCNT_NAME \
    --algorithm API_KEY \
    $SVCACCNT_KEY_NAME

In this case, the output is written as JSON to standard output, and the value of the .apiKey field is the API key.

Groups

A group is a resource used when operating multiple users together. For example, by assigning roles to groups, it is possible to omit assigning roles to individual users.

A group consists of two resources. The primary resource is the Group resource in IAM, which defines the group itself. To add users to a group, use the Group Member resource, which is a child of the Group resource.

Groups can be created in the System, Organization, and Project scopes, but each requires its own permissions.

The following command is an example of creating a group in the Project scope and adding members; note that, as with Role Binding, the --member option must be prefixed.

## create group
cuttle iam create group --project $PROJECT $GROUP_NAME
## add a member
cuttle iam create group-member --project $PROJECT \
  --group $GROUP_NAME --member "user:example@edgelq.com"

Understanding the iam.edgelq.com service APIv1, in proto package ntt.iam.v1.

Understanding the iam.edgelq.com service APIv1alpha2, in proto package ntt.iam.v1alpha2.