Skip to content

Add proto API for authorization service #28

@rowan-stein

Description

@rowan-stein

User Request

Add protobuf API definition for the authorization service.

Specification

File Location

proto/agynio/api/authorization/v1/authorization.proto

Package

  • Package: agynio.api.authorization.v1
  • Go package option: github.com/agynio/api/gen/agynio/api/authorization/v1;authorizationv1

Service: AuthorizationService

The authorization service is a thin gRPC proxy to OpenFGA. It mirrors the OpenFGA runtime API and centralizes store_id/model_id injection. Callers do not provide store_id or authorization_model_id.

Methods

Method Description
Check Can identity X perform relation Y on resource Z? Returns allowed: bool
BatchCheck Multiple checks in a single call. Each check has a correlation_id for matching responses
Write Write and/or delete relationship tuples atomically (up to 100 tuples per call)
Read Read tuples matching a filter (user, relation, object — each optional). Paginated
ListObjects What objects of type T does identity X have relation Y with? Returns list of object IDs
ListUsers What identities have relation Y with object Z? Returns list of identity IDs

Message Design

Relationship Tuple:

message TupleKey {
  string user = 1;      // e.g., "identity:user_abc"
  string relation = 2;  // e.g., "owner"
  string object = 3;    // e.g., "tenant:tenant_123"
}

Check:

rpc Check(CheckRequest) returns (CheckResponse);

message CheckRequest {
  TupleKey tuple_key = 1;
}

message CheckResponse {
  bool allowed = 1;
}

BatchCheck:

rpc BatchCheck(BatchCheckRequest) returns (BatchCheckResponse);

message BatchCheckItem {
  TupleKey tuple_key = 1;
  string correlation_id = 2;
}

message BatchCheckRequest {
  repeated BatchCheckItem checks = 1;
}

message BatchCheckResult {
  bool allowed = 1;
  string error = 2;
}

message BatchCheckResponse {
  map<string, BatchCheckResult> results = 1;  // keyed by correlation_id
}

Write:

rpc Write(WriteRequest) returns (WriteResponse);

message WriteRequest {
  repeated TupleKey writes = 1;   // tuples to add
  repeated TupleKey deletes = 2;  // tuples to remove
}

message WriteResponse {}

Read:

rpc Read(ReadRequest) returns (ReadResponse);

message ReadRequest {
  TupleKey tuple_key = 1;  // partial filter — each field optional
  int32 page_size = 2;
  string page_token = 3;
}

message Tuple {
  TupleKey key = 1;
  google.protobuf.Timestamp timestamp = 2;
}

message ReadResponse {
  repeated Tuple tuples = 1;
  string next_page_token = 2;
}

ListObjects:

rpc ListObjects(ListObjectsRequest) returns (ListObjectsResponse);

message ListObjectsRequest {
  string type = 1;       // e.g., "tenant"
  string relation = 2;   // e.g., "member"
  string user = 3;       // e.g., "identity:user_abc"
}

message ListObjectsResponse {
  repeated string objects = 1;  // e.g., ["tenant:tenant_123"]
}

ListUsers:

rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);

message UserTypeFilter {
  string type = 1;       // e.g., "identity"
  string relation = 2;   // optional, for usersets
}

message ListUsersRequest {
  string object = 1;                       // e.g., "tenant:tenant_123"
  string relation = 2;                     // e.g., "member"
  repeated UserTypeFilter user_filters = 3;  // at least one required
}

message User {
  oneof user {
    string object = 1;     // e.g., "identity:user_abc"
    string wildcard = 2;   // e.g., "identity:*"
  }
}

message ListUsersResponse {
  repeated User users = 1;
}

Conventions

  • Follow STANDARD Buf lint rules
  • Follow FILE Buf breaking change policy
  • Use google.protobuf.Timestamp for timestamps (import google/protobuf/timestamp.proto)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions