Modeling Identities in the Resource Graph

Overview

The Resource Graph provides a powerful way of managing identities used by workloads and what permissions those identities have. For example, it allows you to give deployed workloads an identity and automatically grant permissions based on least privilege to this identity on resources that are provisioned. The permissions, and the identity, will also automatically be removed when the workload is decommissioned.

This page provides the conceptual groudwork for modeling identities and permissions. To proceed straight to how it is done in practice, go to Manage workload identity .

What are identities and permissions?

An identity (represented by some kind of principal) is something that a workload uses when it requests an operation to be carried out on a resource. Some kind of authorization system will be able to decide whether the identity has permission to perform the operation on the target resource.

What an identity used by a workload is varies between different clouds and services. Here are some examples:

These identities will have various permissions granted to them. Permissions are rights to perform certain operations on specific resources. How permissions are granted to identities varies greatly across the industry. In general there is some sort of policy describing permissions granted to an identity.

Identity-based vs. resource-based

Policies can be written in two ways: identity-based or resource-based.

Identity-based means each identity has its own policy which describes all the permissions it has on various resources. Resource-based policies are the opposite, where each resource has its own policy that describes which identities have permissions on the resource. The outcome is the same in both cases: the policy can be used to determine whether an identity has the required permission to perform an operation on a resource.

Some examples of how this is done for the major cloud providers include:

  • AWS has both identity- and resource-based policies . IAM policies are identity-based policies and can be attached to an IAM Role. Resource-based policies can be attached to some AWS services
  • Azure has Roles which are neither strictly identity-based nor resource-based. They exist independently, defining any set of permissions, and only in the course of a role assignment do they get attached to both an identity and a resource (or set of resources, as determined by the assignment scope) at the same time
  • GCP uses Resource-based policies known as allow policies . In the policy, role bindings are used to bind identities such as service accounts or GKE workloads to roles. Roles define a set of permissions that a holder of the role has on a particular resource or set of resources

Using Identities in Workloads

Identities themselves are an abstract concept. In practice, a workload needs to prove that they may use or assume a particular identity when trying to perform an action on a resource. The workload can prove its identity by using credentials. This is known as authentication. This means that a workload assuming some identity is the same as getting access to credentials for that identity.

There are three ways in which a workload can get access to credentials.

Implicitly

Some external system provides credentials to the workload automatically in a way that is understood by the SDK or library that a developer is using. This means that the developer does not have to be aware of credentials, they just use the library or SDK and credentials are handled transparently.

This usually requires some setup and can be tricky if workloads are accessing resources from different service providers. However, as developers do not need to work with credentials, it is considered more secure. Implicit credentials also tend to be short-lived or temporary, being renewed automatically by the SDK or library.

The Workload Identity or Pod Identity solutions offered by the managed Kubernetes services of many cloud providers fall into this category.

Explicitly

A workload receives credentials via some configuration mechanism defined by the workload itself such as an environment variable or a file. The developer then needs to use these credentials to explicitly authenticate with the resource they are working with. This is normally done by passing the credentials into the initialization routine of the library or SDK the developer is using.

This is usually considered less secure than the omplicit method as credentials need to be handled as part of configuration. In addition, explicit credentials tend to be long lived. This is because they need to be injected via some configuration system. However, it can be useful for scenarios where accessing resources in other suppliers and when the exchange mechanism (shown next) is not possible.

Exchange

A workload can exchange its existing credentials for other credentials. This effectively allows it to assume a new identity. This means that the workload needs to have initial credentials to be supplied either implicitly or explicitly. The initial credentials must represent an identity that has permission to perform the credential exchange.

This requires developers to understand that they need to take actions to assume the new identity. This can be necessary in a number of scenarios. For example, when accessing resources from another service provider, there are often techniques for exchanging credentials to move between different cloud providers’ identities.

Identities and the Resource Graph

The structure of the resource graph depends on how the identities are provided to the workload (implicitly, explicitly, or exchange) and whether the policies are identity-based or resource-based. The example diagrams below show the graph structure for modelling access to two storage buckets for each combination.

Identity-based Policy Resource-based Policy
Implicit 1 2

Note:

  • The identity is tied to Kubernetes ServiceAccount used by the workload
  • It is possible for more than one or even all combinations of credential handling and policy type to be used, but this becomes complex
  • In the diagrams below, items in bold letters are defined by the developer. Everything else comes from the graph
  • Whether or not any real-world resource is pre-existing or newly created is not relevant for the Resource Graph pattern

Implicit / identity-based

graph TD
  workload --> bucket1("<b>Bucket One</b>")

  workload("<b>Workload</b>") --> k8s_service_account(K8s ServiceAccount)
  k8s_service_account --> identity(Identity)
  policy1 --> bucket1
  identity --> policy1("Policy One")
  identity --> policy2("Policy Two")
  policy2 --> bucket2
  workload --> bucket2("<b>Bucket Two</b>")

Implicit / resource-based

graph TD
  workload --> bucket1("<b>Bucket One</b>")

  workload("<b>Workload</b>") --> k8s_service_account(K8S ServiceAccount)

  policy1("Policy One") --> identity
  policy1 --> bucket1
  k8s_service_account --> identity(Identity)
  policy2("Policy Two") --> identity 
  policy2 --> bucket2
  workload --> bucket2("<b>Bucket Two</b>")

Next steps

To see these concepts applied, go to Manage workload identity .

Top