syntax = "proto3";

package metacrypt.v2;

option go_package = "git.wntrmute.dev/mc/metacrypt/gen/metacrypt/v2;metacryptv2";

// TransitService provides typed, authenticated access to transit engine
// operations: symmetric encryption, signing, HMAC, and versioned key
// management. All RPCs require the service to be unsealed.
service TransitService {
  // CreateKey creates a new named encryption key. Admin only.
  rpc CreateKey(CreateTransitKeyRequest) returns (CreateTransitKeyResponse);

  // DeleteKey permanently removes a named key. Admin only.
  // Only succeeds if allow_deletion is true on the key config.
  rpc DeleteKey(DeleteTransitKeyRequest) returns (DeleteTransitKeyResponse);

  // GetKey returns metadata for a named key (no raw material). Auth required.
  rpc GetKey(GetTransitKeyRequest) returns (GetTransitKeyResponse);

  // ListKeys returns the names of all configured keys. Auth required.
  rpc ListKeys(ListTransitKeysRequest) returns (ListTransitKeysResponse);

  // RotateKey creates a new version of the named key. Admin only.
  rpc RotateKey(RotateTransitKeyRequest) returns (RotateTransitKeyResponse);

  // UpdateKeyConfig updates key configuration (e.g. min_decryption_version).
  // Admin only.
  rpc UpdateKeyConfig(UpdateTransitKeyConfigRequest) returns (UpdateTransitKeyConfigResponse);

  // TrimKey deletes versions below min_decryption_version. Admin only.
  rpc TrimKey(TrimTransitKeyRequest) returns (TrimTransitKeyResponse);

  // Encrypt encrypts plaintext with the latest key version. Auth required.
  rpc Encrypt(TransitEncryptRequest) returns (TransitEncryptResponse);

  // Decrypt decrypts ciphertext. Auth required.
  rpc Decrypt(TransitDecryptRequest) returns (TransitDecryptResponse);

  // Rewrap re-encrypts ciphertext with the latest key version without
  // exposing plaintext. Auth required.
  rpc Rewrap(TransitRewrapRequest) returns (TransitRewrapResponse);

  // BatchEncrypt encrypts multiple items in a single request. Auth required.
  rpc BatchEncrypt(TransitBatchEncryptRequest) returns (TransitBatchResponse);

  // BatchDecrypt decrypts multiple items in a single request. Auth required.
  rpc BatchDecrypt(TransitBatchDecryptRequest) returns (TransitBatchResponse);

  // BatchRewrap re-encrypts multiple items in a single request. Auth required.
  rpc BatchRewrap(TransitBatchRewrapRequest) returns (TransitBatchResponse);

  // Sign signs input data with an asymmetric key. Auth required.
  rpc Sign(TransitSignRequest) returns (TransitSignResponse);

  // Verify verifies a signature against input data. Auth required.
  rpc Verify(TransitVerifyRequest) returns (TransitVerifyResponse);

  // Hmac computes or verifies an HMAC. Auth required.
  rpc Hmac(TransitHmacRequest) returns (TransitHmacResponse);

  // GetPublicKey returns the public key for an asymmetric key. Auth required.
  rpc GetPublicKey(GetTransitPublicKeyRequest) returns (GetTransitPublicKeyResponse);
}

// --- CreateKey ---

message CreateTransitKeyRequest {
  string mount = 1;
  string name = 2;
  // type is the key algorithm: aes256-gcm, chacha20-poly, ed25519,
  // ecdsa-p256, ecdsa-p384, hmac-sha256, hmac-sha512.
  // Defaults to aes256-gcm if empty.
  string type = 3;
}

message CreateTransitKeyResponse {
  string name = 1;
  string type = 2;
  int32 version = 3;
}

// --- DeleteKey ---

message DeleteTransitKeyRequest {
  string mount = 1;
  string name = 2;
}

message DeleteTransitKeyResponse {}

// --- GetKey ---

message GetTransitKeyRequest {
  string mount = 1;
  string name = 2;
}

message GetTransitKeyResponse {
  string name = 1;
  string type = 2;
  int32 current_version = 3;
  int32 min_decryption_version = 4;
  bool allow_deletion = 5;
  repeated int32 versions = 6;
}

// --- ListKeys ---

message ListTransitKeysRequest {
  string mount = 1;
}

message ListTransitKeysResponse {
  repeated string keys = 1;
}

// --- RotateKey ---

message RotateTransitKeyRequest {
  string mount = 1;
  string name = 2;
}

message RotateTransitKeyResponse {
  string name = 1;
  int32 version = 2;
}

// --- UpdateKeyConfig ---

message UpdateTransitKeyConfigRequest {
  string mount = 1;
  string name = 2;
  int32 min_decryption_version = 3;
  bool allow_deletion = 4;
}

message UpdateTransitKeyConfigResponse {}

// --- TrimKey ---

message TrimTransitKeyRequest {
  string mount = 1;
  string name = 2;
}

message TrimTransitKeyResponse {
  int32 trimmed = 1;
}

// --- Encrypt ---

message TransitEncryptRequest {
  string mount = 1;
  string key = 2;
  // plaintext is base64-encoded data to encrypt.
  string plaintext = 3;
  // context is optional base64-encoded additional authenticated data (AAD).
  string context = 4;
}

message TransitEncryptResponse {
  // ciphertext in format "metacrypt:v{version}:{base64(nonce+ciphertext+tag)}"
  string ciphertext = 1;
}

// --- Decrypt ---

message TransitDecryptRequest {
  string mount = 1;
  string key = 2;
  string ciphertext = 3;
  string context = 4;
}

message TransitDecryptResponse {
  // plaintext is base64-encoded decrypted data.
  string plaintext = 1;
}

// --- Rewrap ---

message TransitRewrapRequest {
  string mount = 1;
  string key = 2;
  string ciphertext = 3;
  string context = 4;
}

message TransitRewrapResponse {
  string ciphertext = 1;
}

// --- Batch ---

message TransitBatchItem {
  string plaintext = 1;
  string ciphertext = 2;
  string context = 3;
  string reference = 4;
}

message TransitBatchResultItem {
  string plaintext = 1;
  string ciphertext = 2;
  string reference = 3;
  string error = 4;
}

message TransitBatchEncryptRequest {
  string mount = 1;
  string key = 2;
  repeated TransitBatchItem items = 3;
}

message TransitBatchDecryptRequest {
  string mount = 1;
  string key = 2;
  repeated TransitBatchItem items = 3;
}

message TransitBatchRewrapRequest {
  string mount = 1;
  string key = 2;
  repeated TransitBatchItem items = 3;
}

message TransitBatchResponse {
  repeated TransitBatchResultItem results = 1;
}

// --- Sign ---

message TransitSignRequest {
  string mount = 1;
  string key = 2;
  // input is base64-encoded data to sign.
  string input = 3;
}

message TransitSignResponse {
  // signature in format "metacrypt:v{version}:{base64(signature_bytes)}"
  string signature = 1;
}

// --- Verify ---

message TransitVerifyRequest {
  string mount = 1;
  string key = 2;
  string input = 3;
  string signature = 4;
}

message TransitVerifyResponse {
  bool valid = 1;
}

// --- HMAC ---

message TransitHmacRequest {
  string mount = 1;
  string key = 2;
  // input is base64-encoded data to HMAC.
  string input = 3;
  // hmac, if set, switches to verify mode.
  string hmac = 4;
}

message TransitHmacResponse {
  // hmac is set in compute mode.
  string hmac = 1;
  // valid is set in verify mode.
  bool valid = 2;
}

// --- GetPublicKey ---

message GetTransitPublicKeyRequest {
  string mount = 1;
  string name = 2;
  int32 version = 3;
}

message GetTransitPublicKeyResponse {
  // public_key is base64-encoded PKIX DER public key.
  string public_key = 1;
  int32 version = 2;
  string type = 3;
}
