// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

syntax = "proto3";

package hashicorp.consul.internal.connect;

import "google/protobuf/timestamp.proto";
import "private/pbcommon/common.proto";

// CARoots is the list of all currently trusted CA Roots.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.IndexedCARoots
// output=connect.gen.go
// name=StructsIndexedCARoots
message CARoots {
  // ActiveRootID is the ID of a root in Roots that is the active CA root.
  // Other roots are still valid if they're in the Roots list but are in
  // the process of being rotated out.
  string ActiveRootID = 1;

  // TrustDomain is the identification root for this Consul cluster. All
  // certificates signed by the cluster's CA must have their identifying URI in
  // this domain.
  //
  // This does not include the protocol (currently spiffe://) since we may
  // implement other protocols in future with equivalent semantics. It should be
  // compared against the "authority" section of a URI (i.e. host:port).
  //
  // We need to support migrating a cluster between trust domains to support
  // Multi-DC migration in Enterprise. In this case the current trust domain is
  // here but entries in Roots may also have ExternalTrustDomain set to a
  // non-empty value implying they were previous roots that are still trusted
  // but under a different trust domain.
  //
  // Note that we DON'T validate trust domain during AuthZ since it causes
  // issues of loss of connectivity during migration between trust domains. The
  // only time the additional validation adds value is where the cluster shares
  // an external root (e.g. organization-wide root) with another distinct Consul
  // cluster or PKI system. In this case, x509 Name Constraints can be added to
  // enforce that Consul's CA can only validly sign or trust certs within the
  // same trust-domain. Name constraints as enforced by TLS handshake also allow
  // seamless rotation between trust domains thanks to cross-signing.
  string TrustDomain = 2;

  // Roots is a list of root CA certs to trust.
  repeated CARoot Roots = 3;

  // QueryMeta here is mainly used to contain the latest Raft Index that could
  // be used to perform a blocking query.
  // mog: func-to=QueryMetaTo func-from=QueryMetaFrom
  common.QueryMeta QueryMeta = 4;
}

// CARoot is the trusted CA Root.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.CARoot
// output=connect.gen.go
// name=StructsCARoot
message CARoot {
  // ID is a globally unique ID (UUID) representing this CA root.
  string ID = 1;

  // Name is a human-friendly name for this CA root. This value is
  // opaque to Consul and is not used for anything internally.
  string Name = 2;

  // SerialNumber is the x509 serial number of the certificate.
  uint64 SerialNumber = 3;

  // SigningKeyID is the ID of the public key that corresponds to the private
  // key used to sign leaf certificates. Is is the HexString format of the
  // raw AuthorityKeyID bytes.
  string SigningKeyID = 4;

  // ExternalTrustDomain is the trust domain this root was generated under. It
  // is usually empty implying "the current cluster trust-domain". It is set
  // only in the case that a cluster changes trust domain and then all old roots
  // that are still trusted have the old trust domain set here.
  //
  // We currently DON'T validate these trust domains explicitly anywhere, see
  // IndexedRoots.TrustDomain doc. We retain this information for debugging and
  // future flexibility.
  string ExternalTrustDomain = 5;

  // Time validity bounds.
  // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto
  google.protobuf.Timestamp NotBefore = 6;
  // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto
  google.protobuf.Timestamp NotAfter = 7;

  // RootCert is the PEM-encoded public certificate.
  string RootCert = 8;

  // IntermediateCerts is a list of PEM-encoded intermediate certs to
  // attach to any leaf certs signed by this CA.
  repeated string IntermediateCerts = 9;

  // SigningCert is the PEM-encoded signing certificate and SigningKey
  // is the PEM-encoded private key for the signing certificate. These
  // may actually be empty if the CA plugin in use manages these for us.
  string SigningCert = 10;
  string SigningKey = 11;

  // Active is true if this is the current active CA. This must only
  // be true for exactly one CA. For any method that modifies roots in the
  // state store, tests should be written to verify that multiple roots
  // cannot be active.
  bool Active = 12;

  // RotatedOutAt is the time at which this CA was removed from the state.
  // This will only be set on roots that have been rotated out from being the
  // active root.
  // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto
  google.protobuf.Timestamp RotatedOutAt = 13;

  // PrivateKeyType is the type of the private key used to sign certificates. It
  // may be "rsa" or "ec". This is provided as a convenience to avoid parsing
  // the public key to from the certificate to infer the type.
  string PrivateKeyType = 14;

  // PrivateKeyBits is the length of the private key used to sign certificates.
  // This is provided as a convenience to avoid parsing the public key from the
  // certificate to infer the type.
  // mog: func-to=int func-from=int32
  int32 PrivateKeyBits = 15;

  // mog: func-to=RaftIndexTo func-from=RaftIndexFrom
  common.RaftIndex RaftIndex = 16;
}

// RaftIndex is used to track the index used while creating
// or modifying a given struct type.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.IssuedCert
// output=connect.gen.go
// name=StructsIssuedCert
message IssuedCert {
  // SerialNumber is the unique serial number for this certificate.
  // This is encoded in standard hex separated by :.
  string SerialNumber = 1;

  // CertPEM and PrivateKeyPEM are the PEM-encoded certificate and private
  // key for that cert, respectively. This should not be stored in the
  // state store, but is present in the sign API response.
  string CertPEM = 2;
  string PrivateKeyPEM = 3;

  // Service is the name of the service for which the cert was issued.
  string Service = 4;
  // ServiceURI is the cert URI value.
  string ServiceURI = 5;

  // Agent is the name of the node for which the cert was issued.
  string Agent = 6;
  // AgentURI is the cert URI value.
  string AgentURI = 7;

  // Kind is the kind of service for which the cert was issued.
  // mog: func-to=structs.ServiceKind func-from=string
  string Kind = 12;
  // KindURI is the cert URI value.
  string KindURI = 13;

  // ServerURI is the URI value of a cert issued for a server agent.
  // The same URI is shared by all servers in a Consul datacenter.
  string ServerURI = 14;

  // WorkloadIdentity is the name of the workload identity for which the cert was issued.
  string WorkloadIdentity = 15;
  // WorkloadIdentityURI is the cert URI value.
  string WorkloadIdentityURI = 16;

  // ValidAfter and ValidBefore are the validity periods for the
  // certificate.
  // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto
  google.protobuf.Timestamp ValidAfter = 8;
  // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto
  google.protobuf.Timestamp ValidBefore = 9;

  // EnterpriseMeta is the Consul Enterprise specific metadata
  // mog: func-to=EnterpriseMetaTo func-from=EnterpriseMetaFrom
  common.EnterpriseMeta EnterpriseMeta = 10;

  // mog: func-to=RaftIndexTo func-from=RaftIndexFrom
  common.RaftIndex RaftIndex = 11;
}
