Add SpiffeID for Consul server agents (#14485)

Co-authored-by: Eric Haberkorn <erichaberkorn@gmail.com>

By adding a SpiffeID for server agents, servers can now request a leaf
certificate from the Connect CA.

This new Spiffe ID has a key property: servers are identified by their
datacenter name and trust domain. All servers that share these
attributes will share a ServerURI.

The aim is to use these certificates to verify the server name of ANY
server in a Consul datacenter.
This commit is contained in:
Freddy 2022-09-06 17:58:13 -06:00 committed by GitHub
parent b800f7e175
commit a7f38384ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 247 additions and 79 deletions

View File

@ -24,6 +24,8 @@ var (
`^(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/]+)$`)
spiffeIDAgentRegexp = regexp.MustCompile(
`^(?:/ap/([^/]+))?/agent/client/dc/([^/]+)/id/([^/]+)$`)
spiffeIDServerRegexp = regexp.MustCompile(
`^/agent/server/dc/([^/]+)$`)
spiffeIDMeshGatewayRegexp = regexp.MustCompile(
`^(?:/ap/([^/]+))?/gateway/mesh/dc/([^/]+)$`)
)
@ -144,6 +146,19 @@ func ParseCertURI(input *url.URL) (CertURI, error) {
Partition: ap,
Datacenter: dc,
}, nil
} else if v := spiffeIDServerRegexp.FindStringSubmatch(path); v != nil {
dc := v[1]
if input.RawPath != "" {
var err error
if dc, err = url.PathUnescape(v[1]); err != nil {
return nil, fmt.Errorf("Invalid datacenter: %s", err)
}
}
return &SpiffeIDServer{
Host: input.Host,
Datacenter: dc,
}, nil
}
// Test for signing ID

View File

@ -0,0 +1,20 @@
package connect
import (
"fmt"
"net/url"
)
type SpiffeIDServer struct {
Host string
Datacenter string
}
// URI returns the *url.URL for this SPIFFE ID.
func (id SpiffeIDServer) URI() *url.URL {
var result url.URL
result.Scheme = "spiffe"
result.Host = id.Host
result.Path = fmt.Sprintf("/agent/server/dc/%s", id.Datacenter)
return &result
}

View File

@ -54,6 +54,12 @@ func (id SpiffeIDSigning) CanSign(cu CertURI) bool {
// worry about Unicode domains if we start allowing customisation beyond the
// built-in cluster ids.
return strings.ToLower(other.Host) == id.Host()
case *SpiffeIDServer:
// The host component of the service must be an exact match for now under
// ascii case folding (since hostnames are case-insensitive). Later we might
// worry about Unicode domains if we start allowing customisation beyond the
// built-in cluster ids.
return strings.ToLower(other.Host) == id.Host()
default:
return false
}

View File

@ -78,7 +78,7 @@ func TestSpiffeIDSigning_CanSign(t *testing.T) {
want: true,
},
{
name: "service - good midex case",
name: "service - good mixed case",
id: testSigning,
input: &SpiffeIDService{Host: strings.ToUpper(TestClusterID) + ".CONsuL", Namespace: "defAUlt", Datacenter: "dc1", Service: "WEB"},
want: true,
@ -102,7 +102,7 @@ func TestSpiffeIDSigning_CanSign(t *testing.T) {
want: true,
},
{
name: "mesh gateway - good midex case",
name: "mesh gateway - good mixed case",
id: testSigning,
input: &SpiffeIDMeshGateway{Host: strings.ToUpper(TestClusterID) + ".CONsuL", Datacenter: "dc1"},
want: true,
@ -119,6 +119,30 @@ func TestSpiffeIDSigning_CanSign(t *testing.T) {
input: &SpiffeIDMeshGateway{Host: TestClusterID + ".fake", Datacenter: "dc1"},
want: false,
},
{
name: "server - good",
id: testSigning,
input: &SpiffeIDServer{Host: TestClusterID + ".consul", Datacenter: "dc1"},
want: true,
},
{
name: "server - good mixed case",
id: testSigning,
input: &SpiffeIDServer{Host: strings.ToUpper(TestClusterID) + ".CONsuL", Datacenter: "dc1"},
want: true,
},
{
name: "server - different cluster",
id: testSigning,
input: &SpiffeIDServer{Host: "55555555-4444-3333-2222-111111111111.consul", Datacenter: "dc1"},
want: false,
},
{
name: "server - different TLD",
id: testSigning,
input: &SpiffeIDServer{Host: TestClusterID + ".fake", Datacenter: "dc1"},
want: false,
},
}
for _, tt := range tests {

View File

@ -19,109 +19,118 @@ func TestParseCertURIFromString(t *testing.T) {
ParseError string
}{
{
"invalid scheme",
"http://google.com/",
nil,
"scheme",
Name: "invalid scheme",
URI: "http://google.com/",
Struct: nil,
ParseError: "scheme",
},
{
"basic service ID",
"spiffe://1234.consul/ns/default/dc/dc01/svc/web",
&SpiffeIDService{
Name: "basic service ID",
URI: "spiffe://1234.consul/ns/default/dc/dc01/svc/web",
Struct: &SpiffeIDService{
Host: "1234.consul",
Partition: defaultEntMeta.PartitionOrDefault(),
Namespace: "default",
Datacenter: "dc01",
Service: "web",
},
"",
ParseError: "",
},
{
"basic service ID with partition",
"spiffe://1234.consul/ap/bizdev/ns/default/dc/dc01/svc/web",
&SpiffeIDService{
Name: "basic service ID with partition",
URI: "spiffe://1234.consul/ap/bizdev/ns/default/dc/dc01/svc/web",
Struct: &SpiffeIDService{
Host: "1234.consul",
Partition: "bizdev",
Namespace: "default",
Datacenter: "dc01",
Service: "web",
},
"",
ParseError: "",
},
{
"basic agent ID",
"spiffe://1234.consul/agent/client/dc/dc1/id/uuid",
&SpiffeIDAgent{
Name: "basic agent ID",
URI: "spiffe://1234.consul/agent/client/dc/dc1/id/uuid",
Struct: &SpiffeIDAgent{
Host: "1234.consul",
Partition: defaultEntMeta.PartitionOrDefault(),
Datacenter: "dc1",
Agent: "uuid",
},
"",
ParseError: "",
},
{
"basic agent ID with partition",
"spiffe://1234.consul/ap/bizdev/agent/client/dc/dc1/id/uuid",
&SpiffeIDAgent{
Name: "basic agent ID with partition",
URI: "spiffe://1234.consul/ap/bizdev/agent/client/dc/dc1/id/uuid",
Struct: &SpiffeIDAgent{
Host: "1234.consul",
Partition: "bizdev",
Datacenter: "dc1",
Agent: "uuid",
},
"",
ParseError: "",
},
{
"mesh-gateway with no partition",
"spiffe://1234.consul/gateway/mesh/dc/dc1",
&SpiffeIDMeshGateway{
Name: "basic server",
URI: "spiffe://1234.consul/agent/server/dc/dc1",
Struct: &SpiffeIDServer{
Host: "1234.consul",
Datacenter: "dc1",
},
ParseError: "",
},
{
Name: "mesh-gateway with no partition",
URI: "spiffe://1234.consul/gateway/mesh/dc/dc1",
Struct: &SpiffeIDMeshGateway{
Host: "1234.consul",
Partition: "default",
Datacenter: "dc1",
},
"",
ParseError: "",
},
{
"mesh-gateway with partition",
"spiffe://1234.consul/ap/bizdev/gateway/mesh/dc/dc1",
&SpiffeIDMeshGateway{
Name: "mesh-gateway with partition",
URI: "spiffe://1234.consul/ap/bizdev/gateway/mesh/dc/dc1",
Struct: &SpiffeIDMeshGateway{
Host: "1234.consul",
Partition: "bizdev",
Datacenter: "dc1",
},
"",
ParseError: "",
},
{
"service with URL-encoded values",
"spiffe://1234.consul/ns/foo%2Fbar/dc/bar%2Fbaz/svc/baz%2Fqux",
&SpiffeIDService{
Name: "service with URL-encoded values",
URI: "spiffe://1234.consul/ns/foo%2Fbar/dc/bar%2Fbaz/svc/baz%2Fqux",
Struct: &SpiffeIDService{
Host: "1234.consul",
Partition: defaultEntMeta.PartitionOrDefault(),
Namespace: "foo/bar",
Datacenter: "bar/baz",
Service: "baz/qux",
},
"",
ParseError: "",
},
{
"service with URL-encoded values with partition",
"spiffe://1234.consul/ap/biz%2Fdev/ns/foo%2Fbar/dc/bar%2Fbaz/svc/baz%2Fqux",
&SpiffeIDService{
Name: "service with URL-encoded values with partition",
URI: "spiffe://1234.consul/ap/biz%2Fdev/ns/foo%2Fbar/dc/bar%2Fbaz/svc/baz%2Fqux",
Struct: &SpiffeIDService{
Host: "1234.consul",
Partition: "biz/dev",
Namespace: "foo/bar",
Datacenter: "bar/baz",
Service: "baz/qux",
},
"",
ParseError: "",
},
{
"signing ID",
"spiffe://1234.consul",
&SpiffeIDSigning{
Name: "signing ID",
URI: "spiffe://1234.consul",
Struct: &SpiffeIDSigning{
ClusterID: "1234",
Domain: "consul",
},
"",
ParseError: "",
},
}
@ -139,3 +148,12 @@ func TestParseCertURIFromString(t *testing.T) {
})
}
}
func TestSpiffeIDServer_URI(t *testing.T) {
srv := &SpiffeIDServer{
Host: "1234.consul",
Datacenter: "dc1",
}
require.Equal(t, "spiffe://1234.consul/agent/server/dc/dc1", srv.URI().String())
}

View File

@ -1451,6 +1451,19 @@ func (c *CAManager) AuthorizeAndSignCertificate(csr *x509.CertificateRequest, au
return nil, connect.InvalidCSRError("SPIFFE ID in CSR from a different datacenter: %s, "+
"we are %s", v.Datacenter, dc)
}
case *connect.SpiffeIDServer:
// The authorizer passed in should have unlimited permissions.
if err := allow.ACLWriteAllowed(&authzContext); err != nil {
return nil, err
}
// Verify that the DC in the URI matches us.
// The request must have been issued by a local server.
dc := c.serverConf.Datacenter
if v.Datacenter != dc {
return nil, connect.InvalidCSRError("SPIFFE ID in CSR from a different datacenter: %s, "+
"we are %s", v.Datacenter, dc)
}
default:
return nil, connect.InvalidCSRError("SPIFFE ID in CSR must be a service or agent ID")
}
@ -1472,9 +1485,11 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne
if err != nil {
return nil, err
}
signingID := connect.SpiffeIDSigningForCluster(config.ClusterID)
serviceID, isService := spiffeID.(*connect.SpiffeIDService)
agentID, isAgent := spiffeID.(*connect.SpiffeIDAgent)
serverID, isServer := spiffeID.(*connect.SpiffeIDServer)
mgwID, isMeshGateway := spiffeID.(*connect.SpiffeIDMeshGateway)
var entMeta acl.EnterpriseMeta
@ -1493,6 +1508,12 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne
}
entMeta.Merge(mgwID.GetEnterpriseMeta())
case isServer:
if !signingID.CanSign(spiffeID) {
return nil, connect.InvalidCSRError("SPIFFE ID in CSR from a different trust domain: %s, "+
"we are %s", serverID.Host, signingID.Host())
}
entMeta.Normalize()
case isAgent:
// isAgent - if we support more ID types then this would need to be an else if
// here we are just automatically fixing the trust domain. For auto-encrypt and
@ -1519,7 +1540,7 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne
entMeta.Merge(agentID.GetEnterpriseMeta())
default:
return nil, connect.InvalidCSRError("SPIFFE ID in CSR must be a service, agent, or mesh gateway ID")
return nil, connect.InvalidCSRError("SPIFFE ID in CSR must be a service, agent, server, or mesh gateway ID")
}
commonCfg, err := config.GetCommonConfig()
@ -1608,6 +1629,8 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne
case isAgent:
reply.Agent = agentID.Agent
reply.AgentURI = cert.URIs[0].String()
case isServer:
reply.ServerURI = cert.URIs[0].String()
default:
return nil, errors.New("not possible")
}

View File

@ -1042,3 +1042,43 @@ func setupPrimaryCA(t *testing.T, client *vaultapi.Client, path string, rootPEM
require.NoError(t, err, "failed to set signed intermediate")
return lib.EnsureTrailingNewline(buf.String())
}
func TestCAManager_Sign_SpiffeIDServer(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
_, s1 := testServerWithConfig(t)
testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
codec := rpcClient(t, s1)
roots := structs.IndexedCARoots{}
retry.Run(t, func(r *retry.R) {
err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots)
require.NoError(r, err)
require.Len(r, roots.Roots, 1)
})
pk, _, err := connect.GeneratePrivateKey()
require.NoError(t, err)
// Request a leaf certificate for a server.
spiffeID := &connect.SpiffeIDServer{
Host: roots.TrustDomain,
Datacenter: "dc1",
}
csr, err := connect.CreateCSR(spiffeID, pk, nil, nil)
require.NoError(t, err)
req := structs.CASignRequest{CSR: csr}
cert := structs.IssuedCert{}
err = msgpackrpc.CallWithCodec(codec, "ConnectCA.Sign", &req, &cert)
require.NoError(t, err)
// Verify the chain of trust.
verifyLeafCert(t, roots.Roots[0], cert.CertPEM)
// Verify the Server's URI.
require.Equal(t, fmt.Sprintf("spiffe://%s/agent/server/dc/dc1", roots.TrustDomain), cert.ServerURI)
}

View File

@ -224,6 +224,10 @@ type IssuedCert struct {
// AgentURI is the cert URI value.
AgentURI string `json:",omitempty"`
// ServerURI is the URI value of a cert issued for a server agent.
// The same URI is shared by all servers in a Consul datacenter.
ServerURI string `json:",omitempty"`
// Kind is the kind of service for which the cert was issued.
Kind ServiceKind `json:",omitempty"`
// KindURI is the cert URI value.

View File

@ -93,6 +93,7 @@ func IssuedCertToStructsIssuedCert(s *IssuedCert, t *structs.IssuedCert) {
t.ServiceURI = s.ServiceURI
t.Agent = s.Agent
t.AgentURI = s.AgentURI
t.ServerURI = s.ServerURI
t.Kind = structs.ServiceKind(s.Kind)
t.KindURI = s.KindURI
t.ValidAfter = structs.TimeFromProto(s.ValidAfter)
@ -111,6 +112,7 @@ func IssuedCertFromStructsIssuedCert(t *structs.IssuedCert, s *IssuedCert) {
s.ServiceURI = t.ServiceURI
s.Agent = t.Agent
s.AgentURI = t.AgentURI
s.ServerURI = t.ServerURI
s.Kind = string(t.Kind)
s.KindURI = t.KindURI
s.ValidAfter = structs.TimeToProto(t.ValidAfter)

View File

@ -377,6 +377,9 @@ type IssuedCert struct {
Kind string `protobuf:"bytes,12,opt,name=Kind,proto3" json:"Kind,omitempty"`
// KindURI is the cert URI value.
KindURI string `protobuf:"bytes,13,opt,name=KindURI,proto3" json:"KindURI,omitempty"`
// ServerURI is the URI value of a cert issued for a server agent.
// The same URI is shared by all servers in a Consul datacenter.
ServerURI string `protobuf:"bytes,14,opt,name=ServerURI,proto3" json:"ServerURI,omitempty"`
// ValidAfter and ValidBefore are the validity periods for the
// certificate.
// mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto
@ -485,6 +488,13 @@ func (x *IssuedCert) GetKindURI() string {
return ""
}
func (x *IssuedCert) GetServerURI() string {
if x != nil {
return x.ServerURI
}
return ""
}
func (x *IssuedCert) GetValidAfter() *timestamppb.Timestamp {
if x != nil {
return x.ValidAfter
@ -579,7 +589,7 @@ var file_proto_pbconnect_connect_proto_rawDesc = []byte{
0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x09, 0x52,
0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xa9, 0x04, 0x0a, 0x0a, 0x49, 0x73, 0x73,
0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xc7, 0x04, 0x0a, 0x0a, 0x49, 0x73, 0x73,
0x75, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61,
0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53,
0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x43,
@ -596,42 +606,44 @@ var file_proto_pbconnect_connect_proto_rawDesc = []byte{
0x67, 0x65, 0x6e, 0x74, 0x55, 0x52, 0x49, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18,
0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x4b,
0x69, 0x6e, 0x64, 0x55, 0x52, 0x49, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4b, 0x69,
0x6e, 0x64, 0x55, 0x52, 0x49, 0x12, 0x3a, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66,
0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, 0x74, 0x65,
0x72, 0x12, 0x3c, 0x0a, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x52, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12,
0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74,
0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72,
0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72,
0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x09, 0x52, 0x61, 0x66,
0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68,
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x09, 0x52, 0x61, 0x66, 0x74, 0x49,
0x6e, 0x64, 0x65, 0x78, 0x42, 0x8a, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73,
0x6e, 0x64, 0x55, 0x52, 0x49, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55,
0x52, 0x49, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x55, 0x52, 0x49, 0x12, 0x3a, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, 0x74, 0x65,
0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12,
0x3c, 0x0a, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x09,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x52, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x58, 0x0a,
0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18,
0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72,
0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72,
0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x09, 0x52, 0x61, 0x66, 0x74, 0x49,
0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x42, 0x0c,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x70, 0x62, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xa2, 0x02, 0x04, 0x48, 0x43,
0x49, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43,
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5c, 0x47,
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x61,
0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x09, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x42, 0x8a, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x42, 0x0c, 0x43, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
0x70, 0x62, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x43,
0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e,
0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x5c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5c, 0x47, 0x50, 0x42,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -165,6 +165,10 @@ message IssuedCert {
// KindURI is the cert URI value.
string KindURI = 13;
// ServerURI is the URI value of a cert issued for a server agent.
// The same URI is shared by all servers in a Consul datacenter.
string ServerURI = 14;
// ValidAfter and ValidBefore are the validity periods for the
// certificate.
// mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto