syntax = "proto3";

package confidence.iam.v1;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
import "google/api/resource.proto";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "confidence/auth/v1/auth.proto";
import "google/protobuf/field_mask.proto";
import "google/api/client.proto";
import "confidence/iam/v1/events/events.proto";
import "confidence/iam/v1/iam.proto";
import "confidence/api/annotations.proto";

option java_package = "com.spotify.confidence.iam.v1";
option java_multiple_files = true;
option java_outer_classname = "ApiProto";

// Manages users, api clients, roles and permissions.
service IamService {
  option (confidence.api.service_name) = "IAM";
  option (confidence.api.hosts) = "iam.eu.confidence.dev";
  option (confidence.api.hosts) = "iam.us.confidence.dev";

  // List users within the organization.
  rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) {
    option (google.api.http) = {
      get: "/v1/users"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_USERS;
    };
  }

  // Fetch a single user.
  rpc GetUser(GetUserRequest) returns (User) {
    option (google.api.http) = {
      get: "/v1/{name=users/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_USERS;
    };
  }

  // List roles.
  rpc ListRoles(ListRolesRequest) returns (ListRolesResponse) {
    option (google.api.http) = {
      get: "/v1/roles"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_ROLES;
    };
  }

  // Fetch a single role.
  rpc GetRole(GetRoleRequest) returns (Role) {
    option (google.api.http) = {
      get: "/v1/{name=roles/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_ROLES;
    };
  }

  // List roles that a specific user belongs to.
  rpc ListUserRoles(ListUserRolesRequest) returns (ListUserRolesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=users/*}/roles"
    };
    option (google.api.method_signature) = "parent";
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_ROLES;
    };
  }

  // Add a role to a user.
  rpc AddUserRole(AddUserRoleRequest) returns (AddUserRoleResponse) {
    option (google.api.http) = {
      post: "/v1/{user=users/*}:addUserRole",
      body: "*"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: UPDATE_USERS;
    };
  }

  // Remove a role from a user.
  rpc RemoveUserRole(RemoveUserRoleRequest) returns (RemoveUserRoleResponse) {
    option (google.api.http) = {
      post: "/v1/{user=users/*}:removeUserRole",
      body: "*"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: UPDATE_USERS;
    };
  }

  // List API clients.
  rpc ListApiClients(ListApiClientsRequest) returns (ListApiClientsResponse) {
    option (google.api.http) = {
      get: "/v1/apiClients"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_API_CLIENTS;
    };
  }

  // Fetch an API client.
  rpc GetApiClient(GetApiClientRequest) returns (ApiClient) {
    option (google.api.http) = {
      get: "/v1/{name=apiClients/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_API_CLIENTS;
    };
  }

  // Create a new API client. An API client is used to programmatically interact
  // with the Confidence APIs.
  rpc CreateApiClient(CreateApiClientRequest) returns (ApiClient) {
    option (google.api.http) = {
      post: "/v1/apiClients"
      body: "api_client"
    };
    option (google.api.method_signature) = "api_client";
    option (confidence.auth.v1.auth) = {
      required_permission: CREATE_API_CLIENTS
    };
  }

  // Update an existing API client.
  rpc UpdateApiClient(UpdateApiClientRequest) returns (ApiClient) {
    option (google.api.http) = {
      patch: "/v1/{api_client.name=apiClients/*}"
      body: "api_client"
    };
    option (google.api.method_signature) = "api_client,update_mask";
    option (confidence.auth.v1.auth) = {
      required_permission: UPDATE_API_CLIENTS
    };
  }

  // Delete an API client.
  rpc DeleteApiClient(DeleteApiClientRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=apiClients/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: DELETE_API_CLIENTS
    };
  }

  // Create a new client. A `Client` is used to resolve flags from all
  // applications of a particular type, like an iOS client. To resolve a flag
  // you need to pass credentials from a specific `Client` and have the flag
  // enabled for that client.
  rpc CreateClient(CreateClientRequest) returns (Client) {
    option (google.api.http) = {
      post: "/v1/clients"
      body: "client"
    };
    option (google.api.method_signature) = "client";
    option (confidence.auth.v1.auth) = {
      required_permission: CREATE_CLIENTS
    };
  }

  // Get an existing client.
  rpc GetClient(GetClientRequest) returns (Client) {
    option (google.api.http) = {
      get: "/v1/{name=clients/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_CLIENTS
    };
  }

  // Delete an existing client.
  rpc DeleteClient(DeleteClientRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=clients/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: UPDATE_CLIENTS
    };
  }

  // List clients. Clients are listed in no particular order.
  rpc ListClients(ListClientsRequest) returns (ListClientsResponse) {
    option (google.api.http) = {
      get: "/v1/clients"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_CLIENTS
    };
  }

  // Create a new client credential. A credential is a type of secret used to
  // authenticate a client when resolving flags.
  rpc CreateClientCredential(CreateClientCredentialRequest) returns (ClientCredential) {
    option (google.api.http) = {
      post: "/v1/{parent=clients/*}/credentials"
      body: "client_credential"
    };
    option (google.api.method_signature) = "parent,client_credential";
    option (confidence.auth.v1.auth) = {
      required_permission: CREATE_CLIENT_CREDENTIALS
    };
  }

  // Get an existing client credential.
  rpc GetClientCredential(GetClientCredentialRequest) returns (ClientCredential) {
    option (google.api.http) = {
      get: "/v1/{name=clients/*/credentials/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_CLIENT_CREDENTIALS
    };
  }

  // List client credentials. Credentials are listed in no particular order.
  rpc ListClientCredentials(ListClientCredentialsRequest) returns (ListClientCredentialsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=clients/*}/credentials"
    };
    option (google.api.method_signature) = "parent";
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_CLIENT_CREDENTIALS
    };
  }

  // Delete a client credential.
  rpc DeleteClientCredential(DeleteClientCredentialRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=clients/*/credentials/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: UPDATE_CLIENT_CREDENTIALS
    };
  }

  // List permissions.
  rpc ListPermissions(ListPermissionsRequest) returns (ListPermissionsResponse) {
    option (google.api.http) = {
      get: "/v1/permissions"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: READ_API_CLIENTS
    };
  }

  // List the invitations currently existing for this account.
  rpc ListUserInvitations(ListUserInvitationsRequest) returns (ListUserInvitationsResponse) {
    option (google.api.http) = {
      get: "/v1/userInvitations"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_USER_INVITATIONS;
    };
  }

  // Get an invitation.
  rpc GetUserInvitation(GetUserInvitationRequest) returns (UserInvitation) {
    option (google.api.http) = {
      get: "/v1/{name=userInvitations/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_USER_INVITATIONS;
    };
  }

  // Creates a new invitation for a user and sends an email with a login link.
  rpc CreateUserInvitation(CreateUserInvitationRequest) returns (UserInvitation) {
    option (google.api.http) = {
      post: "/v1/userInvitations"
      body: "user_invitation"
    };
    option (google.api.method_signature) = "user_invitation";
    option (confidence.auth.v1.auth) = {
      required_permission: CREATE_USER_INVITATIONS
    };
  }

  // Revokes an existing invitation.
  rpc DeleteUserInvitation(DeleteUserInvitationRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=userInvitations/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: DELETE_USER_INVITATIONS
    };
  }

  // List the oauth apps.
  rpc ListOAuthApps(ListOAuthAppsRequest) returns (ListOAuthAppsResponse) {
    option (google.api.http) = {
      get: "/v1/oauthApps"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_OAUTH_APPS;
    };
  }

  // Gets an OAuth App by name.
  rpc GetOAuthApp(GetOAuthAppRequest) returns (OAuthApp) {
    option (google.api.http) = {
      get: "/v1/{name=oauthApps/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_OAUTH_APPS;
    };
  }

  // (-- api-linter: core::0133::method-signature=disabled
  //     aip.dev/not-precedent: We use oauth_app. --)
  // Creates a new OAuth app.
  rpc CreateOAuthApp(CreateOAuthAppRequest) returns (OAuthApp) {
    option (google.api.http) = {
      post: "/v1/oauthApps"
      body: "oauth_app"
    };
    option (google.api.method_signature) = "oauth_app";
    option (confidence.auth.v1.auth) = {
      required_permission: CREATE_OAUTH_APPS
    };
  }
  // (-- api-linter: core::0134::http-uri-name=disabled
  //     aip.dev/not-precedent: We use oauth_app. --)
  // (-- api-linter: core::0134::http-body=disabled
  //     aip.dev/not-precedent: We use oauth_app. --)
  // (-- api-linter: core::0134::method-signature=disabled
  //     aip.dev/not-precedent: We use oauth_app. --)
  // Updates an existing OAuth App.
  rpc UpdateOAuthApp(UpdateOAuthAppRequest) returns (OAuthApp) {
    option (google.api.http) = {
      patch: "/v1/{oauth_app.name=oauthApps/*}"
      body: "oauth_app"
    };
    option (google.api.method_signature) = "oauth_app,update_mask";
    option (confidence.auth.v1.auth) = {
      required_permission: UPDATE_OAUTH_APPS
    };
  }

  // Deletes an OAuth app.
  rpc DeleteOAuthApp(DeleteOAuthAppRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=oauthApps/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: DELETE_OAUTH_APPS
    };
  }

  // (-- api-linter: core::0131::http-uri-name=disabled
  //     aip.dev/not-precedent: No need to pass in the name of the current user. --)
  // (-- api-linter: core::0131::method-signature=disabled
  //     aip.dev/not-precedent: No need to pass in the name of the current user. --)
  // Gets the currently logged in user
  rpc GetCurrentUser(GetCurrentUserRequest) returns (CurrentUser) {
    option (google.api.http) = {
      get: "/v1/currentUser"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: READ_USERS
    };
  }


  // Gets a crypto key by name.
  rpc GetCryptoKey(GetCryptoKeyRequest) returns (CryptoKey) {
    option (google.api.http) = {
      get: "/v1/{name=cryptoKeys/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_CRYPTO_KEYS;
    };
  }

  // Creates a new crypto key.
  rpc CreateCryptoKey(CreateCryptoKeyRequest) returns (CryptoKey) {
    option (google.api.http) = {
      post: "/v1/cryptoKeys"
      body: "crypto_key"
    };
    option (google.api.method_signature) = "crypto_key,crypto_key_id";
    option (confidence.auth.v1.auth) = {
      required_permission: CREATE_CRYPTO_KEYS;
    };
  }

  // Deletes a crypto key. This is a soft delete, the entity is kept but the cryptographic key is destroyed.
  rpc DeleteCryptoKey(DeleteCryptoKeyRequest) returns (CryptoKey) {
    option (google.api.http) = {
      delete: "/v1/{name=cryptoKeys/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: DELETE_CRYPTO_KEYS;
    };
  }

  // List the crypto keys.
  rpc ListCryptoKeys(ListCryptoKeysRequest) returns (ListCryptoKeysResponse) {
    option (google.api.http) = {
      get: "/v1/cryptoKeys"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_CRYPTO_KEYS;
    };
  }

  // Gets an identity by name.
  rpc GetIdentity(GetIdentityRequest) returns (Identity) {
    option (google.api.http) = {
      get: "/v1/{name=identities/*}"
    };
    option (google.api.method_signature) = "name";
    option (confidence.auth.v1.auth) = {
      required_permission: READ_USERS;
    };
  }

  // List API clients.
  rpc ListIdentities(ListIdentitiesRequest) returns (ListIdentitiesResponse) {
    option (google.api.http) = {
      get: "/v1/identities"
    };
    option (confidence.auth.v1.auth) = {
      required_permission: LIST_USERS;
    };
  }
}

// Request for listing identities.
message ListIdentitiesRequest {
  // The maximum number of identities to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of identities.
message ListIdentitiesResponse {
  // Partial list of identities.
  repeated Identity identities = 1 [(google.api.field_behavior) = OPTIONAL];

  // A token that can be used to fetch more identities, empty if no more
  // identities are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for getting an identity
message GetIdentityRequest {
  // Name of the identity to get.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/Identity",
    (google.api.field_behavior) = REQUIRED
  ];
}
// Request for deleting an crypto key.
message DeleteCryptoKeyRequest {
  // Name of the crypto key to delete.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/CryptoKey",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request for listing crypto keys.
message ListCryptoKeysRequest {
  // The maximum number of crypto keys to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

  // If deleted crypto keys should be included. By default false.
  bool show_deleted = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of crypto keys.
message ListCryptoKeysResponse {
  // Partial list of returned crypto keys.
  repeated CryptoKey crypto_keys = 1 [(google.api.field_behavior) = OPTIONAL];

  // A token that can be used to fetch more crypto keys, empty if no more
  // crypto keys are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request to create a crypto key
message CreateCryptoKeyRequest {
  // CryptoKey configuration.
  CryptoKey crypto_key = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
  // The ID that the crypto key should have
  string crypto_key_id = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request to get a crypto key
message GetCryptoKeyRequest {
  // The name of the crypto key to get.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/CryptoKey",
    (google.api.field_behavior) = REQUIRED
  ];
}

// (-- api-linter: core::0131::request-name-required=disabled
//     aip.dev/not-precedent: No need to pass in the name of the current user. --)
//A request to get the current user
message GetCurrentUserRequest {

}

// Request for fetching an OAuthApp.
message GetOAuthAppRequest {
  // The name of the oauth app that you want to fetch.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/OAuthApp",
    (google.api.field_behavior) = REQUIRED
  ];
}

// (-- api-linter: core::0133::request-resource-field=disabled
//     aip.dev/not-precedent: We use oauth_app. --)
// (-- api-linter: core::0133::request-parent-required=disabled
//     aip.dev/not-precedent: The oauth apps have no parent. --)
// Request for creating an OAuthApp.
message CreateOAuthAppRequest {
  // OAuthApp configuration.
  OAuthApp oauth_app = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// (-- api-linter: core::0134::request-unknown-fields=disabled
//     aip.dev/not-precedent: We use oauth_app. --)
// (-- api-linter: core::0134::request-resource-field=disabled
//     aip.dev/not-precedent: We use oauth_app. --)
// Request for updating an OAuthApp.
message UpdateOAuthAppRequest {
  // The oauth app to update.
  OAuthApp oauth_app = 1 [
    (google.api.field_behavior) = REQUIRED
  ];

  // The list of fields to update.
  // Fields are specified relative to the OAuthApp
  // (e.g. `display_name`; *not* `oauth_app.display_name`).
  google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for deleting an OAuthApp.
message DeleteOAuthAppRequest {
  // Name of the OAuthApp.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/OAuthApp",
    (google.api.field_behavior) = REQUIRED
  ];
}

// (-- api-linter: core::0132::request-parent-required=disabled
//     aip.dev/not-precedent: OAuthApp have no parent. --)
// Request for listing OAuthApps.
message ListOAuthAppsRequest {
  // The maximum number of OAuthApps to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of OAuthApps.
message ListOAuthAppsResponse {
  // (-- api-linter: core::0132::response-unknown-fields=disabled
  //     aip.dev/not-precedent: We use oauth_apps. --)
  // Partial list of returned OAuthApps.
  repeated OAuthApp oauth_apps = 1 [(google.api.field_behavior) = OPTIONAL];

  // A token that can be used to fetch more OAuthAPps, empty if no more
  // OAuthApps are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for listing user invitations.
message ListUserInvitationsRequest {
  // The maximum number of user invitations to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of user invitations.
message ListUserInvitationsResponse {
  // List of user invitations.
  repeated UserInvitation user_invitations = 1 [(google.api.field_behavior) = OPTIONAL];

  // A token that can be used to fetch more user invitations, empty if no more
  // user invitations are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request to delete a user invitation.
message DeleteUserInvitationRequest {
  // Name of the user invitation to delete.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/UserInvitation",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request to create a new user invitation.
message CreateUserInvitationRequest {
  // The user invitation to create.
  UserInvitation user_invitation = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request to get a user invitation.
message GetUserInvitationRequest {
  // Name of the user invitation to get.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/UserInvitation",
    (google.api.field_behavior) = REQUIRED
  ];
}

// (-- api-linter: core::0132::request-parent-required=disabled
//     aip.dev/not-precedent: Permissions have no parent. --)
// Request for listing permissions.
message ListPermissionsRequest {
  // The maximum number of permissions to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of permissions.
message ListPermissionsResponse {
  // Partial list of permissions.
  repeated PermissionWithScope permissions = 1 [(google.api.field_behavior) = OPTIONAL];

  // A token that can be used to fetch more permissions, empty if no more
  // permissions are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request to delete an API client.
message DeleteApiClientRequest {
  // Name of the API client to delete.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/ApiClient",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request to create an API client.
message CreateApiClientRequest {
  // The API client to create.
  ApiClient api_client = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request to update an API client.
message UpdateApiClientRequest {
  // The updated API client.
  ApiClient api_client = 1 [
    (google.api.field_behavior) = REQUIRED
  ];

  // The list of fields to update.
  // Fields are specified relative to the API client
  // (e.g. `display_name`; *not* `api_client.display_name`).
  google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request to fetch an API client.
message GetApiClientRequest {
  // Name of the API client to fetch.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/ApiClient",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request for listing API clients.
message ListApiClientsRequest {
  // The maximum number of API clients to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of API clients.
message ListApiClientsResponse {
  // Partial list of returned API clients.
  repeated ApiClient api_clients = 1 [(google.api.field_behavior) = OPTIONAL];

  // A token that can be used to fetch more API clients, empty if no more
  // API clients are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request to remove a role from a user.
message RemoveUserRoleRequest {
  // Name of the user on the form `users/<id>`.
  string user = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/User",
    (google.api.field_behavior) = REQUIRED
  ];

  // Name of the role to remove on the form `roles/<id>`.
  string role = 2 [
    (google.api.resource_reference).type = "iam.confidence.dev/Role",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Response for removing a role.
message RemoveUserRoleResponse {

}

// Request for adding a role to a user.
message AddUserRoleRequest {
  // Name of the user on the form `users/<id>`.
  string user = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/User",
    (google.api.field_behavior) = REQUIRED
  ];

  // Name of the role to remove on the form `roles/<id>`.
  string role = 2 [
    (google.api.resource_reference).type = "iam.confidence.dev/Role",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Response for adding a role.
message AddUserRoleResponse {

}

// Fetch a specific role.
message GetRoleRequest {
  // Name of the role on the form `roles/<id>`.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/Role",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request for listing user roles.
message ListUserRolesRequest {
  // The maximum number of user roles to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

  // Name of the user to list roles for on the form `users/<id>`.
  string parent = 3 [
    (google.api.resource_reference).type = "iam.confidence.dev/User",
    (google.api.field_behavior) = REQUIRED
  ];
}

// (-- api-linter: core::0158::response-plural-first-field=disabled
//     aip.dev/not-precedent: We use UserRoles here. --)
// Paginated list of user roles.
message ListUserRolesResponse {
  // Partial list of returned roles of the user.
  repeated Role user_roles = 1 [(google.api.field_behavior) = REQUIRED];

  // A token that can be used to fetch more user roles, empty if no more
  // user roles are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for listing roles.
message ListRolesRequest {
  // The maximum number of roles to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of roles.
message ListRolesResponse {
  // Partial list of returned roles.
  repeated Role roles = 1 [(google.api.field_behavior) = REQUIRED];

  // A token that can be used to fetch more roles, empty if no more
  // roles are available.
  string next_page_token = 2;
}

// A role is a named set of permissions, like `Admin` or `Flag Editor`.
message Role {
  option (google.api.resource) = {
    type: "iam.confidence.dev/Role"
    pattern: "roles/{role}"
    singular: "role"
    plural: "roles"
  };
  // Name of the role on the form `roles/<id>`.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Human friendly name of the role.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // List of permissions that having this role implies.
  repeated string permissions = 3;
}

// Request to fetch a user.
message GetUserRequest {
  // Name of the user on the form `users/<id>`.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/User",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request to list users.
message ListUsersRequest {
  // The maximum number of users to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Paginated list of users.
message ListUsersResponse {
  // Partial list of returned users.
  repeated User users = 1 [(google.api.field_behavior) = REQUIRED];

  // A token that can be used to fetch more users, empty if no more
  // users are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Create a client used for resolving flags.
message CreateClientRequest {
  // Properties of the client to be created.
  Client client = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// Get an existing client.
message GetClientRequest {
  // Resource reference to a client.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/Client",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Deletes an existing client.
message DeleteClientRequest {
  // Resource reference to a client.
  string name = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/Client",
    (google.api.field_behavior) = REQUIRED
  ];
}

// List clients.
message ListClientsRequest {
  // The maximum number of clients to fetch.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}

// The returned list of clients.
message ListClientsResponse {
  // List of clients.
  repeated Client clients = 1 [(google.api.field_behavior) = REQUIRED];

  // A token that can be used to fetch more clients, empty if no more clients
  // are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}


// Create a new client credential used to authenticate a client.
message CreateClientCredentialRequest {
  // The resource reference to a client.
  string parent = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/Client",
    (google.api.field_behavior) = REQUIRED
  ];

  // The type of credential to create.
  ClientCredential client_credential = 2 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// Get an existing client credential.
message GetClientCredentialRequest {
  // The resource reference to a client credential.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/ClientCredential",
    (google.api.field_behavior) = REQUIRED
  ];
}

// Delete an existing client credential.
message DeleteClientCredentialRequest {
  // The resource reference to a client credential.
  string name = 1  [
    (google.api.resource_reference).type = "iam.confidence.dev/ClientCredential",
    (google.api.field_behavior) = REQUIRED
  ];
}

// List client credentials.
message ListClientCredentialsRequest {
  // The resource reference to a client.
  string parent = 1 [
    (google.api.resource_reference).type = "iam.confidence.dev/Client",
    (google.api.field_behavior) = REQUIRED
  ];

  // The maximum number of credentials to fetch.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Token used for pagination.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// The returned list of client credentials.
message ListClientCredentialsResponse {
  // List of client credentials.
  repeated ClientCredential client_credentials = 1 [(google.api.field_behavior) = REQUIRED];

  // A token that can be used to fetch more client credentials, empty if no more
  // client credentials are available.
  string next_page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}


