An opinionated Open Source implementation of the google.iam.v1.IAMPolicy service API, using Cloud Spanner for storage.
$ go get go.einride.tech/iam
package your.pkg;
import "google/iam/v1/iam_policy.proto";
import "google/iam/v1/policy.proto";
service YourService {
/* ... */
rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy);
rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy);
rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse);
}
See iamspanner.IAMServer.
// Server implements your gRPC API.
type Server struct {
*iamspanner.IAMServer
// ...
}
// Server now also implements the iam.IAMPolicyServer mixin.
var _ iam.IAMPolicyServer = &Server{}
See schema.sql.
Buf annotations for rpc method authorization are described in annotations.proto
package your.pkg;
import "einride/iam/v1/annotations.proto";
service YourService {
rpc YourMethod(YourMethodRequest) returns YourMethodResponse {
option (einride.iam.v1.method_authorization) = {
permission: "namespace.entity.method"
before: {
expression: "test(caller, request.entity)" // iamcel expression
description: "The caller must have method permission against the entity"
}
};
};
}
message YourMethodRequest {
string entity = 1 [
(google.api.resource_reference) = {
type: "example.com/Entity"
}
];
};
package your.pkg;
import "einride/iam/v1/annotations.proto";
service YourService {
rpc YourMethod(YourMethodRequest) returns YourMethodResponse {
option (einride.iam.v1.method_authorization) = {
resource_permissions {
resource_permission {
resource: {
type: "example.com/Entity1"
}
permission: "namespace.entity1.method"
}
resource_permission {
resource: {
type: "example.com/Entity2"
}
permission: "namespace.entity2.method"
}
}
after: {
expression: "test_all(caller, response.entities)" // iamcel expression
description: "The caller must have method permission against all entities"
}
};
};
}
message YourMethodResponse {
// Elements in this list are either Entity1 or Entity2 references
repeated string entities = 1;
};
Expresssions in the method_authorization
annotation use
cel-go with iamcel extensions.
The iamcel
extensions provide the following cel functions.
Tests caller
s permissions against resource
.
Tests caller
s permissions against all resources
. This test asserts that the
caller has the permission against all resources.
Tests caller
s permissions against any resources
. This test asserts that the
caller has the permission against at least one resource.
Resolves an ancestor of resource
using pattern
. An input of
ancestor("foo/1/bar/2", "foo/{foo}")
will yield the result "foo/1"
.
Joins a resource
name with a parent
resource name. An input of
join("foo/1", "bar/2")
will yield the result "foo/1/bar/2"
.
Returns the first IAM member value from the caller's member list which matches the member kind, or fails if there are no such kind.
Coming soon.