Skip to content

Commit

Permalink
Add support for bundle endpoint profile in trust zones
Browse files Browse the repository at this point in the history
This is an enum in the TrustZone message, and the https_web and
https_spiffe profiles are currently supported. The default continues to
be https_spiffe, but plugins may choose to change this.

Fixes: #71
  • Loading branch information
markgoddard committed Dec 9, 2024
1 parent 71b78f0 commit 622491a
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 29 deletions.
16 changes: 9 additions & 7 deletions cmd/cofidectl/cmd/trustzone/trustzone.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"slices"
"strconv"

cmdcontext "github.com/cofide/cofidectl/pkg/cmd/context"
"github.com/cofide/cofidectl/cmd/cofidectl/cmd/trustzone/helm"
cmdcontext "github.com/cofide/cofidectl/pkg/cmd/context"
"github.com/manifoldco/promptui"

trust_provider_proto "github.com/cofide/cofide-api-sdk/gen/go/proto/trust_provider/v1alpha1"
Expand Down Expand Up @@ -140,13 +140,15 @@ func (c *TrustZoneCommand) GetAddCommand() *cobra.Command {
return err
}

bundleEndpointProfile := trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_HTTPS_SPIFFE
newTrustZone := &trust_zone_proto.TrustZone{
Name: opts.name,
TrustDomain: opts.trustDomain,
KubernetesCluster: &opts.kubernetesCluster,
KubernetesContext: &opts.context,
TrustProvider: &trust_provider_proto.TrustProvider{Kind: &opts.profile},
JwtIssuer: &opts.jwtIssuer,
Name: opts.name,
TrustDomain: opts.trustDomain,
KubernetesCluster: &opts.kubernetesCluster,
KubernetesContext: &opts.context,
TrustProvider: &trust_provider_proto.TrustProvider{Kind: &opts.profile},
JwtIssuer: &opts.jwtIssuer,
BundleEndpointProfile: &bundleEndpointProfile,
}

_, err = ds.AddTrustZone(newTrustZone)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.7
require (
buf.build/go/protoyaml v0.2.0
cuelang.org/go v0.10.1
github.com/cofide/cofide-api-sdk v0.3.1-0.20241206100419-25af9d3bc0c5
github.com/cofide/cofide-api-sdk v0.3.1-0.20241209124727-c60451a4ba77
github.com/fatih/color v1.18.0
github.com/gofrs/flock v0.12.1
github.com/google/go-cmp v0.6.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
github.com/cofide/cofide-api-sdk v0.3.1-0.20241206100419-25af9d3bc0c5 h1:o0xy1hnXWVEoHyqrLm+sU5lXyw/Rcm3A+1w884v8vqI=
github.com/cofide/cofide-api-sdk v0.3.1-0.20241206100419-25af9d3bc0c5/go.mod h1:yKMfhL3qCIVJcKvgZsPZC1o60/8co6/0NsCaJtrUoFY=
github.com/cofide/cofide-api-sdk v0.3.1-0.20241209124727-c60451a4ba77 h1:Uq2GS7GLwqjGWnnEEi/dfoc0+D9/yhmjEwNqLd7e8J0=
github.com/cofide/cofide-api-sdk v0.3.1-0.20241209124727-c60451a4ba77/go.mod h1:yKMfhL3qCIVJcKvgZsPZC1o60/8co6/0NsCaJtrUoFY=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
Expand Down
3 changes: 3 additions & 0 deletions internal/pkg/config/schema.cue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
attestation_policies: [...#APBinding]
jwt_issuer?: string
extra_helm_values?: #HelmValues
bundle_endpoint_profile?: #BundleEndpointProfile
}

#TrustProvider: {
Expand Down Expand Up @@ -58,6 +59,8 @@
[string]: _
}

#BundleEndpointProfile: string & =~"BUNDLE_ENDPOINT_PROFILE_.*"

#PluginConfig: {
[string]: _
}
Expand Down
2 changes: 2 additions & 0 deletions internal/pkg/config/testdata/config/full.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ trust_zones:
create: true
spire-server:
logLevel: INFO
bundle_endpoint_profile: BUNDLE_ENDPOINT_PROFILE_HTTPS_SPIFFE
- name: tz2
trust_domain: td2
kubernetes_cluster: local2
Expand All @@ -39,6 +40,7 @@ trust_zones:
federates_with:
- tz1
jwt_issuer: https://tz2.example.com
bundle_endpoint_profile: BUNDLE_ENDPOINT_PROFILE_HTTPS_WEB
attestation_policies:
- name: ap1
kubernetes:
Expand Down
38 changes: 27 additions & 11 deletions internal/pkg/federation/federation.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
trust_zone_proto "github.com/cofide/cofide-api-sdk/gen/go/proto/trust_zone/v1alpha1"
)

const (
bundleEndpointProfileHTTPSWeb = "https_web"
bundleEndpointProfileHTTPSSPIFFE = "https_spiffe"
)

type Federation struct {
destTrustZone *trust_zone_proto.TrustZone
}
Expand All @@ -19,16 +24,27 @@ func NewFederation(trustZone *trust_zone_proto.TrustZone) *Federation {
}
}

func (fed *Federation) GetHelmConfig() map[string]interface{} {
clusterFederatedTrustDomain := map[string]interface{}{
"bundleEndpointURL": fed.destTrustZone.GetBundleEndpointUrl(),
"bundleEndpointProfile": map[string]interface{}{
"type": "https_spiffe",
"endpointSPIFFEID": fmt.Sprintf("spiffe://%s/spire/server", fed.destTrustZone.TrustDomain),
},
"trustDomain": fed.destTrustZone.TrustDomain,
"trustDomainBundle": fed.destTrustZone.GetBundle(),
func (fed *Federation) GetHelmConfig() (map[string]interface{}, error) {
switch fed.destTrustZone.GetBundleEndpointProfile() {
case trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_HTTPS_SPIFFE:
return map[string]interface{}{
"bundleEndpointURL": fed.destTrustZone.GetBundleEndpointUrl(),
"bundleEndpointProfile": map[string]interface{}{
"type": bundleEndpointProfileHTTPSSPIFFE,
"endpointSPIFFEID": fmt.Sprintf("spiffe://%s/spire/server", fed.destTrustZone.TrustDomain),
},
"trustDomain": fed.destTrustZone.TrustDomain,
"trustDomainBundle": fed.destTrustZone.GetBundle(),
}, nil
case trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_HTTPS_WEB:
return map[string]interface{}{
"bundleEndpointURL": fed.destTrustZone.GetBundleEndpointUrl(),
"bundleEndpointProfile": map[string]interface{}{
"type": bundleEndpointProfileHTTPSWeb,
},
"trustDomain": fed.destTrustZone.TrustDomain,
}, nil
default:
return nil, fmt.Errorf("unexpected bundle endpoint profile %d", fed.destTrustZone.GetBundleEndpointProfile())
}

return clusterFederatedTrustDomain
}
11 changes: 7 additions & 4 deletions internal/pkg/test/fixtures/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var trustZoneFixtures map[string]*trust_zone_proto.TrustZone = map[string]*trust
}
return value
}(),
BundleEndpointProfile: trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_HTTPS_SPIFFE.Enum(),
},
"tz2": {
Name: "tz2",
Expand All @@ -82,7 +83,8 @@ var trustZoneFixtures map[string]*trust_zone_proto.TrustZone = map[string]*trust
FederatesWith: []string{"tz1"},
},
},
JwtIssuer: StringPtr("https://tz2.example.com"),
JwtIssuer: StringPtr("https://tz2.example.com"),
BundleEndpointProfile: trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_HTTPS_WEB.Enum(),
},
// tz3 has no federations or bound attestation policies.
"tz3": {
Expand All @@ -93,9 +95,10 @@ var trustZoneFixtures map[string]*trust_zone_proto.TrustZone = map[string]*trust
TrustProvider: &trust_provider_proto.TrustProvider{
Kind: StringPtr("kubernetes"),
},
BundleEndpointUrl: StringPtr("127.0.0.3"),
Federations: []*federation_proto.Federation{},
AttestationPolicies: []*ap_binding_proto.APBinding{},
BundleEndpointUrl: StringPtr("127.0.0.3"),
Federations: []*federation_proto.Federation{},
AttestationPolicies: []*ap_binding_proto.APBinding{},
BundleEndpointProfile: trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_HTTPS_SPIFFE.Enum(),
},
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/provider/helm/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ func (g *HelmValuesGenerator) GenerateValues() (map[string]any, error) {
return nil, fmt.Errorf("failed to get clusterFederatedTrustDomains map from identities: %w", err)
}

cftd[fed.To] = federation.NewFederation(tz).GetHelmConfig()
cftd[fed.To], err = federation.NewFederation(tz).GetHelmConfig()
if err != nil {
return nil, err
}
}
}
}
Expand Down
46 changes: 43 additions & 3 deletions pkg/provider/helm/values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,10 @@ func TestHelmValuesGenerator_GenerateValues_success(t *testing.T) {
"clusterFederatedTrustDomains": Values{
"tz2": Values{
"bundleEndpointProfile": Values{
"endpointSPIFFEID": "spiffe://td2/spire/server",
"type": "https_spiffe",
"type": "https_web",
},
"bundleEndpointURL": "127.0.0.2",
"trustDomain": "td2",
"trustDomainBundle": "",
},
},
"clusterSPIFFEIDs": Values{
Expand Down Expand Up @@ -440,6 +438,48 @@ func TestHelmValuesGenerator_GenerateValues_failure(t *testing.T) {
}
}

func TestHelmValuesGenerator_GenerateValues_federationFailure(t *testing.T) {
tests := []struct {
name string
destTrustZone *trust_zone_proto.TrustZone
wantErrString string
}{
{
name: "nil bundle endpoint profile",
destTrustZone: func() *trust_zone_proto.TrustZone {
tz := fixtures.TrustZone("tz2")
tz.BundleEndpointProfile = nil
return tz
}(),
wantErrString: "unexpected bundle endpoint profile 0",
},
{
name: "unspecified bundle endpoint profile",
destTrustZone: func() *trust_zone_proto.TrustZone {
tz := fixtures.TrustZone("tz2")
tz.BundleEndpointProfile = trust_zone_proto.BundleEndpointProfile_BUNDLE_ENDPOINT_PROFILE_UNSPECIFIED.Enum()
return tz
}(),
wantErrString: "unexpected bundle endpoint profile 0",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := defaultConfig()
cfg.TrustZones[1] = tt.destTrustZone
source := newFakeDataSource(t, cfg)
g := &HelmValuesGenerator{
source: source,
trustZone: cfg.TrustZones[0],
values: nil,
}
_, err := g.GenerateValues()
require.Error(t, err)
assert.ErrorContains(t, err, tt.wantErrString)
})
}
}

func TestGetOrCreateNestedMap(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit 622491a

Please sign in to comment.