syntax = "proto3";

package linkedca;

option go_package = "github.com/smallstep/linkedca";

import "linkedca/admin.proto";
import "linkedca/provisioners.proto";
import "linkedca/acme.proto";
import "google/protobuf/timestamp.proto";

// Majordomo is the public service used to sync configurations to CA's and post
// certificates.
service Majordomo {
	// Login creates signs a given CSR and returns the certificate that will be
	// used for authentication.
	rpc Login(LoginRequest) returns (LoginResponse);
	// GetRootCertificate returns the root certificate for a given fingerprint.
	rpc GetRootCertificate(GetRootCertificateRequest) returns (GetRootCertificateResponse);

	// GetConfiguration returns the full configuration of an authority.
	rpc GetConfiguration(ConfigurationRequest) returns (ConfigurationResponse);

	// CreateProvisioner adds a new provisioner to the majordomo authority and
	// returns the proto representation.
	rpc CreateProvisioner(CreateProvisionerRequest) returns (Provisioner);
	// GetProvisioner returns a provisioner by its id.
	rpc GetProvisioner(GetProvisionerRequest) returns (Provisioner);
	// UpdateProvisioners updates a previously created provisioner.
	rpc UpdateProvisioner(UpdateProvisionerRequest) returns (Provisioner);
	// DeleteProvisioner deletes a previously created provisioner.
	rpc DeleteProvisioner(DeleteProvisionerRequest) returns (Provisioner);

	// CreateAdmin adds a new admin user to the majordomo authority. Admin users
	// can add or delete provisioners.
	rpc CreateAdmin(CreateAdminRequest) returns (Admin);
	// GetAdmin returns an admin by its id.
	rpc GetAdmin(GetAdminRequest) returns (Admin);
	// UpdateAdmin updates a previously created admin.
	rpc UpdateAdmin(UpdateAdminRequest) returns (Admin);
	// DeleteAdmin deletes a previously created admin user
	rpc DeleteAdmin(DeleteAdminRequest) returns (Admin);

	// PostCertificate sends a signed X.509 certificate to majordomo.
	rpc PostCertificate(CertificateRequest) returns (CertificateResponse);
	// PostSSHCertificate sends a signed SSH certificate to majordomo.
	rpc PostSSHCertificate(SSHCertificateRequest) returns (SSHCertificateResponse);
	// PostOneTimeToken sends a one time token to majordomo.
	rpc PostOneTimeToken(OneTimeTokenRequest) returns (OneTimeTokenResponse);
	// RevokeCertificate marks an X.509 certificate as revoked.
	rpc RevokeCertificate(RevokeCertificateRequest) returns (RevokeCertificateResponse);
	// RevokeSSHCertificate marks an SSH certificate as revoked.
	rpc RevokeSSHCertificate(RevokeSSHCertificateRequest) returns (RevokeSSHCertificateResponse);
	// GetCertificate returns the X.509 certificate by serial.
	rpc GetCertificate(GetCertificateRequest) returns (GetCertificateResponse);
	// GetCertificateStatus returns the status of an X.509 certificate by serial.
	rpc GetCertificateStatus(GetCertificateStatusRequest) returns (GetCertificateStatusResponse);
	// GetSSHCertificateStatus returns the status of an SSH certificate by serial.
	rpc GetSSHCertificateStatus(GetSSHCertificateStatusRequest) returns (GetSSHCertificateStatusResponse);

	// GetACMEAccount returns the ACMEAccount by its id or kid.
	rpc GetACMEAccount(GetACMEAccountRequest) returns (ACMEAccount);
	// CreateACMEAccount adds a new ACMEAccount to the majordomo team.
	rpc CreateACMEAccount(CreateACMEAccountRequest) returns (ACMEAccount);
	// UpdateACMEAccount updates a previously existing ACMEAccount.
	rpc UpdateACMEAccount(UpdateACMEAccountRequest) returns (ACMEAccount);
	// DeleteACMEAccount deletes a previously existing ACMEAccount.
	rpc DeleteACMEAccount(DeleteACMEAccountRequest) returns (ACMEAccount);
}

message LoginRequest {
	string authority_id = 1;
	string token = 2;
	string pem_certificate_request = 3;
}

message LoginResponse {
	string pem_certificate = 1;
	string pem_certificate_chain = 2;
}

message GetRootCertificateRequest {
	string fingerprint = 1;
}

message GetRootCertificateResponse {
	string pem_certificate = 1;
}

message ConfigurationRequest {
	string authority_id = 1;
}

message ConfigurationResponse {
	repeated Provisioner provisioners = 1;
	repeated Admin admins = 2;
	RegistrationAuthorityConfig ra_config = 3;
	ServerConfiguration server_config = 4;
}

message ServerConfiguration {
	string address = 1;
	repeated string dns_names = 2;
}

message RegistrationAuthorityConfig {
	string ca_url = 1;
	string fingerprint = 2;
	ProvisionerIdentity provisioner = 3;
}

message RegistrationAuthorityProvisioner {
	string authority_id = 1;
	ProvisionerIdentity provisioner = 2;
}

message CreateProvisionerRequest {
	Provisioner.Type type = 1;
	string name = 2;
	ProvisionerDetails details = 3;
	Claims claims = 4;
	Template x509_template = 5;
	Template ssh_template = 6;
	string preferred_id = 7;
}

message GetProvisionerRequest {
	string id = 1;
}

message UpdateProvisionerRequest {
	string id = 1;
	string name = 2;
	ProvisionerDetails details = 3;
	Claims claims = 4;
	Template x509_template = 5;
	Template ssh_template = 6;
}

message DeleteProvisionerRequest {
	string id = 1;
}

message CreateAdminRequest {
	string subject = 1;
	string provisioner_id = 2;
	Admin.Type type = 3;
	string preferred_id = 4;
}

message GetAdminRequest {
	string id = 1;
}

message UpdateAdminRequest {
	string id = 1;
	Admin.Type type = 2;
}

message DeleteAdminRequest {
	string id = 1;
}

message CertificateRequest {
	string pem_certificate = 1;
	string pem_certificate_chain = 2;
	string pem_parent_certificate = 3;
	ProvisionerIdentity provisioner = 4;
	RegistrationAuthorityProvisioner ra_provisioner = 5;
	string endpoint_id = 6;
	AttestationData attestation_data = 7;
}

// AttestationData holds the information available at certificate sign time.
// Currently only the permanent identifier (UDID or SerialNumber, not both) is
// available.
message AttestationData {
	string permanent_identifier = 1;
}

message CertificateResponse {
	string id = 1;
}

message SSHCertificateRequest {
	string certificate = 1;
	string parent_certificate = 2;
	ProvisionerIdentity provisioner = 3;
}

message SSHCertificateResponse {
	string id = 1;
}

message OneTimeTokenRequest {
	string jti = 1;
	string token = 2;
}

message OneTimeTokenResponse {
	string id = 1;
}

enum RevocationStatus {
	UNKNOWN = 0;
	ACTIVE = 1;
	REVOKED = 2;
	HOLD = 3;
}

enum RevocationReasonCode {
	UNSPECIFIED = 0;
	KEY_COMPROMISE = 1;
	CA_COMPROMISE = 2;
	AFFILIATION_CHANGED = 3;
	SUPERSEDED = 4;
	CESSATION_OF_OPERATION = 5;
	CERTIFICATE_HOLD = 6;
	REMOVE_FROM_CRL = 8;
	PRIVILEGE_WITHDRAWN = 9;
	AA_COMPROMISE = 10;
}

message RevokeCertificateRequest {
	string serial = 1;
	string pem_certificate = 2;
	string reason = 3;
	RevocationReasonCode reason_code = 4;
	bool passive = 5;
	google.protobuf.Timestamp revoked_at = 6;
}

message RevokeCertificateResponse {
	RevocationStatus status = 1;
}

message RevokeSSHCertificateRequest {
	string serial = 1;
	string certificate = 2;
	string reason = 3;
	RevocationReasonCode reason_code = 4;
	bool passive = 5;
	google.protobuf.Timestamp revoked_at = 6;
}

message RevokeSSHCertificateResponse {
	RevocationStatus status = 1;
}

message GetCertificateRequest {
	string serial = 1;
}

message GetCertificateResponse {
	string pem_certificate = 1;
	ProvisionerIdentity provisioner = 2;
	RegistrationAuthorityProvisioner ra_provisioner = 3;
}

message GetCertificateStatusRequest {
	string serial = 1;
}

message GetCertificateStatusResponse {
	RevocationStatus status = 1;
	string reason = 2;
	RevocationReasonCode reason_code = 3;
	google.protobuf.Timestamp revoked_at = 4;
}

message GetSSHCertificateStatusRequest {
	string serial = 1;
}

message GetSSHCertificateStatusResponse {
	RevocationStatus status = 1;
	string reason = 2;
	RevocationReasonCode reason_code = 3;
	google.protobuf.Timestamp revoked_at = 4;
}

message GetACMEAccountRequest {
	oneof identifier {
		string id = 1;
		string kid = 2;
	}
}

message CreateACMEAccountRequest {
	string preferred_id = 1;
	bytes jwk = 2;
    ACMEAccount.Status status = 3;
    repeated string contact = 4;
    bool terms_of_service_agreed = 5;
}

message UpdateACMEAccountRequest {
	string id = 1;
	bytes jwk = 2;
    ACMEAccount.Status status = 3;
    repeated string contact = 4;
    bool terms_of_service_agreed = 5;
}

message DeleteACMEAccountRequest {
	string id = 1;
}
