mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
GitHub Proxy part 3: gen github user cert and export CA (#49396)
* GitHub Proxy part 3: gen github user cert and export CA * address pr comment * minor refactor * use cache * fix build and cache
This commit is contained in:
@@ -5196,3 +5196,8 @@ func (c *Client) IdentityCenterClient() identitycenterv1.IdentityCenterServiceCl
|
||||
func (c *Client) ProvisioningServiceClient() provisioningv1.ProvisioningServiceClient {
|
||||
return provisioningv1.NewProvisioningServiceClient(c.conn)
|
||||
}
|
||||
|
||||
// IntegrationsClient returns integrations client.
|
||||
func (c *Client) IntegrationsClient() integrationpb.IntegrationServiceClient {
|
||||
return c.integrationsClient()
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
types "github.com/gravitational/teleport/api/types"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
durationpb "google.golang.org/protobuf/types/known/durationpb"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
@@ -494,6 +495,233 @@ func (x *GenerateAWSOIDCTokenResponse) GetToken() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GenerateGitHubUserCertRequest is a request to sign a client certificate used by
|
||||
// GitHub integration to authenticate with GitHub enterprise.
|
||||
type GenerateGitHubUserCertRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Integration is the name of the integration;
|
||||
Integration string `protobuf:"bytes,1,opt,name=integration,proto3" json:"integration,omitempty"`
|
||||
// PublicKey is the public key to be signed.
|
||||
PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
// UserId is the GitHub user id.
|
||||
UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
// KeyId is the certificate ID, usually the Teleport username.
|
||||
KeyId string `protobuf:"bytes,4,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
|
||||
// Ttl is the duration the certificate will be valid for.
|
||||
Ttl *durationpb.Duration `protobuf:"bytes,5,opt,name=ttl,proto3" json:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) Reset() {
|
||||
*x = GenerateGitHubUserCertRequest{}
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GenerateGitHubUserCertRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[9]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GenerateGitHubUserCertRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GenerateGitHubUserCertRequest) Descriptor() ([]byte, []int) {
|
||||
return file_teleport_integration_v1_integration_service_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) GetIntegration() string {
|
||||
if x != nil {
|
||||
return x.Integration
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) GetKeyId() string {
|
||||
if x != nil {
|
||||
return x.KeyId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertRequest) GetTtl() *durationpb.Duration {
|
||||
if x != nil {
|
||||
return x.Ttl
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateGitHubUserCertResponse contains a signed certificate.
|
||||
type GenerateGitHubUserCertResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// AuthorizedKey is the signed certificate.
|
||||
AuthorizedKey []byte `protobuf:"bytes,1,opt,name=authorized_key,json=authorizedKey,proto3" json:"authorized_key,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertResponse) Reset() {
|
||||
*x = GenerateGitHubUserCertResponse{}
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GenerateGitHubUserCertResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GenerateGitHubUserCertResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[10]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GenerateGitHubUserCertResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GenerateGitHubUserCertResponse) Descriptor() ([]byte, []int) {
|
||||
return file_teleport_integration_v1_integration_service_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *GenerateGitHubUserCertResponse) GetAuthorizedKey() []byte {
|
||||
if x != nil {
|
||||
return x.AuthorizedKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExportIntegrationCertAuthoritiesRequest is the request to export cert
|
||||
// authorities for an integration.
|
||||
type ExportIntegrationCertAuthoritiesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Integration is the name of the integration;
|
||||
Integration string `protobuf:"bytes,1,opt,name=integration,proto3" json:"integration,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesRequest) Reset() {
|
||||
*x = ExportIntegrationCertAuthoritiesRequest{}
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExportIntegrationCertAuthoritiesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[11]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExportIntegrationCertAuthoritiesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ExportIntegrationCertAuthoritiesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_teleport_integration_v1_integration_service_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesRequest) GetIntegration() string {
|
||||
if x != nil {
|
||||
return x.Integration
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ExportIntegrationCertAuthoritiesResponse is the response to
|
||||
// ExportIntegrationCertAuthorities.
|
||||
type ExportIntegrationCertAuthoritiesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// CertAuthorities are the CA key sets used to sign any new certificates.
|
||||
CertAuthorities *types.CAKeySet `protobuf:"bytes,1,opt,name=cert_authorities,json=certAuthorities,proto3" json:"cert_authorities,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesResponse) Reset() {
|
||||
*x = ExportIntegrationCertAuthoritiesResponse{}
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExportIntegrationCertAuthoritiesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_teleport_integration_v1_integration_service_proto_msgTypes[12]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExportIntegrationCertAuthoritiesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ExportIntegrationCertAuthoritiesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_teleport_integration_v1_integration_service_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *ExportIntegrationCertAuthoritiesResponse) GetCertAuthorities() *types.CAKeySet {
|
||||
if x != nil {
|
||||
return x.CertAuthorities
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_teleport_integration_v1_integration_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_teleport_integration_v1_integration_service_proto_rawDesc = []byte{
|
||||
@@ -501,7 +729,9 @@ var file_teleport_integration_v1_integration_service_proto_rawDesc = []byte{
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x12, 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x67, 0x6f,
|
||||
0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
|
||||
@@ -547,60 +777,107 @@ var file_teleport_integration_v1_integration_service_proto_rawDesc = []byte{
|
||||
0x1c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x32, 0xef, 0x05, 0x0a, 0x12, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x77, 0x0a, 0x10, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30,
|
||||
0x6b, 0x65, 0x6e, 0x22, 0xbd, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
|
||||
0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12,
|
||||
0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03,
|
||||
0x74, 0x74, 0x6c, 0x22, 0x47, 0x0a, 0x1e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47,
|
||||
0x69, 0x74, 0x48, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61,
|
||||
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0x4b, 0x0a, 0x27,
|
||||
0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x67,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x66, 0x0a, 0x28, 0x45, 0x78, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x65,
|
||||
0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x61, 0x75,
|
||||
0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x41, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74,
|
||||
0x52, 0x0f, 0x63, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65,
|
||||
0x73, 0x32, 0xa5, 0x08, 0x0a, 0x12, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x77, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x2e, 0x74,
|
||||
0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31,
|
||||
0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x74,
|
||||
0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e,
|
||||
0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x5c, 0x0a, 0x11, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x56, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65,
|
||||
0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x5c, 0x0a, 0x11, 0x55, 0x70, 0x64,
|
||||
0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x5c, 0x0a, 0x11, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31,
|
||||
0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x5c, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x2e, 0x74,
|
||||
0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74,
|
||||
0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x66, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x12, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12,
|
||||
0x83, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x57, 0x53, 0x4f,
|
||||
0x49, 0x44, 0x43, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x57, 0x53, 0x4f, 0x49,
|
||||
0x44, 0x43, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35,
|
||||
0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c,
|
||||
0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x66, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41,
|
||||
0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35,
|
||||
0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41,
|
||||
0x6c, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x83, 0x01,
|
||||
0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44,
|
||||
0x43, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x74,
|
||||
0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41,
|
||||
0x57, 0x53, 0x4f, 0x49, 0x44, 0x43, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
|
||||
0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x12, 0x36,
|
||||
0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
|
||||
0x65, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61,
|
||||
0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
|
||||
0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76,
|
||||
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x55,
|
||||
0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0xa7, 0x01, 0x0a, 0x20, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
|
||||
0x74, 0x69, 0x65, 0x73, 0x12, 0x40, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45,
|
||||
0x78, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f,
|
||||
0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -615,43 +892,55 @@ func file_teleport_integration_v1_integration_service_proto_rawDescGZIP() []byte
|
||||
return file_teleport_integration_v1_integration_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_teleport_integration_v1_integration_service_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_teleport_integration_v1_integration_service_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
|
||||
var file_teleport_integration_v1_integration_service_proto_goTypes = []any{
|
||||
(*ListIntegrationsRequest)(nil), // 0: teleport.integration.v1.ListIntegrationsRequest
|
||||
(*ListIntegrationsResponse)(nil), // 1: teleport.integration.v1.ListIntegrationsResponse
|
||||
(*GetIntegrationRequest)(nil), // 2: teleport.integration.v1.GetIntegrationRequest
|
||||
(*CreateIntegrationRequest)(nil), // 3: teleport.integration.v1.CreateIntegrationRequest
|
||||
(*UpdateIntegrationRequest)(nil), // 4: teleport.integration.v1.UpdateIntegrationRequest
|
||||
(*DeleteIntegrationRequest)(nil), // 5: teleport.integration.v1.DeleteIntegrationRequest
|
||||
(*DeleteAllIntegrationsRequest)(nil), // 6: teleport.integration.v1.DeleteAllIntegrationsRequest
|
||||
(*GenerateAWSOIDCTokenRequest)(nil), // 7: teleport.integration.v1.GenerateAWSOIDCTokenRequest
|
||||
(*GenerateAWSOIDCTokenResponse)(nil), // 8: teleport.integration.v1.GenerateAWSOIDCTokenResponse
|
||||
(*types.IntegrationV1)(nil), // 9: types.IntegrationV1
|
||||
(*emptypb.Empty)(nil), // 10: google.protobuf.Empty
|
||||
(*ListIntegrationsRequest)(nil), // 0: teleport.integration.v1.ListIntegrationsRequest
|
||||
(*ListIntegrationsResponse)(nil), // 1: teleport.integration.v1.ListIntegrationsResponse
|
||||
(*GetIntegrationRequest)(nil), // 2: teleport.integration.v1.GetIntegrationRequest
|
||||
(*CreateIntegrationRequest)(nil), // 3: teleport.integration.v1.CreateIntegrationRequest
|
||||
(*UpdateIntegrationRequest)(nil), // 4: teleport.integration.v1.UpdateIntegrationRequest
|
||||
(*DeleteIntegrationRequest)(nil), // 5: teleport.integration.v1.DeleteIntegrationRequest
|
||||
(*DeleteAllIntegrationsRequest)(nil), // 6: teleport.integration.v1.DeleteAllIntegrationsRequest
|
||||
(*GenerateAWSOIDCTokenRequest)(nil), // 7: teleport.integration.v1.GenerateAWSOIDCTokenRequest
|
||||
(*GenerateAWSOIDCTokenResponse)(nil), // 8: teleport.integration.v1.GenerateAWSOIDCTokenResponse
|
||||
(*GenerateGitHubUserCertRequest)(nil), // 9: teleport.integration.v1.GenerateGitHubUserCertRequest
|
||||
(*GenerateGitHubUserCertResponse)(nil), // 10: teleport.integration.v1.GenerateGitHubUserCertResponse
|
||||
(*ExportIntegrationCertAuthoritiesRequest)(nil), // 11: teleport.integration.v1.ExportIntegrationCertAuthoritiesRequest
|
||||
(*ExportIntegrationCertAuthoritiesResponse)(nil), // 12: teleport.integration.v1.ExportIntegrationCertAuthoritiesResponse
|
||||
(*types.IntegrationV1)(nil), // 13: types.IntegrationV1
|
||||
(*durationpb.Duration)(nil), // 14: google.protobuf.Duration
|
||||
(*types.CAKeySet)(nil), // 15: types.CAKeySet
|
||||
(*emptypb.Empty)(nil), // 16: google.protobuf.Empty
|
||||
}
|
||||
var file_teleport_integration_v1_integration_service_proto_depIdxs = []int32{
|
||||
9, // 0: teleport.integration.v1.ListIntegrationsResponse.integrations:type_name -> types.IntegrationV1
|
||||
9, // 1: teleport.integration.v1.CreateIntegrationRequest.integration:type_name -> types.IntegrationV1
|
||||
9, // 2: teleport.integration.v1.UpdateIntegrationRequest.integration:type_name -> types.IntegrationV1
|
||||
0, // 3: teleport.integration.v1.IntegrationService.ListIntegrations:input_type -> teleport.integration.v1.ListIntegrationsRequest
|
||||
2, // 4: teleport.integration.v1.IntegrationService.GetIntegration:input_type -> teleport.integration.v1.GetIntegrationRequest
|
||||
3, // 5: teleport.integration.v1.IntegrationService.CreateIntegration:input_type -> teleport.integration.v1.CreateIntegrationRequest
|
||||
4, // 6: teleport.integration.v1.IntegrationService.UpdateIntegration:input_type -> teleport.integration.v1.UpdateIntegrationRequest
|
||||
5, // 7: teleport.integration.v1.IntegrationService.DeleteIntegration:input_type -> teleport.integration.v1.DeleteIntegrationRequest
|
||||
6, // 8: teleport.integration.v1.IntegrationService.DeleteAllIntegrations:input_type -> teleport.integration.v1.DeleteAllIntegrationsRequest
|
||||
7, // 9: teleport.integration.v1.IntegrationService.GenerateAWSOIDCToken:input_type -> teleport.integration.v1.GenerateAWSOIDCTokenRequest
|
||||
1, // 10: teleport.integration.v1.IntegrationService.ListIntegrations:output_type -> teleport.integration.v1.ListIntegrationsResponse
|
||||
9, // 11: teleport.integration.v1.IntegrationService.GetIntegration:output_type -> types.IntegrationV1
|
||||
9, // 12: teleport.integration.v1.IntegrationService.CreateIntegration:output_type -> types.IntegrationV1
|
||||
9, // 13: teleport.integration.v1.IntegrationService.UpdateIntegration:output_type -> types.IntegrationV1
|
||||
10, // 14: teleport.integration.v1.IntegrationService.DeleteIntegration:output_type -> google.protobuf.Empty
|
||||
10, // 15: teleport.integration.v1.IntegrationService.DeleteAllIntegrations:output_type -> google.protobuf.Empty
|
||||
8, // 16: teleport.integration.v1.IntegrationService.GenerateAWSOIDCToken:output_type -> teleport.integration.v1.GenerateAWSOIDCTokenResponse
|
||||
10, // [10:17] is the sub-list for method output_type
|
||||
3, // [3:10] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
13, // 0: teleport.integration.v1.ListIntegrationsResponse.integrations:type_name -> types.IntegrationV1
|
||||
13, // 1: teleport.integration.v1.CreateIntegrationRequest.integration:type_name -> types.IntegrationV1
|
||||
13, // 2: teleport.integration.v1.UpdateIntegrationRequest.integration:type_name -> types.IntegrationV1
|
||||
14, // 3: teleport.integration.v1.GenerateGitHubUserCertRequest.ttl:type_name -> google.protobuf.Duration
|
||||
15, // 4: teleport.integration.v1.ExportIntegrationCertAuthoritiesResponse.cert_authorities:type_name -> types.CAKeySet
|
||||
0, // 5: teleport.integration.v1.IntegrationService.ListIntegrations:input_type -> teleport.integration.v1.ListIntegrationsRequest
|
||||
2, // 6: teleport.integration.v1.IntegrationService.GetIntegration:input_type -> teleport.integration.v1.GetIntegrationRequest
|
||||
3, // 7: teleport.integration.v1.IntegrationService.CreateIntegration:input_type -> teleport.integration.v1.CreateIntegrationRequest
|
||||
4, // 8: teleport.integration.v1.IntegrationService.UpdateIntegration:input_type -> teleport.integration.v1.UpdateIntegrationRequest
|
||||
5, // 9: teleport.integration.v1.IntegrationService.DeleteIntegration:input_type -> teleport.integration.v1.DeleteIntegrationRequest
|
||||
6, // 10: teleport.integration.v1.IntegrationService.DeleteAllIntegrations:input_type -> teleport.integration.v1.DeleteAllIntegrationsRequest
|
||||
7, // 11: teleport.integration.v1.IntegrationService.GenerateAWSOIDCToken:input_type -> teleport.integration.v1.GenerateAWSOIDCTokenRequest
|
||||
9, // 12: teleport.integration.v1.IntegrationService.GenerateGitHubUserCert:input_type -> teleport.integration.v1.GenerateGitHubUserCertRequest
|
||||
11, // 13: teleport.integration.v1.IntegrationService.ExportIntegrationCertAuthorities:input_type -> teleport.integration.v1.ExportIntegrationCertAuthoritiesRequest
|
||||
1, // 14: teleport.integration.v1.IntegrationService.ListIntegrations:output_type -> teleport.integration.v1.ListIntegrationsResponse
|
||||
13, // 15: teleport.integration.v1.IntegrationService.GetIntegration:output_type -> types.IntegrationV1
|
||||
13, // 16: teleport.integration.v1.IntegrationService.CreateIntegration:output_type -> types.IntegrationV1
|
||||
13, // 17: teleport.integration.v1.IntegrationService.UpdateIntegration:output_type -> types.IntegrationV1
|
||||
16, // 18: teleport.integration.v1.IntegrationService.DeleteIntegration:output_type -> google.protobuf.Empty
|
||||
16, // 19: teleport.integration.v1.IntegrationService.DeleteAllIntegrations:output_type -> google.protobuf.Empty
|
||||
8, // 20: teleport.integration.v1.IntegrationService.GenerateAWSOIDCToken:output_type -> teleport.integration.v1.GenerateAWSOIDCTokenResponse
|
||||
10, // 21: teleport.integration.v1.IntegrationService.GenerateGitHubUserCert:output_type -> teleport.integration.v1.GenerateGitHubUserCertResponse
|
||||
12, // 22: teleport.integration.v1.IntegrationService.ExportIntegrationCertAuthorities:output_type -> teleport.integration.v1.ExportIntegrationCertAuthoritiesResponse
|
||||
14, // [14:23] is the sub-list for method output_type
|
||||
5, // [5:14] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_teleport_integration_v1_integration_service_proto_init() }
|
||||
@@ -665,7 +954,7 @@ func file_teleport_integration_v1_integration_service_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_teleport_integration_v1_integration_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 9,
|
||||
NumMessages: 13,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -35,13 +35,15 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
IntegrationService_ListIntegrations_FullMethodName = "/teleport.integration.v1.IntegrationService/ListIntegrations"
|
||||
IntegrationService_GetIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/GetIntegration"
|
||||
IntegrationService_CreateIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/CreateIntegration"
|
||||
IntegrationService_UpdateIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/UpdateIntegration"
|
||||
IntegrationService_DeleteIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/DeleteIntegration"
|
||||
IntegrationService_DeleteAllIntegrations_FullMethodName = "/teleport.integration.v1.IntegrationService/DeleteAllIntegrations"
|
||||
IntegrationService_GenerateAWSOIDCToken_FullMethodName = "/teleport.integration.v1.IntegrationService/GenerateAWSOIDCToken"
|
||||
IntegrationService_ListIntegrations_FullMethodName = "/teleport.integration.v1.IntegrationService/ListIntegrations"
|
||||
IntegrationService_GetIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/GetIntegration"
|
||||
IntegrationService_CreateIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/CreateIntegration"
|
||||
IntegrationService_UpdateIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/UpdateIntegration"
|
||||
IntegrationService_DeleteIntegration_FullMethodName = "/teleport.integration.v1.IntegrationService/DeleteIntegration"
|
||||
IntegrationService_DeleteAllIntegrations_FullMethodName = "/teleport.integration.v1.IntegrationService/DeleteAllIntegrations"
|
||||
IntegrationService_GenerateAWSOIDCToken_FullMethodName = "/teleport.integration.v1.IntegrationService/GenerateAWSOIDCToken"
|
||||
IntegrationService_GenerateGitHubUserCert_FullMethodName = "/teleport.integration.v1.IntegrationService/GenerateGitHubUserCert"
|
||||
IntegrationService_ExportIntegrationCertAuthorities_FullMethodName = "/teleport.integration.v1.IntegrationService/ExportIntegrationCertAuthorities"
|
||||
)
|
||||
|
||||
// IntegrationServiceClient is the client API for IntegrationService service.
|
||||
@@ -65,6 +67,10 @@ type IntegrationServiceClient interface {
|
||||
DeleteAllIntegrations(ctx context.Context, in *DeleteAllIntegrationsRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
// GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action.
|
||||
GenerateAWSOIDCToken(ctx context.Context, in *GenerateAWSOIDCTokenRequest, opts ...grpc.CallOption) (*GenerateAWSOIDCTokenResponse, error)
|
||||
// GenerateGitHubUserCert signs a SSH certificate for GitHub integration.
|
||||
GenerateGitHubUserCert(ctx context.Context, in *GenerateGitHubUserCertRequest, opts ...grpc.CallOption) (*GenerateGitHubUserCertResponse, error)
|
||||
// ExportIntegrationCertAuthorities exports cert authorities for an integration.
|
||||
ExportIntegrationCertAuthorities(ctx context.Context, in *ExportIntegrationCertAuthoritiesRequest, opts ...grpc.CallOption) (*ExportIntegrationCertAuthoritiesResponse, error)
|
||||
}
|
||||
|
||||
type integrationServiceClient struct {
|
||||
@@ -145,6 +151,26 @@ func (c *integrationServiceClient) GenerateAWSOIDCToken(ctx context.Context, in
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *integrationServiceClient) GenerateGitHubUserCert(ctx context.Context, in *GenerateGitHubUserCertRequest, opts ...grpc.CallOption) (*GenerateGitHubUserCertResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GenerateGitHubUserCertResponse)
|
||||
err := c.cc.Invoke(ctx, IntegrationService_GenerateGitHubUserCert_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *integrationServiceClient) ExportIntegrationCertAuthorities(ctx context.Context, in *ExportIntegrationCertAuthoritiesRequest, opts ...grpc.CallOption) (*ExportIntegrationCertAuthoritiesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ExportIntegrationCertAuthoritiesResponse)
|
||||
err := c.cc.Invoke(ctx, IntegrationService_ExportIntegrationCertAuthorities_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// IntegrationServiceServer is the server API for IntegrationService service.
|
||||
// All implementations must embed UnimplementedIntegrationServiceServer
|
||||
// for forward compatibility.
|
||||
@@ -166,6 +192,10 @@ type IntegrationServiceServer interface {
|
||||
DeleteAllIntegrations(context.Context, *DeleteAllIntegrationsRequest) (*emptypb.Empty, error)
|
||||
// GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action.
|
||||
GenerateAWSOIDCToken(context.Context, *GenerateAWSOIDCTokenRequest) (*GenerateAWSOIDCTokenResponse, error)
|
||||
// GenerateGitHubUserCert signs a SSH certificate for GitHub integration.
|
||||
GenerateGitHubUserCert(context.Context, *GenerateGitHubUserCertRequest) (*GenerateGitHubUserCertResponse, error)
|
||||
// ExportIntegrationCertAuthorities exports cert authorities for an integration.
|
||||
ExportIntegrationCertAuthorities(context.Context, *ExportIntegrationCertAuthoritiesRequest) (*ExportIntegrationCertAuthoritiesResponse, error)
|
||||
mustEmbedUnimplementedIntegrationServiceServer()
|
||||
}
|
||||
|
||||
@@ -197,6 +227,12 @@ func (UnimplementedIntegrationServiceServer) DeleteAllIntegrations(context.Conte
|
||||
func (UnimplementedIntegrationServiceServer) GenerateAWSOIDCToken(context.Context, *GenerateAWSOIDCTokenRequest) (*GenerateAWSOIDCTokenResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateAWSOIDCToken not implemented")
|
||||
}
|
||||
func (UnimplementedIntegrationServiceServer) GenerateGitHubUserCert(context.Context, *GenerateGitHubUserCertRequest) (*GenerateGitHubUserCertResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateGitHubUserCert not implemented")
|
||||
}
|
||||
func (UnimplementedIntegrationServiceServer) ExportIntegrationCertAuthorities(context.Context, *ExportIntegrationCertAuthoritiesRequest) (*ExportIntegrationCertAuthoritiesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ExportIntegrationCertAuthorities not implemented")
|
||||
}
|
||||
func (UnimplementedIntegrationServiceServer) mustEmbedUnimplementedIntegrationServiceServer() {}
|
||||
func (UnimplementedIntegrationServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
@@ -344,6 +380,42 @@ func _IntegrationService_GenerateAWSOIDCToken_Handler(srv interface{}, ctx conte
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _IntegrationService_GenerateGitHubUserCert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GenerateGitHubUserCertRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(IntegrationServiceServer).GenerateGitHubUserCert(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: IntegrationService_GenerateGitHubUserCert_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(IntegrationServiceServer).GenerateGitHubUserCert(ctx, req.(*GenerateGitHubUserCertRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _IntegrationService_ExportIntegrationCertAuthorities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ExportIntegrationCertAuthoritiesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(IntegrationServiceServer).ExportIntegrationCertAuthorities(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: IntegrationService_ExportIntegrationCertAuthorities_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(IntegrationServiceServer).ExportIntegrationCertAuthorities(ctx, req.(*ExportIntegrationCertAuthoritiesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// IntegrationService_ServiceDesc is the grpc.ServiceDesc for IntegrationService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -379,6 +451,14 @@ var IntegrationService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GenerateAWSOIDCToken",
|
||||
Handler: _IntegrationService_GenerateAWSOIDCToken_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GenerateGitHubUserCert",
|
||||
Handler: _IntegrationService_GenerateGitHubUserCert_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ExportIntegrationCertAuthorities",
|
||||
Handler: _IntegrationService_ExportIntegrationCertAuthorities_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "teleport/integration/v1/integration_service.proto",
|
||||
|
||||
@@ -16,6 +16,7 @@ syntax = "proto3";
|
||||
|
||||
package teleport.integration.v1;
|
||||
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "teleport/legacy/types/types.proto";
|
||||
|
||||
@@ -44,6 +45,12 @@ service IntegrationService {
|
||||
|
||||
// GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action.
|
||||
rpc GenerateAWSOIDCToken(GenerateAWSOIDCTokenRequest) returns (GenerateAWSOIDCTokenResponse);
|
||||
|
||||
// GenerateGitHubUserCert signs a SSH certificate for GitHub integration.
|
||||
rpc GenerateGitHubUserCert(GenerateGitHubUserCertRequest) returns (GenerateGitHubUserCertResponse);
|
||||
|
||||
// ExportIntegrationCertAuthorities exports cert authorities for an integration.
|
||||
rpc ExportIntegrationCertAuthorities(ExportIntegrationCertAuthoritiesRequest) returns (ExportIntegrationCertAuthoritiesResponse);
|
||||
}
|
||||
|
||||
// ListIntegrationsRequest is a request for a paginated list of Integrations.
|
||||
@@ -111,3 +118,38 @@ message GenerateAWSOIDCTokenResponse {
|
||||
// Token is the signed JWT ready to be used
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
// GenerateGitHubUserCertRequest is a request to sign a client certificate used by
|
||||
// GitHub integration to authenticate with GitHub enterprise.
|
||||
message GenerateGitHubUserCertRequest {
|
||||
// Integration is the name of the integration;
|
||||
string integration = 1;
|
||||
// PublicKey is the public key to be signed.
|
||||
bytes public_key = 2;
|
||||
// UserId is the GitHub user id.
|
||||
string user_id = 3;
|
||||
// KeyId is the certificate ID, usually the Teleport username.
|
||||
string key_id = 4;
|
||||
// Ttl is the duration the certificate will be valid for.
|
||||
google.protobuf.Duration ttl = 5;
|
||||
}
|
||||
|
||||
// GenerateGitHubUserCertResponse contains a signed certificate.
|
||||
message GenerateGitHubUserCertResponse {
|
||||
// AuthorizedKey is the signed certificate.
|
||||
bytes authorized_key = 1;
|
||||
}
|
||||
|
||||
// ExportIntegrationCertAuthoritiesRequest is the request to export cert
|
||||
// authorities for an integration.
|
||||
message ExportIntegrationCertAuthoritiesRequest {
|
||||
// Integration is the name of the integration;
|
||||
string integration = 1;
|
||||
}
|
||||
|
||||
// ExportIntegrationCertAuthoritiesResponse is the response to
|
||||
// ExportIntegrationCertAuthorities.
|
||||
message ExportIntegrationCertAuthoritiesResponse {
|
||||
// CertAuthorities are the CA key sets used to sign any new certificates.
|
||||
types.CAKeySet cert_authorities = 1;
|
||||
}
|
||||
|
||||
@@ -1242,6 +1242,9 @@ type Cache interface {
|
||||
|
||||
// ListAccountAssignments fetches a paginated list of IdentityCenter Account Assignments
|
||||
ListAccountAssignments(context.Context, int, *pagination.PageRequestToken) ([]services.IdentityCenterAccountAssignment, pagination.NextPageToken, error)
|
||||
|
||||
// GetPluginStaticCredentialsByLabels will get a list of plugin static credentials resource by matching labels.
|
||||
GetPluginStaticCredentialsByLabels(ctx context.Context, labels map[string]string) ([]types.PluginStaticCredentials, error)
|
||||
}
|
||||
|
||||
type NodeWrapper struct {
|
||||
|
||||
@@ -1892,6 +1892,9 @@ type ClientI interface {
|
||||
// ProvisioningServiceClient returns provisioning service client.
|
||||
ProvisioningServiceClient() provisioningv1.ProvisioningServiceClient
|
||||
|
||||
// IntegrationsClient returns integrations client.
|
||||
IntegrationsClient() integrationv1.IntegrationServiceClient
|
||||
|
||||
// GitServerClient returns git server client.
|
||||
GitServerClient() gitserverv1.GitServerServiceClient
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"context"
|
||||
"maps"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
)
|
||||
|
||||
// Package credentials defines constants and provides helper functions for
|
||||
// integration credentials.
|
||||
|
||||
const (
|
||||
// LabelStaticCredentialsIntegration is the label used to store the
|
||||
// UUID ref in the static credentials.
|
||||
LabelStaticCredentialsIntegration = types.TeleportInternalLabelPrefix + types.KindIntegration
|
||||
// LabelStaticCredentialsPurpose is the label used to store the purpose of
|
||||
// the static credentials.
|
||||
LabelStaticCredentialsPurpose = "purpose"
|
||||
|
||||
// PurposeGitHubSSHCA is the label value that indicates the static
|
||||
// credentials contains the GitHub SSH CA.
|
||||
PurposeGitHubSSHCA = "github-sshca"
|
||||
// PurposeGitHubOAuth is the label value that indicates the static
|
||||
// credentials contains the GitHub OAuth ID and secret.
|
||||
PurposeGitHubOAuth = "github-oauth"
|
||||
)
|
||||
|
||||
// NewRef creates a new PluginStaticCredentialsRef that is saved along with the
|
||||
// integration resource in the backend. The actual credentials are saved as
|
||||
// PlugStaticCredentials and can only be retrieved by the ref.
|
||||
func NewRef() *types.PluginStaticCredentialsRef {
|
||||
return NewRefWithUUID(uuid.NewString())
|
||||
}
|
||||
|
||||
// NewRefWithUUID creates a PluginStaticCredentialsRef with provided UUID.
|
||||
func NewRefWithUUID(uuid string) *types.PluginStaticCredentialsRef {
|
||||
return &types.PluginStaticCredentialsRef{
|
||||
Labels: map[string]string{
|
||||
LabelStaticCredentialsIntegration: uuid,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CopyRefLabels copies the labels from the Ref to the actual credentials so the
|
||||
// credentials can be retrieved using the same labels.
|
||||
func CopyRefLabels(cred types.PluginStaticCredentials, ref *types.PluginStaticCredentialsRef) {
|
||||
labels := cred.GetStaticLabels()
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
maps.Copy(labels, ref.Labels)
|
||||
|
||||
cred.SetStaticLabels(labels)
|
||||
}
|
||||
|
||||
// ByLabelsGetter defines an interface to retrieve credentials by labels.
|
||||
type ByLabelsGetter interface {
|
||||
// GetPluginStaticCredentialsByLabels will get a list of plugin static credentials resource by matching labels.
|
||||
GetPluginStaticCredentialsByLabels(ctx context.Context, labels map[string]string) ([]types.PluginStaticCredentials, error)
|
||||
}
|
||||
|
||||
// GetByPurpose retrieves a credentials based on the provided purpose.
|
||||
func GetByPurpose(ctx context.Context, ref *types.PluginStaticCredentialsRef, purpose string, getter ByLabelsGetter) (types.PluginStaticCredentials, error) {
|
||||
if ref == nil {
|
||||
return nil, trace.BadParameter("missing credentials ref")
|
||||
}
|
||||
labels := ref.Labels
|
||||
if len(labels) == 0 {
|
||||
return nil, trace.BadParameter("missing labels from credentials ref")
|
||||
}
|
||||
labels[LabelStaticCredentialsPurpose] = purpose
|
||||
|
||||
creds, err := getter.GetPluginStaticCredentialsByLabels(ctx, labels)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
switch len(creds) {
|
||||
case 0:
|
||||
return nil, trace.NotFound("%v credentials not found", purpose)
|
||||
case 1:
|
||||
return creds[0], nil
|
||||
default:
|
||||
return nil, trace.CompareFailed("expecting one plugin static credentials but got %v", len(creds))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"maps"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
)
|
||||
|
||||
type mockByLabelsGetter struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *mockByLabelsGetter) GetPluginStaticCredentialsByLabels(_ context.Context, labels map[string]string) ([]types.PluginStaticCredentials, error) {
|
||||
args := m.Called(labels)
|
||||
creds, ok := args.Get(0).([]types.PluginStaticCredentials)
|
||||
if ok {
|
||||
return creds, args.Error(1)
|
||||
}
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
|
||||
func mustMakeCred(t *testing.T, labels map[string]string) types.PluginStaticCredentials {
|
||||
t.Helper()
|
||||
cred, err := types.NewPluginStaticCredentials(
|
||||
types.Metadata{
|
||||
Name: uuid.NewString(),
|
||||
Labels: labels,
|
||||
},
|
||||
types.PluginStaticCredentialsSpecV1{
|
||||
Credentials: &types.PluginStaticCredentialsSpecV1_APIToken{
|
||||
APIToken: "token",
|
||||
},
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
return cred
|
||||
}
|
||||
|
||||
func TestGetByPurpose(t *testing.T) {
|
||||
ref := NewRef()
|
||||
purpose := "test-found"
|
||||
labels := map[string]string{LabelStaticCredentialsPurpose: purpose}
|
||||
maps.Copy(labels, ref.Labels)
|
||||
cred := mustMakeCred(t, labels)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ref *types.PluginStaticCredentialsRef
|
||||
setupMock func(m *mockByLabelsGetter)
|
||||
wantError func(error) bool
|
||||
wantCred types.PluginStaticCredentials
|
||||
}{
|
||||
{
|
||||
name: "nil ref",
|
||||
ref: nil,
|
||||
wantError: trace.IsBadParameter,
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
ref: ref,
|
||||
setupMock: func(m *mockByLabelsGetter) {
|
||||
m.On("GetPluginStaticCredentialsByLabels", labels).
|
||||
Return([]types.PluginStaticCredentials{cred}, nil)
|
||||
},
|
||||
wantCred: cred,
|
||||
},
|
||||
{
|
||||
name: "no creds found",
|
||||
ref: ref,
|
||||
setupMock: func(m *mockByLabelsGetter) {
|
||||
m.On("GetPluginStaticCredentialsByLabels", labels).
|
||||
Return([]types.PluginStaticCredentials{}, nil)
|
||||
},
|
||||
wantError: trace.IsNotFound,
|
||||
},
|
||||
{
|
||||
name: "too mandy creds found",
|
||||
ref: ref,
|
||||
setupMock: func(m *mockByLabelsGetter) {
|
||||
m.On("GetPluginStaticCredentialsByLabels", labels).
|
||||
Return([]types.PluginStaticCredentials{cred, mustMakeCred(t, labels)}, nil)
|
||||
},
|
||||
wantError: trace.IsCompareFailed,
|
||||
},
|
||||
{
|
||||
name: "backend issue",
|
||||
ref: ref,
|
||||
setupMock: func(m *mockByLabelsGetter) {
|
||||
m.On("GetPluginStaticCredentialsByLabels", labels).
|
||||
Return(nil, trace.ConnectionProblem(fmt.Errorf("backend"), "problem"))
|
||||
},
|
||||
wantError: trace.IsConnectionProblem,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
m := &mockByLabelsGetter{}
|
||||
if test.setupMock != nil {
|
||||
test.setupMock(m)
|
||||
}
|
||||
|
||||
cred, err := GetByPurpose(context.Background(), test.ref, purpose, m)
|
||||
if test.wantError != nil {
|
||||
require.True(t, test.wantError(err))
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.wantCred, cred)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -20,47 +20,42 @@ package integrationv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"maps"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/auth/integration/credentials"
|
||||
"github.com/gravitational/teleport/lib/cryptosuites"
|
||||
)
|
||||
|
||||
const (
|
||||
// labelStaticCredentialsIntegration is the label used to store the
|
||||
// UUID ref in the static credentials.
|
||||
labelStaticCredentialsIntegration = types.TeleportInternalLabelPrefix + types.KindIntegration
|
||||
// labelStaticCredentialsPurpose is the label used to store the purpose of
|
||||
// the static credentials.
|
||||
labelStaticCredentialsPurpose = "purpose"
|
||||
|
||||
// purposeGitHubSSHCA is the label value that indicates the static
|
||||
// credentials contains the GitHub SSH CA.
|
||||
purposeGitHubSSHCA = "github-sshca"
|
||||
// purposeGitHubOAuth is the label value that indicates the static
|
||||
// credentials contains the GitHub OAuth ID and secret.
|
||||
purposeGitHubOAuth = "github-oauth"
|
||||
)
|
||||
|
||||
func newStaticCredentialsRef(uuid string) *types.PluginStaticCredentialsRef {
|
||||
return &types.PluginStaticCredentialsRef{
|
||||
Labels: map[string]string{
|
||||
labelStaticCredentialsIntegration: uuid,
|
||||
},
|
||||
// ExportIntegrationCertAuthorities exports cert authorities for an integration.
|
||||
func (s *Service) ExportIntegrationCertAuthorities(ctx context.Context, in *integrationpb.ExportIntegrationCertAuthoritiesRequest) (*integrationpb.ExportIntegrationCertAuthoritiesResponse, error) {
|
||||
authCtx, err := s.authorizer.Authorize(ctx)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
func copyRefLabels(cred types.PluginStaticCredentials, ref *types.PluginStaticCredentialsRef) {
|
||||
labels := cred.GetStaticLabels()
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
if err := authCtx.CheckAccessToKind(types.KindIntegration, types.VerbRead); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
ig, err := s.cache.GetIntegration(ctx, in.Integration)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
maps.Copy(labels, ref.Labels)
|
||||
|
||||
cred.SetStaticLabels(labels)
|
||||
// Currently only public keys are exported.
|
||||
switch ig.GetSubKind() {
|
||||
case types.IntegrationSubKindGitHub:
|
||||
caKeySet, err := s.getGitHubCertAuthorities(ctx, ig)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
caKeySetWithoutSecerts := caKeySet.WithoutSecrets()
|
||||
return &integrationpb.ExportIntegrationCertAuthoritiesResponse{CertAuthorities: &caKeySetWithoutSecerts}, nil
|
||||
default:
|
||||
return nil, trace.BadParameter("unsupported for integration subkind %v", ig.GetSubKind())
|
||||
}
|
||||
}
|
||||
|
||||
func buildGitHubOAuthCredentials(ig types.Integration) (*types.PluginStaticCredentialsV1, error) {
|
||||
@@ -73,7 +68,7 @@ func buildGitHubOAuthCredentials(ig types.Integration) (*types.PluginStaticCrede
|
||||
Metadata: types.Metadata{
|
||||
Name: uuid.NewString(),
|
||||
Labels: map[string]string{
|
||||
labelStaticCredentialsPurpose: purposeGitHubOAuth,
|
||||
credentials.LabelStaticCredentialsPurpose: credentials.PurposeGitHubOAuth,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -98,7 +93,7 @@ func (s *Service) newGitHubSSHCA(ctx context.Context) (*types.PluginStaticCreden
|
||||
Metadata: types.Metadata{
|
||||
Name: uuid.NewString(),
|
||||
Labels: map[string]string{
|
||||
labelStaticCredentialsPurpose: purposeGitHubSSHCA,
|
||||
credentials.LabelStaticCredentialsPurpose: credentials.PurposeGitHubSSHCA,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -132,11 +127,11 @@ func (s *Service) createGitHubCredentials(ctx context.Context, ig types.Integrat
|
||||
}
|
||||
|
||||
func (s *Service) createStaticCredentials(ctx context.Context, ig types.Integration, creds ...types.PluginStaticCredentials) error {
|
||||
ref := newStaticCredentialsRef(uuid.NewString())
|
||||
ref := credentials.NewRef()
|
||||
|
||||
for _, cred := range creds {
|
||||
s.logger.DebugContext(ctx, "Creating static credentials", "integration", ig.GetName(), "labels", cred.GetStaticLabels())
|
||||
copyRefLabels(cred, ref)
|
||||
credentials.CopyRefLabels(cred, ref)
|
||||
if err := s.backend.CreatePluginStaticCredentials(ctx, cred); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
@@ -185,7 +180,7 @@ func (s *Service) updateStaticCredentials(ctx context.Context, ig types.Integrat
|
||||
s.logger.DebugContext(ctx, "Updating static credentials", "integration", ig.GetName(), "labels", cred.GetStaticLabels())
|
||||
|
||||
// Use same labels to find existing credentials.
|
||||
copyRefLabels(cred, ref)
|
||||
credentials.CopyRefLabels(cred, ref)
|
||||
oldCreds, err := s.backend.GetPluginStaticCredentialsByLabels(ctx, cred.GetStaticLabels())
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
@@ -226,3 +221,29 @@ func (s *Service) removeStaticCredentials(ctx context.Context, ig types.Integrat
|
||||
}
|
||||
return trace.NewAggregate(errors...)
|
||||
}
|
||||
|
||||
func (s *Service) getStaticCredentialsWithPurpose(ctx context.Context, ig types.Integration, purpose string) (types.PluginStaticCredentials, error) {
|
||||
if ig.GetCredentials() == nil {
|
||||
return nil, trace.BadParameter("missing credentials")
|
||||
}
|
||||
|
||||
return credentials.GetByPurpose(ctx, ig.GetCredentials().GetStaticCredentialsRef(), purpose, s.cache)
|
||||
}
|
||||
|
||||
func (s *Service) getGitHubCertAuthorities(ctx context.Context, ig types.Integration) (*types.CAKeySet, error) {
|
||||
if ig.GetSubKind() != types.IntegrationSubKindGitHub {
|
||||
return nil, trace.BadParameter("integration is not a GitHub integration")
|
||||
}
|
||||
creds, err := s.getStaticCredentialsWithPurpose(ctx, ig, credentials.PurposeGitHubSSHCA)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
cas := creds.GetSSHCertAuthorities()
|
||||
if len(cas) == 0 {
|
||||
return nil, trace.BadParameter("missing SSH cert authorities from plugin static credentials")
|
||||
}
|
||||
return &types.CAKeySet{
|
||||
SSH: cas,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package integrationv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/authz"
|
||||
)
|
||||
|
||||
func TestExportIntegrationCertAuthorities(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ca := newCertAuthority(t, types.HostCA, "test-cluster")
|
||||
ctx, localClient, resourceSvc := initSvc(t, ca, ca.GetClusterName(), "127.0.0.1")
|
||||
|
||||
githubIntegration, err := newGitHubIntegration("github-my-org", "id", "secret")
|
||||
require.NoError(t, err)
|
||||
|
||||
oidcIntegration, err := types.NewIntegrationAWSOIDC(
|
||||
types.Metadata{Name: "aws-oidc"},
|
||||
&types.AWSOIDCIntegrationSpecV1{
|
||||
RoleARN: "arn:aws:iam::123456789012:role/OpsTeam",
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
adminCtx := authz.ContextWithUser(ctx, authz.BuiltinRole{
|
||||
Role: types.RoleAdmin,
|
||||
Username: string(types.RoleAdmin),
|
||||
})
|
||||
|
||||
_, err = resourceSvc.CreateIntegration(adminCtx, &integrationpb.CreateIntegrationRequest{Integration: githubIntegration})
|
||||
require.NoError(t, err)
|
||||
_, err = resourceSvc.CreateIntegration(adminCtx, &integrationpb.CreateIntegrationRequest{Integration: oidcIntegration})
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
integration string
|
||||
identity context.Context
|
||||
check func(*testing.T, *integrationpb.ExportIntegrationCertAuthoritiesResponse, error)
|
||||
}{
|
||||
{
|
||||
name: "success",
|
||||
integration: githubIntegration.GetName(),
|
||||
identity: adminCtx,
|
||||
check: func(t *testing.T, resp *integrationpb.ExportIntegrationCertAuthoritiesResponse, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
require.NotNil(t, resp.CertAuthorities)
|
||||
require.Len(t, resp.CertAuthorities.SSH, 1)
|
||||
require.NotNil(t, resp.CertAuthorities.SSH[0])
|
||||
assert.NotEmpty(t, resp.CertAuthorities.SSH[0].PublicKey)
|
||||
assert.Empty(t, resp.CertAuthorities.SSH[0].PrivateKey)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not found",
|
||||
integration: "not-found",
|
||||
identity: adminCtx,
|
||||
check: func(t *testing.T, resp *integrationpb.ExportIntegrationCertAuthoritiesResponse, err error) {
|
||||
t.Helper()
|
||||
require.Nil(t, resp)
|
||||
require.Error(t, err)
|
||||
require.True(t, trace.IsNotFound(err))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not allowed",
|
||||
integration: githubIntegration.GetName(),
|
||||
identity: authorizerForDummyUser(t, ctx, types.RoleSpecV6{}, localClient),
|
||||
check: func(t *testing.T, resp *integrationpb.ExportIntegrationCertAuthoritiesResponse, err error) {
|
||||
t.Helper()
|
||||
require.Nil(t, resp)
|
||||
require.Error(t, err)
|
||||
require.True(t, trace.IsAccessDenied(err))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not supported",
|
||||
integration: oidcIntegration.GetName(),
|
||||
identity: adminCtx,
|
||||
check: func(t *testing.T, resp *integrationpb.ExportIntegrationCertAuthoritiesResponse, err error) {
|
||||
t.Helper()
|
||||
require.Nil(t, resp)
|
||||
require.Error(t, err)
|
||||
require.True(t, trace.IsBadParameter(err))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
resp, err := resourceSvc.ExportIntegrationCertAuthorities(test.identity, &integrationpb.ExportIntegrationCertAuthoritiesRequest{
|
||||
Integration: test.integration,
|
||||
})
|
||||
test.check(t, resp, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package integrationv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/authz"
|
||||
)
|
||||
|
||||
// GenerateGitHubUserCert signs a SSH certificate for GitHub integration.
|
||||
func (s *Service) GenerateGitHubUserCert(ctx context.Context, in *integrationpb.GenerateGitHubUserCertRequest) (*integrationpb.GenerateGitHubUserCertResponse, error) {
|
||||
authCtx, err := s.authorizer.Authorize(ctx)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
if !authz.HasBuiltinRole(*authCtx, string(types.RoleProxy)) {
|
||||
return nil, trace.AccessDenied("GenerateGitHubUserCert is only available to proxy services")
|
||||
}
|
||||
|
||||
cert, err := s.prepareGitHubCert(in)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
caSigner, err := s.getGitHubSigner(ctx, in.Integration)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
if err := cert.SignCert(rand.Reader, caSigner); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return &integrationpb.GenerateGitHubUserCertResponse{
|
||||
AuthorizedKey: ssh.MarshalAuthorizedKey(cert),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) prepareGitHubCert(in *integrationpb.GenerateGitHubUserCertRequest) (*ssh.Certificate, error) {
|
||||
if in.UserId == "" {
|
||||
return nil, trace.BadParameter("missing UserId for GenerateGitHubUserCert")
|
||||
}
|
||||
if in.KeyId == "" {
|
||||
return nil, trace.BadParameter("missing KeyId for GenerateGitHubUserCert")
|
||||
}
|
||||
key, _, _, _, err := ssh.ParseAuthorizedKey(in.PublicKey)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
// Sign with user ID set in [email protected] extension.
|
||||
// https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-git-access-to-your-organizations-repositories/about-ssh-certificate-authorities
|
||||
now := s.clock.Now()
|
||||
cert := &ssh.Certificate{
|
||||
Key: key,
|
||||
CertType: ssh.UserCert,
|
||||
KeyId: in.KeyId,
|
||||
ValidAfter: uint64(now.Add(-time.Minute).Unix()),
|
||||
ValidBefore: uint64(now.Add(in.Ttl.AsDuration()).Unix()),
|
||||
Permissions: ssh.Permissions{
|
||||
Extensions: map[string]string{
|
||||
"[email protected]": in.UserId,
|
||||
},
|
||||
},
|
||||
}
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func (s *Service) getGitHubSigner(ctx context.Context, integration string) (ssh.Signer, error) {
|
||||
ig, err := s.cache.GetIntegration(ctx, integration)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
caKeySet, err := s.getGitHubCertAuthorities(ctx, ig)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
caSigner, err := s.keyStoreManager.GetSSHSignerFromKeySet(ctx, *caKeySet)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return caSigner, nil
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package integrationv1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/authz"
|
||||
"github.com/gravitational/teleport/lib/cryptosuites"
|
||||
)
|
||||
|
||||
func TestGenerateGitHubUserCert(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ca := newCertAuthority(t, types.HostCA, "test-cluster")
|
||||
ctx, _, resourceSvc := initSvc(t, ca, ca.GetClusterName(), "127.0.0.1.nip.io")
|
||||
|
||||
githubIntegration, err := newGitHubIntegration("github-my-org", "id", "secret")
|
||||
require.NoError(t, err)
|
||||
|
||||
adminCtx := authz.ContextWithUser(ctx, authz.BuiltinRole{
|
||||
Role: types.RoleAdmin,
|
||||
Username: string(types.RoleAdmin),
|
||||
})
|
||||
_, err = resourceSvc.CreateIntegration(adminCtx, &integrationpb.CreateIntegrationRequest{Integration: githubIntegration})
|
||||
require.NoError(t, err)
|
||||
|
||||
key, err := cryptosuites.GeneratePrivateKeyWithAlgorithm(cryptosuites.Ed25519)
|
||||
require.NoError(t, err)
|
||||
|
||||
req := &integrationpb.GenerateGitHubUserCertRequest{
|
||||
Integration: "github-my-org",
|
||||
PublicKey: key.MarshalSSHPublicKey(),
|
||||
UserId: "1122334455",
|
||||
KeyId: "alice",
|
||||
Ttl: durationpb.New(time.Minute),
|
||||
}
|
||||
|
||||
// Admin users cannot generate certs.
|
||||
_, err = resourceSvc.GenerateGitHubUserCert(adminCtx, req)
|
||||
require.True(t, trace.IsAccessDenied(err))
|
||||
|
||||
// Call as Proxy.
|
||||
proxyCtx := authz.ContextWithUser(ctx, authz.BuiltinRole{
|
||||
Role: types.RoleProxy,
|
||||
Username: string(types.RoleProxy),
|
||||
})
|
||||
resp, err := resourceSvc.GenerateGitHubUserCert(proxyCtx, req)
|
||||
require.NoError(t, err)
|
||||
authorizedKey, _, _, _, err := ssh.ParseAuthorizedKey(resp.AuthorizedKey)
|
||||
require.NoError(t, err)
|
||||
sshCert, ok := authorizedKey.(*ssh.Certificate)
|
||||
require.True(t, ok)
|
||||
|
||||
assert.Equal(t, "alice", sshCert.KeyId)
|
||||
assert.Equal(t, map[string]string{"[email protected]": "1122334455"}, sshCert.Permissions.Extensions)
|
||||
}
|
||||
@@ -53,6 +53,9 @@ type Cache interface {
|
||||
|
||||
// IntegrationsGetter defines methods to access Integration resources.
|
||||
services.IntegrationsGetter
|
||||
|
||||
// GetPluginStaticCredentialsByLabels will get a list of plugin static credentials resource by matching labels.
|
||||
GetPluginStaticCredentialsByLabels(ctx context.Context, labels map[string]string) ([]types.PluginStaticCredentials, error)
|
||||
}
|
||||
|
||||
// KeyStoreManager defines methods to get signers using the server's keystore.
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/api/types/externalauditstorage"
|
||||
"github.com/gravitational/teleport/lib/auth/integration/credentials"
|
||||
"github.com/gravitational/teleport/lib/auth/keystore"
|
||||
"github.com/gravitational/teleport/lib/auth/testauthority"
|
||||
"github.com/gravitational/teleport/lib/authz"
|
||||
@@ -63,32 +64,6 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||
return ig
|
||||
}
|
||||
|
||||
newGitHubIntegration := func(name, id, secret string) (*types.IntegrationV1, error) {
|
||||
ig, err := types.NewIntegrationGitHub(
|
||||
types.Metadata{
|
||||
Name: name,
|
||||
},
|
||||
&types.GitHubIntegrationSpecV1{
|
||||
Organization: "my-org",
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
if secret != "" {
|
||||
ig.SetCredentials(&types.PluginCredentialsV1{
|
||||
Credentials: &types.PluginCredentialsV1_IdSecret{
|
||||
IdSecret: &types.PluginIdSecretCredential{
|
||||
Id: id,
|
||||
Secret: secret,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
return ig, nil
|
||||
}
|
||||
|
||||
tt := []struct {
|
||||
Name string
|
||||
Role types.RoleSpecV6
|
||||
@@ -446,7 +421,7 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||
refUUID := uuid.NewString()
|
||||
ig.SetCredentials(&types.PluginCredentialsV1{
|
||||
Credentials: &types.PluginCredentialsV1_StaticCredentialsRef{
|
||||
StaticCredentialsRef: newStaticCredentialsRef(refUUID),
|
||||
StaticCredentialsRef: credentials.NewRefWithUUID(refUUID),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -459,8 +434,8 @@ func TestIntegrationCRUD(t *testing.T) {
|
||||
Metadata: types.Metadata{
|
||||
Name: igName,
|
||||
Labels: map[string]string{
|
||||
labelStaticCredentialsIntegration: refUUID,
|
||||
labelStaticCredentialsPurpose: "test",
|
||||
credentials.LabelStaticCredentialsIntegration: refUUID,
|
||||
credentials.LabelStaticCredentialsPurpose: "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -652,7 +627,8 @@ func initSvc(t *testing.T, ca types.CertAuthority, clusterName string, proxyPubl
|
||||
PublicAddrs: []string{proxyPublicAddr},
|
||||
}},
|
||||
},
|
||||
IntegrationsService: *cacheResourceService,
|
||||
IntegrationsService: *cacheResourceService,
|
||||
PluginStaticCredentialsService: localCredService,
|
||||
}
|
||||
|
||||
resourceSvc, err := NewService(&ServiceConfig{
|
||||
@@ -689,6 +665,7 @@ type mockCache struct {
|
||||
returnErr error
|
||||
|
||||
local.IntegrationsService
|
||||
*local.PluginStaticCredentialsService
|
||||
}
|
||||
|
||||
func (m *mockCache) GetProxies() ([]types.Server, error) {
|
||||
@@ -769,6 +746,32 @@ func newPlugin(t *testing.T, integrationName string) *types.PluginV1 {
|
||||
}
|
||||
}
|
||||
|
||||
func newGitHubIntegration(name, id, secret string) (*types.IntegrationV1, error) {
|
||||
ig, err := types.NewIntegrationGitHub(
|
||||
types.Metadata{
|
||||
Name: name,
|
||||
},
|
||||
&types.GitHubIntegrationSpecV1{
|
||||
Organization: "my-org",
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
if secret != "" {
|
||||
ig.SetCredentials(&types.PluginCredentialsV1{
|
||||
Credentials: &types.PluginCredentialsV1_IdSecret{
|
||||
IdSecret: &types.PluginIdSecretCredential{
|
||||
Id: id,
|
||||
Secret: secret,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
return ig, nil
|
||||
}
|
||||
|
||||
func mustFindGitHubCredentials(t *testing.T, localClient Backend, igName, wantId, wantSecret string) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ var _ executor[types.PluginStaticCredentials, pluginStaticCredentialsGetter] = p
|
||||
type pluginStaticCredentialsExecutor struct{}
|
||||
|
||||
func (pluginStaticCredentialsExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]types.PluginStaticCredentials, error) {
|
||||
return cache.pluginStaticCredentialsCache.GetAllPluginStaticCredentials(ctx)
|
||||
return cache.PluginStaticCredentials.GetAllPluginStaticCredentials(ctx)
|
||||
}
|
||||
|
||||
func (pluginStaticCredentialsExecutor) upsert(ctx context.Context, cache *Cache, resource types.PluginStaticCredentials) error {
|
||||
|
||||
@@ -22,12 +22,15 @@ import (
|
||||
"context"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/mfa"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/auth/authclient"
|
||||
@@ -49,6 +52,23 @@ type ExportAuthoritiesRequest struct {
|
||||
AuthType string
|
||||
ExportAuthorityFingerprint string
|
||||
UseCompatVersion bool
|
||||
Integration string
|
||||
}
|
||||
|
||||
func (r *ExportAuthoritiesRequest) shouldExportIntegration(ctx context.Context) (bool, error) {
|
||||
switch r.AuthType {
|
||||
case "github":
|
||||
if r.Integration == "" {
|
||||
return false, trace.BadParameter("integration name must be provided for %q CAs", r.AuthType)
|
||||
}
|
||||
return true, nil
|
||||
default:
|
||||
if r.Integration != "" {
|
||||
r.Integration = ""
|
||||
slog.DebugContext(ctx, "Integration name is ignored for non-integration CAs")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExportAuthorities returns the list of authorities in OpenSSH compatible formats as a string.
|
||||
@@ -76,12 +96,22 @@ type ExportAuthoritiesRequest struct {
|
||||
// > @cert-authority *.cluster-a ssh-rsa AAA... type=host
|
||||
// URL encoding is used to pass the CA type and allowed logins into the comment field.
|
||||
func ExportAuthorities(ctx context.Context, client authclient.ClientI, req ExportAuthoritiesRequest) (string, error) {
|
||||
if isIntegration, err := req.shouldExportIntegration(ctx); err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
} else if isIntegration {
|
||||
return exportAuthForIntegration(ctx, client, req)
|
||||
}
|
||||
return exportAuth(ctx, client, req, false /* exportSecrets */)
|
||||
}
|
||||
|
||||
// ExportAuthoritiesSecrets exports the Authority Certificate secrets (private keys).
|
||||
// See ExportAuthorities for more information.
|
||||
func ExportAuthoritiesSecrets(ctx context.Context, client authclient.ClientI, req ExportAuthoritiesRequest) (string, error) {
|
||||
if isIntegration, err := req.shouldExportIntegration(ctx); err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
} else if isIntegration {
|
||||
return "", trace.NotImplemented("export with secrets is not supported for %q CAs", req.AuthType)
|
||||
}
|
||||
return exportAuth(ctx, client, req, true /* exportSecrets */)
|
||||
}
|
||||
|
||||
@@ -344,3 +374,49 @@ func hostCAFormat(ca types.CertAuthority, keyBytes []byte, client authclient.Cli
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func exportAuthForIntegration(ctx context.Context, client authclient.ClientI, req ExportAuthoritiesRequest) (string, error) {
|
||||
switch req.AuthType {
|
||||
case "github":
|
||||
keySet, err := fetchIntegrationCAKeySet(ctx, client, req.Integration)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
ret, err := exportGitHubCAs(keySet, req)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
return ret, nil
|
||||
|
||||
default:
|
||||
return "", trace.BadParameter("unknown integration CA type %q", req.AuthType)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchIntegrationCAKeySet(ctx context.Context, client authclient.ClientI, integration string) (*types.CAKeySet, error) {
|
||||
resp, err := client.IntegrationsClient().ExportIntegrationCertAuthorities(ctx, &integrationpb.ExportIntegrationCertAuthoritiesRequest{
|
||||
Integration: integration,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return resp.CertAuthorities, nil
|
||||
}
|
||||
|
||||
func exportGitHubCAs(keySet *types.CAKeySet, req ExportAuthoritiesRequest) (string, error) {
|
||||
ret := strings.Builder{}
|
||||
for _, key := range keySet.SSH {
|
||||
if req.ExportAuthorityFingerprint != "" {
|
||||
if fingerprint, err := sshutils.AuthorizedKeyFingerprint(key.PublicKey); err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
} else if !sshutils.EqualFingerprints(req.ExportAuthorityFingerprint, fingerprint) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub only needs the keys like "ssh-rsa xxx" so print them without
|
||||
// cert-authority for easier copy-and-paste.
|
||||
ret.WriteString(fmt.Sprintf("%s integration=%s\n", strings.TrimSpace(string(key.PublicKey)), req.Integration))
|
||||
}
|
||||
return ret.String(), nil
|
||||
}
|
||||
|
||||
@@ -26,18 +26,22 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/gravitational/teleport/api/client/proto"
|
||||
integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1"
|
||||
"github.com/gravitational/teleport/api/mfa"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/api/utils/keys"
|
||||
"github.com/gravitational/teleport/lib/auth"
|
||||
"github.com/gravitational/teleport/lib/auth/authclient"
|
||||
"github.com/gravitational/teleport/lib/fixtures"
|
||||
)
|
||||
|
||||
type mockAuthClient struct {
|
||||
authclient.ClientI
|
||||
server *auth.Server
|
||||
server *auth.Server
|
||||
integrationsClient mockIntegrationsClient
|
||||
}
|
||||
|
||||
func (m *mockAuthClient) GetDomainName(ctx context.Context) (string, error) {
|
||||
@@ -57,6 +61,21 @@ func (m *mockAuthClient) PerformMFACeremony(ctx context.Context, challengeReques
|
||||
return nil, &mfa.ErrMFANotRequired
|
||||
}
|
||||
|
||||
func (m *mockAuthClient) IntegrationsClient() integrationpb.IntegrationServiceClient {
|
||||
return &m.integrationsClient
|
||||
}
|
||||
|
||||
type mockIntegrationsClient struct {
|
||||
integrationpb.IntegrationServiceClient
|
||||
caKeySet *types.CAKeySet
|
||||
}
|
||||
|
||||
func (m *mockIntegrationsClient) ExportIntegrationCertAuthorities(ctx context.Context, in *integrationpb.ExportIntegrationCertAuthoritiesRequest, opts ...grpc.CallOption) (*integrationpb.ExportIntegrationCertAuthoritiesResponse, error) {
|
||||
return &integrationpb.ExportIntegrationCertAuthoritiesResponse{
|
||||
CertAuthorities: m.caKeySet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestExportAuthorities(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
const localClusterName = "localcluster"
|
||||
@@ -100,6 +119,10 @@ func TestExportAuthorities(t *testing.T) {
|
||||
require.NotNil(t, privKey, "x509.ParsePKCS8PrivateKey returned a nil key")
|
||||
}
|
||||
|
||||
validateGitHubCAFunc := func(t *testing.T, s string) {
|
||||
require.Contains(t, s, fixtures.SSHCAPublicKey)
|
||||
}
|
||||
|
||||
for _, exportSecrets := range []bool{false, true} {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
@@ -247,10 +270,33 @@ func TestExportAuthorities(t *testing.T) {
|
||||
assertNoSecrets: validateTLSCertificateDERFunc,
|
||||
assertSecrets: validateRSAPrivateKeyDERFunc,
|
||||
},
|
||||
{
|
||||
name: "github missing integration",
|
||||
req: ExportAuthoritiesRequest{
|
||||
AuthType: "github",
|
||||
},
|
||||
errorCheck: require.Error,
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
req: ExportAuthoritiesRequest{
|
||||
AuthType: "github",
|
||||
Integration: "my-github",
|
||||
},
|
||||
errorCheck: require.NoError,
|
||||
assertNoSecrets: validateGitHubCAFunc,
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("%s_exportSecrets_%v", tt.name, exportSecrets), func(t *testing.T) {
|
||||
mockedClient := &mockAuthClient{
|
||||
server: testAuth.AuthServer,
|
||||
integrationsClient: mockIntegrationsClient{
|
||||
caKeySet: &types.CAKeySet{
|
||||
SSH: []*types.SSHKeyPair{{
|
||||
PublicKey: []byte(fixtures.SSHCAPublicKey),
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
var (
|
||||
err error
|
||||
@@ -264,6 +310,10 @@ func TestExportAuthorities(t *testing.T) {
|
||||
checkFunc = tt.assertSecrets
|
||||
}
|
||||
|
||||
if checkFunc == nil {
|
||||
t.Skip("assert func not provided")
|
||||
}
|
||||
|
||||
exported, err = exportFunc(ctx, mockedClient, tt.req)
|
||||
tt.errorCheck(t, err)
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ type PluginStaticCredentials interface {
|
||||
|
||||
// DeletePluginStaticCredentials will delete a plugin static credentials resource.
|
||||
DeletePluginStaticCredentials(ctx context.Context, name string) error
|
||||
|
||||
// GetAllPluginStaticCredentials will get all plugin static credentials.
|
||||
GetAllPluginStaticCredentials(ctx context.Context) ([]types.PluginStaticCredentials, error)
|
||||
}
|
||||
|
||||
// MarshalPluginStaticCredentials marshals PluginStaticCredentials resource to JSON.
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
package sshutils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
@@ -47,3 +49,18 @@ func PrivateKeyFingerprint(keyBytes []byte) (string, error) {
|
||||
}
|
||||
return Fingerprint(signer.PublicKey()), nil
|
||||
}
|
||||
|
||||
// fingerprintPrefix is the fingerprint prefix added by ssh.FingerprintSHA256.
|
||||
const fingerprintPrefix = "SHA256:"
|
||||
|
||||
func maybeAddPrefix(fingerprint string) string {
|
||||
if !strings.HasPrefix(fingerprint, fingerprintPrefix) {
|
||||
return fingerprintPrefix + fingerprint
|
||||
}
|
||||
return fingerprint
|
||||
}
|
||||
|
||||
// EqualFingerprints checks if two finger prints are equal.
|
||||
func EqualFingerprints(a, b string) bool {
|
||||
return strings.EqualFold(maybeAddPrefix(a), maybeAddPrefix(b))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package sshutils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEqualFingerprints(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
a string
|
||||
b string
|
||||
check require.BoolAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "equal",
|
||||
a: "SHA256:fingerprint",
|
||||
b: "SHA256:fingerprint",
|
||||
check: require.True,
|
||||
},
|
||||
{
|
||||
name: "not equal",
|
||||
a: "SHA256:fingerprint",
|
||||
b: "SHA256:fingerprint2",
|
||||
check: require.False,
|
||||
},
|
||||
{
|
||||
name: "equal without prefix",
|
||||
a: "SHA256:fingerprint",
|
||||
b: "fingerprint",
|
||||
check: require.True,
|
||||
},
|
||||
{
|
||||
name: "equal fold",
|
||||
a: "FINGERPRINT",
|
||||
b: "SHA256:fingerprint",
|
||||
check: require.True,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.check(t, EqualFingerprints(test.a, test.b))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,7 @@ type AuthCommand struct {
|
||||
caType string
|
||||
streamTarfile bool
|
||||
identityWriter identityfile.ConfigWriter
|
||||
integration string
|
||||
|
||||
rotateGracePeriod time.Duration
|
||||
rotateType string
|
||||
@@ -116,6 +117,7 @@ func (a *AuthCommand) Initialize(app *kingpin.Application, config *servicecfg.Co
|
||||
a.authExport.Flag("type",
|
||||
fmt.Sprintf("export certificate type (%v)", strings.Join(allowedCertificateTypes, ", "))).
|
||||
EnumVar(&a.authType, allowedCertificateTypes...)
|
||||
a.authExport.Flag("integration", "Name of the integration. Only applies to \"github\" CAs.").StringVar(&a.integration)
|
||||
|
||||
a.authGenerate = auth.Command("gen", "Generate a new SSH keypair.").Hidden()
|
||||
a.authGenerate.Flag("pub-key", "path to the public key").Required().StringVar(&a.genPubPath)
|
||||
@@ -206,6 +208,7 @@ var allowedCertificateTypes = []string{
|
||||
"db-client-der",
|
||||
"openssh",
|
||||
"saml-idp",
|
||||
"github",
|
||||
}
|
||||
|
||||
// allowedCRLCertificateTypes list of certificate authorities types that can
|
||||
@@ -233,6 +236,7 @@ func (a *AuthCommand) ExportAuthorities(ctx context.Context, clt *authclient.Cli
|
||||
AuthType: a.authType,
|
||||
ExportAuthorityFingerprint: a.exportAuthorityFingerprint,
|
||||
UseCompatVersion: a.compatVersion == "1.0",
|
||||
Integration: a.integration,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user