// Copyright IBM Corp. 2020, 2026
// SPDX-License-Identifier: BUSL-1.1

syntax = "proto3";

// Package store provides protobufs for storing types in the vault
// credential package.
package controller.storage.credential.vault.store.v1;

import "controller/custom_options/v1/options.proto";
import "controller/storage/timestamp/v1/timestamp.proto";

option go_package = "github.com/hashicorp/boundary/internal/credential/vault/store;store";

message CredentialStore {
  // public_id is a surrogate key suitable for use in a public API.
  // @inject_tag: `gorm:"primary_key"`
  string public_id = 1;

  // The create_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp create_time = 2;

  // The update_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp update_time = 3;

  // The delete_time is set by the application.
  // @inject_tag: `gorm:"default:null"`
  timestamp.v1.Timestamp delete_time = 4;

  // name is optional. If set, it must be unique within project_id.
  // @inject_tag: `gorm:"default:null"`
  string name = 5 [(custom_options.v1.mask_mapping) = {
    this: "Name"
    that: "name"
  }];

  // description is optional.
  // @inject_tag: `gorm:"default:null"`
  string description = 6 [(custom_options.v1.mask_mapping) = {
    this: "Description"
    that: "description"
  }];

  // The project_id of the owning project.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string project_id = 7;

  // version allows optimistic locking of the resource.
  // @inject_tag: `gorm:"default:null"`
  uint32 version = 8;

  // vault_address is the address of the vault server. This should be a
  // complete URL.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string vault_address = 9 [(custom_options.v1.mask_mapping) = {
    this: "VaultAddress"
    that: "attributes.address"
  }];

  // namespace is the vault namespace the credential store should use.
  // It is optional.
  // @inject_tag: `gorm:"default:null"`
  string namespace = 10 [(custom_options.v1.mask_mapping) = {
    this: "Namespace"
    that: "attributes.namespace"
  }];

  // ca_cert is a single PEM-encoded CA certificate to verify the Vault
  // server's SSL certificate.
  // It is optional.
  // @inject_tag: `gorm:"default:null"`
  bytes ca_cert = 11 [(custom_options.v1.mask_mapping) = {
    this: "CaCert"
    that: "attributes.ca_cert"
  }];

  // tls_server_name is the name to use as the SNI host when connecting to
  // Vault via TLS.
  // It is optional.
  // @inject_tag: `gorm:"default:null"`
  string tls_server_name = 12 [(custom_options.v1.mask_mapping) = {
    this: "TlsServerName"
    that: "attributes.tls_server_name"
  }];

  // tls_skip_verify disables verification of TLS certificates. Using this
  // option is highly discouraged as it decreases the security of data
  // transmissions to and from the Vault server.
  // @inject_tag: `gorm:"default:false"`
  bool tls_skip_verify = 13 [(custom_options.v1.mask_mapping) = {
    this: "TlsSkipVerify"
    that: "attributes.tls_skip_verify"
  }];

  // worker_filter is optional. Filters to the worker(s) who can handle Vault requests for this cred store
  // @inject_tag: `gorm:"default:null"`
  string worker_filter = 14 [(custom_options.v1.mask_mapping) = {
    this: "WorkerFilter"
    that: "attributes.worker_filter"
  }];
}

message Token {
  // token_hmac is the hmac-sha256 value of the token. The hmac key is the
  // blake2b-256 value of the token accessor.
  // @inject_tag: `gorm:"primary_key"`
  bytes token_hmac = 1;

  // token is the plain-text of the token data. We are not storing this
  // plain-text token in the database.
  // @inject_tag: `gorm:"-" wrapping:"pt,token_data"`
  bytes token = 2 [(custom_options.v1.mask_mapping) = {
    this: "Token"
    that: "attributes.token"
  }];

  // ct_token is the ciphertext of the token data. It is stored in the database.
  // @inject_tag: `gorm:"column:token;not_null" wrapping:"ct,token_data"`
  bytes ct_token = 3;

  // store_id is the ID of the owning vault credential store. A vault
  // credential store can have 0 or 1 token.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string store_id = 4;

  // create_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp create_time = 5;

  // update_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp update_time = 6;

  // last_renewal_time is the time the token was last renewed with Vault.
  // @inject_tag: `gorm:"default:null"`
  timestamp.v1.Timestamp last_renewal_time = 8;

  // expiration_time is the time the token is expected to expire.
  // expiration_time is calculated when the token is renewed.
  //
  // The calculation is:
  //   expiration_time := time.Now().Add(LeaseDuration * time.Second)
  // LeaseDuration is a value returned by Vault when the token is renewed.
  //
  // https://www.vaultproject.io/api-docs/auth/token#renew-a-token-self
  //
  // @inject_tag: `gorm:"default:null"`
  timestamp.v1.Timestamp expiration_time = 9;

  // The key_id of the kms database key used for encrypting this entry.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string key_id = 10;

  // The status of the token.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string status = 11;
}

message ClientCertificate {
  // store_id is the ID of the owning vault credential store. A vault
  // credential store can have 0 or 1 client certificate.
  // @inject_tag: `gorm:"primary_key"`
  string store_id = 1;

  // certificate is the PEM encoded certificate.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  bytes certificate = 2 [(custom_options.v1.mask_mapping) = {
    this: "Certificate"
    that: "attributes.client_certificate"
  }];

  // certificate_key is the plain-text of the certificate key data. We are
  // not storing this plain-text key in the database.
  // @inject_tag: `gorm:"-" wrapping:"pt,certificate_key_data"`
  bytes certificate_key = 3 [(custom_options.v1.mask_mapping) = {
    this: "CertificateKey"
    that: "attributes.client_certificate_key"
  }];

  // ct_certificate_key is the ciphertext of the certificate key data. It
  // is stored in the database.
  // @inject_tag: `gorm:"column:certificate_key;not_null" wrapping:"ct,certificate_key_data"`
  bytes ct_certificate_key = 4;

  // certificate_key_hmac is a sha256-hmac of the unencrypted certificate_key that
  // is returned from the API for read.  It is recalculated everytime the raw
  // certificate_key is updated.
  // @inject_tag: `gorm:"not_null"`
  bytes certificate_key_hmac = 130;

  // The key_id of the kms database key used for encrypting this entry.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string key_id = 10;
}

message CredentialLibrary {
  // public_id is a surrogate key suitable for use in a public API.
  // @inject_tag: `gorm:"primary_key"`
  string public_id = 1;

  // create_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp create_time = 2;

  // update_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp update_time = 3;

  // name is optional. If set, it must be unique within project_id.
  // @inject_tag: `gorm:"default:null"`
  string name = 4 [(custom_options.v1.mask_mapping) = {
    this: "Name"
    that: "name"
  }];

  // description is optional.
  // @inject_tag: `gorm:"default:null"`
  string description = 5 [(custom_options.v1.mask_mapping) = {
    this: "Description"
    that: "description"
  }];

  // store_id of the owning vault credential store.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string store_id = 6;

  // version allows optimistic locking of the resource.
  // @inject_tag: `gorm:"default:null"`
  uint32 version = 7;

  // vault_path is the path in Vault to request credentials from.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string vault_path = 8 [(custom_options.v1.mask_mapping) = {
    this: "VaultPath"
    that: "attributes.path"
  }];

  // The HTTP method the library uses to communicate with Vault.
  // It must be set. Can only be GET or POST.
  // @inject_tag: `gorm:"not_null"`
  string http_method = 9 [(custom_options.v1.mask_mapping) = {
    this: "HttpMethod"
    that: "attributes.http_method"
  }];

  // The body of the HTTP request the library sends to Vault.
  // Can only be set if http_method is POST.
  // @inject_tag: `gorm:"default:null"`
  bytes http_request_body = 10 [(custom_options.v1.mask_mapping) = {
    this: "HttpRequestBody"
    that: "attributes.http_request_body"
  }];

  // credential_type is optional. If set, it indicates the type of
  // credential the library returns.
  // @inject_tag: `gorm:"default:null"`
  string credential_type = 11;
}

message SSHCertificateCredentialLibrary {
  // public_id is a surrogate key suitable for use in a public API.
  // @inject_tag: `gorm:"primary_key"`
  string public_id = 1;

  // create_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp create_time = 2;

  // update_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp update_time = 3;

  // name is optional. If set, it must be unique within project_id.
  // @inject_tag: `gorm:"default:null"`
  string name = 4 [(custom_options.v1.mask_mapping) = {
    this: "Name"
    that: "name"
  }];

  // description is optional.
  // @inject_tag: `gorm:"default:null"`
  string description = 5 [(custom_options.v1.mask_mapping) = {
    this: "Description"
    that: "description"
  }];

  // store_id of the owning vault credential store.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string store_id = 6;

  // version allows optimistic locking of the resource.
  // @inject_tag: `gorm:"default:null"`
  uint32 version = 7;

  // vault_path is the path in Vault to request credentials from.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string vault_path = 8 [(custom_options.v1.mask_mapping) = {
    this: "VaultPath"
    that: "attributes.path"
  }];

  // username is the username to use when making an SSH connection.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string username = 9 [(custom_options.v1.mask_mapping) = {
    this: "Username"
    that: "attributes.username"
  }];

  // key_type specifies the key type to use when generating an SSH private key.
  // Values must be "rsa", "ed25519", or "ecdsa".
  // @inject_tag: `gorm:"not_null"`
  string key_type = 10 [(custom_options.v1.mask_mapping) = {
    this: "KeyType"
    that: "attributes.key_type"
  }];

  // key_bits specifies the number of bits to use to generate an SSH private key.
  // Not used if key_type is ed25519.
  // @inject_tag: `gorm:"not_null"`
  uint32 key_bits = 11 [(custom_options.v1.mask_mapping) = {
    this: "KeyBits"
    that: "attributes.key_bits"
  }];

  // ttl specifies the requested time to live for the certificate.
  // @inject_tag: `gorm:"default:null"`
  string ttl = 12 [(custom_options.v1.mask_mapping) = {
    this: "Ttl"
    that: "attributes.ttl"
  }];

  // key_id specifies the key id that the created certificate should have.
  // @inject_tag: `gorm:"default:null"`
  string key_id = 13 [(custom_options.v1.mask_mapping) = {
    this: "KeyId"
    that: "attributes.key_id"
  }];

  // critical_options specifies a map of the critical options that the certificate should be signed for.
  // @inject_tag: `gorm:"default:null"`
  string critical_options = 14 [(custom_options.v1.mask_mapping) = {
    this: "CriticalOptions"
    that: "attributes.critical_options"
  }];

  // extensions specifies a map of the extensions that the certificate should be signed for.
  // @inject_tag: `gorm:"default:null"`
  string extensions = 15 [(custom_options.v1.mask_mapping) = {
    this: "Extensions"
    that: "attributes.extensions"
  }];

  // credential_type is always ssh_certificate
  // @inject_tag: `gorm:"default:null"`
  string credential_type = 16;

  // additional_valid_principals are strings that will be sent to vault in the "valid_principles"
  // api field in addition to the username.
  // @inject_tag: `gorm:"default:null"`
  string additional_valid_principals = 17 [(custom_options.v1.mask_mapping) = {
    this: "AdditionalValidPrincipals"
    that: "attributes.additional_valid_principals"
  }];
}

message Credential {
  // public_id is a surrogate key suitable for use in a public API.
  // @inject_tag: `gorm:"primary_key"`
  string public_id = 1;

  // library_id of the owning vault credential library.
  // It must be set.
  string library_id = 2;

  // session_id of the session the credential was created for.
  // It must be set.
  string session_id = 3;

  // token_hmac is the foreign key of the token used to acquire the secret.
  // @inject_tag: `gorm:"not_null"`
  bytes token_hmac = 4;

  // create_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp create_time = 5;

  // update_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp update_time = 6;

  // version allows optimistic locking of the resource.
  // @inject_tag: `gorm:"default:null"`
  uint32 version = 7;

  // external_id is the lease ID returned from Vault.
  // @inject_tag: `gorm:"not_null"`
  string external_id = 8;

  // last_renewal_time is the time the lease was last renewed with Vault.
  // @inject_tag: `gorm:"default:null"`
  timestamp.v1.Timestamp last_renewal_time = 9;

  // expiration_time is the time the lease is expected to expire.
  // expiration_time is calculated when the credential is initially
  // retrieved and whenever the credential's lease is renewed.
  //
  // The calculation is:
  //   expiration_time := time.Now().Add(LeaseDuration * time.Second)
  // LeaseDuration is a value returned by Vault when the credential is
  // retrieved or the lease for the credential is renewed.
  //
  // https://www.vaultproject.io/docs/concepts/lease
  //
  // @inject_tag: `gorm:"default:null"`
  timestamp.v1.Timestamp expiration_time = 10;

  // is_renewable indicates if the lease can be renewed.
  // @inject_tag: `gorm:"default:false"`
  bool is_renewable = 11;

  // The status of the credential.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string status = 12;
}

message UsernamePasswordOverride {
  // library_id of the owning vault credential library.
  // @inject_tag: `gorm:"primary_key"`
  string library_id = 1;

  // username_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a username.
  // If set, it overrides any default attribute names the system uses to
  // find a username attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string username_attribute = 2;

  // password_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a password.
  // If set, it overrides any default attribute names the system uses to
  // find a password attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string password_attribute = 3;
}

message UsernamePasswordDomainOverride {
  // library_id of the owning vault credential library.
  // @inject_tag: `gorm:"primary_key"`
  string library_id = 1;

  // username_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a username.
  // If set, it overrides any default attribute names the system uses to
  // find a username attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string username_attribute = 2;

  // password_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a password.
  // If set, it overrides any default attribute names the system uses to
  // find a password attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string password_attribute = 3;
  // domain_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a domain.
  // If set, it overrides any default attribute names the system uses to
  // find a domain attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string domain_attribute = 4;
}

message PasswordOverride {
  // library_id of the owning vault credential library.
  // @inject_tag: `gorm:"primary_key"`
  string library_id = 1;

  // password_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a password.
  // If set, it overrides any default attribute names the system uses to
  // find a password attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string password_attribute = 2;
}

message SshPrivateKeyOverride {
  // library_id of the owning vault credential library.
  // @inject_tag: `gorm:"primary_key"`
  string library_id = 1;

  // username_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a username.
  // If set, it overrides any default attribute names the system uses to
  // find a username attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string username_attribute = 2;

  // private_key_attribute is the name of the attribute in the Data field of a
  // Vault api.Secret that maps to a private key.
  // If set, it overrides any default attribute names the system uses to
  // find a private_key attribute.
  //
  // See https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string private_key_attribute = 3;

  // private_key_passphrase_attribute is the name of the attribute in the Data
  // field of a Vault api.Secret that maps to a private key passphrase. If set,
  // it overrides any default attribute names the system uses to find a
  // private_key_passphrase attribute.
  //
  // See
  // https://github.com/hashicorp/vault/blob/5e505ec039177e8212cbbab74ccb644c46e62e63/api/secret.go#L25
  //
  // @inject_tag: `gorm:"default:null"`
  string private_key_passphrase_attribute = 4;
}

message LdapCredentialLibrary {
  // public_id is a surrogate key suitable for use in a public API.
  // @inject_tag: `gorm:"primary_key"`
  string public_id = 1;

  // create_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp create_time = 2;

  // update_time is set by the database.
  // @inject_tag: `gorm:"default:current_timestamp"`
  timestamp.v1.Timestamp update_time = 3;

  // name is optional. If set, it must be unique within project_id.
  // @inject_tag: `gorm:"default:null"`
  string name = 4 [(custom_options.v1.mask_mapping) = {
    this: "Name"
    that: "name"
  }];

  // description is optional.
  // @inject_tag: `gorm:"default:null"`
  string description = 5 [(custom_options.v1.mask_mapping) = {
    this: "Description"
    that: "description"
  }];

  // store_id of the owning vault credential store.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string store_id = 6;

  // version allows optimistic locking of the resource.
  // @inject_tag: `gorm:"default:null"`
  uint32 version = 7;

  // vault_path is the path in Vault to request credentials from.
  // It must be set.
  // @inject_tag: `gorm:"not_null"`
  string vault_path = 8 [(custom_options.v1.mask_mapping) = {
    this: "VaultPath"
    that: "attributes.path"
  }];

  // credential_type is always ssh_certificate
  // @inject_tag: `gorm:"default:null"`
  string credential_type = 9;
}
