Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for federated mode #124

Merged
merged 9 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ The configuration file is an [HCL](https://github.com/hashicorp/hcl) formatted f
| `svid_bundle_file_name` | File name to be used to store the X.509 SVID Bundle in PEM format. | `"svid_bundle.pem"` |
| `jwt_svids` | An array with the audience and file name to store the JWT SVIDs. File is Base64-encoded string). | `[{jwt_audience="your-audience", jwt_svid_file_name="jwt_svid.token"}]` |
| `jwt_bundle_file_name` | File name to be used to store JWT Bundle in JSON format. | `"jwt_bundle.json"` |
| `include_federated_domains` | Include trust domains from federated servers in the CA bundle. | `true` |


### Configuration example
```
Expand Down
1 change: 1 addition & 0 deletions pkg/sidecar/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Config struct {
SvidBundleFileNameDeprecated string `hcl:"svidBundleFileName"`
RenewSignal string `hcl:"renew_signal"`
RenewSignalDeprecated string `hcl:"renewSignal"`
IncludeFederatedDomains bool `hcl:"include_federated_domains"`

// JWT configuration
JwtSvids []JwtConfig `hcl:"jwt_svids"`
Expand Down
13 changes: 13 additions & 0 deletions pkg/sidecar/sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,12 @@ func (s *Sidecar) dumpBundles(svidResponse *workloadapi.X509Context) error {
svidBundleFile := path.Join(s.config.CertDir, s.config.SvidBundleFileName)

certs := svid.Certificates

bundleSet, found := svidResponse.Bundles.Get(svid.ID.TrustDomain())
if !found {
return fmt.Errorf("no bundles found for %s trust domain", svid.ID.TrustDomain().String())
}

bundles := bundleSet.X509Authorities()
privateKey, err := x509.MarshalPKCS8PrivateKey(svid.PrivateKey)
if err != nil {
Expand All @@ -234,6 +236,17 @@ func (s *Sidecar) dumpBundles(svidResponse *workloadapi.X509Context) error {
certs = []*x509.Certificate{certs[0]}
}

// If using federated domains, add them to the CA bundle
if s.config.IncludeFederatedDomains {
bundleSets := svidResponse.Bundles.Bundles()
for _, bundle := range bundleSets {
// The bundle corresponding to svid.ID.TrustDomain is already stored
if bundle.TrustDomain().Name() != svid.ID.TrustDomain().Name() {
bundles = append(bundles, bundle.X509Authorities()...)
}
}
}

if err := writeCerts(svidFile, certs); err != nil {
return err
}
Expand Down
23 changes: 23 additions & 0 deletions pkg/sidecar/sidecar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func TestSidecar_RunDaemon(t *testing.T) {
domain1Inter := domain1CA.CreateCA()
domain1Bundle := domain1CA.Roots()

// Used for testing federated trust domains
domain2CA := spiffetest.NewCA(t)
domain2Bundle := domain2CA.Roots()

// Svid with intermediate
spiffeIDWithIntermediate, err := spiffeid.FromString("spiffe://example.test/workloadWithIntermediate")
require.NoError(t, err)
Expand Down Expand Up @@ -62,6 +66,12 @@ func TestSidecar_RunDaemon(t *testing.T) {
},
}

bundleWithFederatedDomains := domain1CA.Roots()
bundleWithFederatedDomains = append(bundleWithFederatedDomains, domain2Bundle[0:]...)
// Used to create an additional bundle when testing federated trust domains
federatedSpiffeID, err := spiffeid.FromString("spiffe://foo.test/server")
require.NoError(t, err)

tmpdir := t.TempDir()

log, _ := test.NewNullLogger()
Expand Down Expand Up @@ -90,6 +100,7 @@ func TestSidecar_RunDaemon(t *testing.T) {
bundle []*x509.Certificate
renewSignal string
intermediateInBundle bool
federatedDomains bool
}{
{
name: "svid with intermediate",
Expand Down Expand Up @@ -147,6 +158,17 @@ func TestSidecar_RunDaemon(t *testing.T) {
bundle: domain1Bundle,
renewSignal: "SIGHUP",
},
{
name: "svid with federated trust domains",
response: &workloadapi.X509Context{
Bundles: x509bundle.NewSet(x509bundle.FromX509Authorities(spiffeID.TrustDomain(), domain1CA.Roots()), x509bundle.FromX509Authorities(federatedSpiffeID.TrustDomain(), domain2CA.Roots())),
SVIDs: svid,
},
certs: svidChain,
key: svidKey,
bundle: bundleWithFederatedDomains,
federatedDomains: true,
},
}

svidFile := path.Join(tmpdir, config.SvidFileName)
Expand All @@ -160,6 +182,7 @@ func TestSidecar_RunDaemon(t *testing.T) {
t.Run(testCase.name, func(t *testing.T) {
sidecar.config.AddIntermediatesToBundle = testCase.intermediateInBundle
sidecar.config.RenewSignal = testCase.renewSignal
sidecar.config.IncludeFederatedDomains = testCase.federatedDomains
// Push response to start updating process
// updateMockChan <- testCase.response.ToProto(t)
w.OnX509ContextUpdate(testCase.response)
Expand Down