// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.agentidentitycredentials.v1alpha;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";

option go_package = "cloud.google.com/go/agentidentitycredentials/apiv1alpha/agentidentitycredentialspb;agentidentitycredentialspb";
option java_multiple_files = true;
option java_outer_classname = "AuthProviderCredentialsServiceProto";
option java_package = "com.google.cloud.agentidentitycredentials.v1alpha";
option (google.api.resource_definition) = {
  type: "agentidentity.googleapis.com/AuthProvider"
  pattern: "projects/{project}/locations/{location}/authProviders/{auth_provider}"
};

// Service for managing AuthProvider Credentials.
service AuthProviderCredentialsService {
  option (google.api.default_host) = "agentidentitycredentials.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Retrieves authorization credentials for an authprovider, or indicates what
  // action needs to be taken to obtain credentials.
  // If the `token` field in the response is populated, credential retrieval
  // was successful.
  // If one of the fields in the `status` oneof is populated, further action is
  // required to obtain credentials, such as redirecting the user for consent.
  // View comments on `RetrieveCredentialsResponse` for more information.
  rpc RetrieveCredentials(RetrieveCredentialsRequest)
      returns (RetrieveCredentialsResponse) {
    option (google.api.http) = {
      post: "/v1alpha/{auth_provider=projects/*/locations/*/authProviders/*}/credentials:retrieve"
      body: "*"
    };
    option (google.api.method_signature) = "auth_provider,user_id";
  }

  // Finalizes the credentials after a successful consent flow.
  rpc FinalizeCredentials(FinalizeCredentialsRequest)
      returns (FinalizeCredentialsResponse) {
    option (google.api.http) = {
      post: "/v1alpha/{auth_provider=projects/*/locations/*/authProviders/*}/credentials:finalize"
      body: "*"
    };
  }
}

// Request message for RetrieveCredentials.
message RetrieveCredentialsRequest {
  // Required. The parent resource name of the AuthProvider.
  // Format:
  // `projects/{project}/locations/{location}/authProviders/{auth_provider}`
  string auth_provider = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "agentidentity.googleapis.com/AuthProvider"
    }
  ];

  // Required. The identity of the end user.
  string user_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The OAuth scopes required for this access.
  repeated string scopes = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The URI to redirect the user to after consent is completed.
  // This field is required for authproviders using the 3-legged OAuth flow. For
  // other authprovider types, this field is unused but not rejected.
  string continue_uri = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Input only. Set this field only if the previous token was expired
  // or invalid. This value must be the full, previously returned token string.
  // Will trigger a refresh of the access token with a stored refresh token, if
  // possible, or a new consent flow.
  string force_refresh_token = 7 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = INPUT_ONLY
  ];
}

// Response message for RetrieveCredentials.
// Contains the access tokens and related artifacts.
message RetrieveCredentialsResponse {
  // Message indicating successful retrieval of credentials.
  message Success {
    // The retrieved access token or credential for the end user.
    //
    // On MCPTool call, for an invalid token OAuth spec says this should
    // return 401 or 403, but MCPServers may implement this differently. If you
    // get any flavor of `PERMISSION_DENIED`, retry your original request to
    // RetrieveCredentials with
    // [force_refresh_token][google.cloud.agentidentitycredentials.v1alpha.RetrieveCredentialsRequest.force_refresh_token]
    // set to the expired/invalid token string, which will fetch a new token or
    // initiate a new consent flow.
    string token = 1;

    // The HTTP header name where the token should be placed.
    string header = 2;

    // The expiration time of the token.
    //
    // This does not guarantee that the token will be valid until this time,
    // since the token could be revoked earlier. There could also be clock skew
    // between the auth provider and the client so it may expire slightly
    // earlier. If not set, the token might be permanent or it may be that the
    // service does not (or cannot) know when it will expire.
    google.protobuf.Timestamp expire_time = 3;

    // The scopes actually associated with the retrieved token.
    //
    // End users may have rejected some requested scopes, or the third-party
    // authorization servers can return a different set of scopes than what was
    // asked for. Callers should verify that all required scopes for their
    // intended use are included in this list.
    repeated string scopes = 4;
  }

  // Indicates that the user must visit the provided URI to consent to
  // delegate permission to the agent to act on their behalf. The caller can
  // either poll the provided operation, or await the user ID validation
  // callback
  message UriConsentRequired {
    // Output only. The URL where the user should be redirected to grant
    // consent. This will always be present.
    string authorization_uri = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. A one-time, randomly generated value that validates the
    // entire consent flow is handled by a single user, avoiding CSRF attacks.
    // It must be submitted with the FinalizeCredentials request to complete the
    // OAuth exchange. This will always be present. Implemented per
    // https://www.rfc-editor.org/rfc/rfc6819#section-5.3.5
    string consent_nonce = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Indicates that the credential retrieval is pending. The caller should
  // retry the RetrieveCredentials request after some time.
  message Pending {}

  // Indicates the user has rejected the permission delegation or cancelled the
  // request.
  message ConsentRejected {}

  // The result of the RetrieveCredentials call.
  // This oneof indicates whether credentials were successfully retrieved, or
  // what action needs to be taken.
  //
  // Note: All polling or retries should follow an exponential backoff
  // (seconds): `0.5`, `1`, `2`, `4`, `8`, etc...
  oneof result {
    // Message indicating credentials were successfully retrieved.
    Success success = 1;

    // Message indicating credential retrieval is pending.
    Pending pending = 2;

    // Message indicating uri based consent is required.
    UriConsentRequired uri_consent_required = 3;

    // Message indicating consent was rejected.
    ConsentRejected consent_rejected = 4;
  }
}

// Request message for FinalizeCredentials.
message FinalizeCredentialsRequest {
  // Required. The resource name of the AuthProvider.
  // Format:
  // `projects/{project}/locations/{location}/authProviders/{auth_provider}`
  string auth_provider = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "agentidentity.googleapis.com/AuthProvider"
    }
  ];

  // Required. The identity of the end user.
  string user_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The encrypted state passed back from the consent flow.
  bytes user_id_validation_state = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The same consent_nonce value that was provided during redirect in
  // the UriConsentRequired metadata.
  string consent_nonce = 4 [(google.api.field_behavior) = REQUIRED];
}

// Response message for FinalizeCredentials. Intentionally empty
message FinalizeCredentialsResponse {}
