GCP Access Control Model
What is it
The GCP Access Control Model is an extension to the AIP design framework for adding access controls to resource-oriented APIs.
In summary, it provides a protobuf data model for Identity and Access Management Policies (IAM Policies), and gRPC API mixins for binding IAM Policies to resources.
It can be used to add domain-specific customer-oriented role-based access controls to gRPC APIs.
In simple terms, the GCP Access Control Model lets us control who can do what on which resource.
Policies
An IAM Policy is, according to the Google Cloud documentation:
Access control [...] is managed by Identity and Access Management (IAM) policies, which are attached to resources. You can attach only one IAM policy to each resource.
// Defines an Identity and Access Management (IAM) policy. It is used to
// specify access control policies for [...] resources.
//
// A `Policy` is a collection of `bindings`. A `binding` binds one or more
// `members` to a single `role` [...].
//
//
// A `role` is a named list of permissions [...].
message Policy {
// Associates a list of `members` to a `role`.
// `bindings` with no members will result in an error.
repeated Binding bindings = 4;
// `etag` is used for optimistic concurrency control as a way to help
// prevent simultaneous updates of a policy from overwriting each other.
bytes etag = 3;
}
Policies are assigned to resources via the google.iam.v1.IAMPolicy
mixin service:
// Manages Identity and Access Management (IAM) policies.
//
// Any implementation of an API that offers access control features
// implements the google.iam.v1.IAMPolicy interface.
service IAMPolicy {
// Sets the access control policy on the specified resource.
// Replaces any existing policy.
rpc SetIamPolicy(SetIamPolicyRequest) returns (Policy) {
option (google.api.http) = {
post: "/v1/{resource=**}:setIamPolicy"
body: "*"
};
}
// Gets the access control policy for a resource.
// Returns an empty policy if the resource exists and does not have a policy.
rpc GetIamPolicy(GetIamPolicyRequest) returns (Policy) {
option (google.api.http) = {
post: "/v1/{resource=**}:getIamPolicy"
body: "*"
};
}
}
The first step when adding access controls to a gRPC API using the GCP Access Control Model is to
include the GetIamPolicy
and SetIamPolicy
methods.
A gRPC mixin service is just a set of standardized gRPC methods that can be added (i.e. copy-pasted) to another gRPC service. The most common mixins are for adding access controls and long-running operations.
Bindings and Members
From the Google Cloud documentation:
An IAM policy is a collection of role bindings and metadata. A role binding specifies what access should be granted to a resource.
In other words, a Policy is a list of Bindings, and each binding specifies which Role should be granted to which policy members.
// Associates `members` with a `role`.
message Binding {
// Role that is assigned to `members`.
// For example, `roles/viewer`, `roles/editor`, or `roles/owner`.
string role = 1;
// Specifies the identities requesting access for a [...] resource.
repeated string members = 2;
}
Google's documentation sometimes uses "principal" and "member" interchangeably. We prefer "member".
A member is a string on the format {type}:{value}
.
Examples of members are email:john.smith@einride.tech
and domain:einride.tech
.
Roles and Permissions
From the Google Cloud documentation:
Permissions determine what operations are allowed on a resource. In the IAM world, permissions are represented in the form of
service.resource.verb
, for example,pubsub.subscriptions.consume
.
In other words, permissions are strings on a specific format:
service.resource.verb
, e.g. freight.sites.create
.
-
The
service
part of a permission is typically the name of the gRPC service where the permission is used. -
The
resource
part of a permission is typically the type of the resource which the permission is related to, as plural. -
The
verb
part of a permission is typically the verb part of the gRPC method that the permission is related to.
From the Google Cloud documentation:
A role, which is a named collection of permissions that provide the ability to perform actions on [...] resources.
In other words, a role is simply a named list of permissions, which can also be observed in the protobuf definition of a Role:
// A role in the Identity and Access Management API.
message Role {
// The resource name of the role.
string name = 1;
// Optional. A human-readable title for the role.
string title = 2;
// Optional. A human-readable description for the role.
string description = 3;
// The names of the permissions this role grants when bound in an IAM policy.
repeated string included_permissions = 7;
}
Resource hierarchy
When a policy is bound to a resource, it also applies to children of that resource.
The parent/child relationship between resources is defined through resource names. A child's resource name will start with the parent's resource name.
For example: shippers/folkfood
is a parent of shippers/folkfood/sites/gbg
.
When the role roles/freight.editor
is bound to shippers/folkfood
, the binding will also apply to
shippers/folkfood/sites/gbg
.
The parent/child relationship makes it possible to model classical role-based access controls using the GCP Access Control Model. Bind a role at a high level in a resource hierarchy, for example at the tenant level, and the role will apply to all resources under that level.
How to use it
Use the GCP Access Control Model for backend APIs that require domain-specific access controls.
For Go services, make use of the IAM Go SDK.
How to learn it
Start by deep-reading this article a couple of times until all the concepts connect together. Ask the Infrastructure Guild if any questions come up.
See the Access Control Model for Google Cloud IoT whitepaper for a formal definition of the Google Cloud Access Control Model.
See also Google Cloud's own documentation for the GCP Access Control Model: