Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 0 additions & 1 deletion .data/.file

This file was deleted.

2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,10 @@ git_dirty := $(shell git status -s)
protos := \
proto/private/server/journal/journal.proto \
proto/spire/common/common.proto \
proto/brokerapi/brokerapi.proto

api-protos := \
proto/brokerapi/brokerapi.proto

plugin-protos := \
proto/spire/common/plugin/plugin.proto
Expand Down
10 changes: 10 additions & 0 deletions cmd/spire-agent/cli/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type Config struct {
type agentConfig struct {
DataDir string `hcl:"data_dir"`
AdminSocketPath string `hcl:"admin_socket_path"`
BrokerSocketPath string `hcl:"broker_socket_path"`
InsecureBootstrap bool `hcl:"insecure_bootstrap"`
RebootstrapMode string `hcl:"rebootstrap_mode"`
RebootstrapDelay string `hcl:"rebootstrap_delay"`
Expand Down Expand Up @@ -491,6 +492,15 @@ func NewAgentConfig(c *Config, logOptions []log.Option, allowUnknownConfig bool)
}
ac.AdminBindAddress = adminAddr
}

if c.Agent.hasBrokerAddr() {
brokerAddr, err := c.Agent.getBrokerAddr()
if err != nil {
return nil, err
}
ac.BrokerBindAddress = brokerAddr
}

// Handle join token - read from file if specified
if c.Agent.JoinTokenFile != "" {
tokenBytes, err := os.ReadFile(c.Agent.JoinTokenFile)
Expand Down
35 changes: 35 additions & 0 deletions cmd/spire-agent/cli/run/run_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,30 @@ func (c *agentConfig) hasAdminAddr() bool {
return c.AdminSocketPath != ""
}

func (c *agentConfig) getBrokerAddr() (net.Addr, error) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I'm only supporting UDS, once the Broker API evolves we may allow serving it on TCP too.

socketPathAbs, err := filepath.Abs(c.SocketPath)
if err != nil {
return nil, fmt.Errorf("failed to get absolute path for socket_path: %w", err)
}
brokerSocketPathAbs, err := filepath.Abs(c.BrokerSocketPath)
if err != nil {
return nil, fmt.Errorf("failed to get absolute path for broker_socket_path: %w", err)
}

if strings.HasPrefix(brokerSocketPathAbs, filepath.Dir(socketPathAbs)+"/") {
return nil, errors.New("broker socket cannot be in the same directory or a subdirectory as that containing the Workload API socket")
}

return &net.UnixAddr{
Name: brokerSocketPathAbs,
Net: "unix",
}, nil
}

func (c *agentConfig) hasBrokerAddr() bool {
return c.BrokerSocketPath != ""
}

// validateOS performs posix specific validations of the agent config
func (c *agentConfig) validateOS() error {
if c.Experimental.NamedPipeName != "" {
Expand Down Expand Up @@ -88,5 +112,16 @@ func prepareEndpoints(c *agent.Config) error {
}
}

if c.BrokerBindAddress != nil {
// Create uds dir and parents if not exists
brokerDir := filepath.Dir(c.BrokerBindAddress.String())
if _, statErr := os.Stat(brokerDir); os.IsNotExist(statErr) {
c.Log.WithField("dir", brokerDir).Infof("Creating broker UDS directory")
if err := os.MkdirAll(brokerDir, 0755); err != nil {
return err
}
}
}

return nil
}
8 changes: 8 additions & 0 deletions cmd/spire-agent/cli/run/run_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ func (c *agentConfig) hasAdminAddr() bool {
return c.Experimental.AdminNamedPipeName != ""
}

func (c *agentConfig) getBrokerAddr() (net.Addr, error) {
return nil, errors.New("broker_socket_path is not supported in this platform")
}

func (c *agentConfig) hasBrokerAddr() bool {
return false
}

// validateOS performs windows specific validations of the agent config
func (c *agentConfig) validateOS() error {
if c.SocketPath != "" {
Expand Down
5 changes: 5 additions & 0 deletions conf/agent/agent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ agent {
socket_path ="/tmp/spire-agent/public/api.sock"
trust_bundle_path = "./conf/agent/dummy_root_ca.crt"
trust_domain = "example.org"

authorized_delegates = [
"spiffe://example.org/broker",
]
broker_socket_path = "/tmp/spire-agent/broker/api.sock"
}

plugins {
Expand Down
3 changes: 3 additions & 0 deletions conf/agent/agent_full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ agent {
# "spiffe://example.org/authorized_client1",
# ]

# broker_socket_path: Location to bind the SPIFFE Broker Endpoint.
# broker_socket_path = ""

# sds: Optional SDS configuration section.
# sds = {
# # default_svid_name: The TLS Certificate resource name to use for the default
Expand Down
19 changes: 19 additions & 0 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
admin_api "github.com/spiffe/spire/pkg/agent/api"
node_attestor "github.com/spiffe/spire/pkg/agent/attestor/node"
workload_attestor "github.com/spiffe/spire/pkg/agent/attestor/workload"
"github.com/spiffe/spire/pkg/agent/broker"
"github.com/spiffe/spire/pkg/agent/catalog"
"github.com/spiffe/spire/pkg/agent/endpoints"
"github.com/spiffe/spire/pkg/agent/manager"
Expand Down Expand Up @@ -255,6 +256,24 @@ func (a *Agent) Run(ctx context.Context) error {
tasks = append(tasks, adminEndpoints.ListenAndServe)
}

if a.c.BrokerBindAddress != nil {
brokerEndpoints, err := broker.New(&broker.Config{
BindAddr: a.c.BrokerBindAddress,
Manager: manager,
Log: a.c.Log,
Metrics: metrics,
Attestor: workloadAttestor,
TrustDomain: a.c.TrustDomain,
AuthorizedDelegates: a.c.AuthorizedDelegates,
SVIDSource: as,
BundleSource: manager.GetX509Bundle(),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure what's better here, us the attestation result as a bundle source or the one from the manager?

})
if err != nil {
return fmt.Errorf("failed to create broker endpoints: %w", err)
}
tasks = append(tasks, brokerEndpoints.ListenAndServe)
}

if a.c.LogReopener != nil {
tasks = append(tasks, a.c.LogReopener)
}
Expand Down
7 changes: 0 additions & 7 deletions pkg/agent/attestor/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ const (
roundRobinServiceConfig = `{ "loadBalancingConfig": [ { "round_robin": {} } ] }`
)

type AttestationResult struct {
SVID []*x509.Certificate
Key keymanager.Key
Bundle *spiffebundle.Bundle
Reattestable bool
}

type Attestor interface {
Attest(ctx context.Context) (*AttestationResult, error)
}
Expand Down
40 changes: 40 additions & 0 deletions pkg/agent/attestor/node/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package attestor

import (
"crypto/x509"
"fmt"

"github.com/spiffe/go-spiffe/v2/bundle/spiffebundle"
"github.com/spiffe/go-spiffe/v2/bundle/x509bundle"
"github.com/spiffe/go-spiffe/v2/spiffeid"
"github.com/spiffe/go-spiffe/v2/svid/x509svid"
"github.com/spiffe/spire/pkg/agent/plugin/keymanager"
)

// Allow AttestationResult to be used as go-spiffe SVID and bundle sources.
// TODO(arndt): Check whether the key of the agent is ok to be exposed to other parties.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is worth a discussion.

var (
_ x509svid.Source = (*AttestationResult)(nil)
_ x509bundle.Source = (*AttestationResult)(nil)
)

type AttestationResult struct {
SVID []*x509.Certificate
Key keymanager.Key
Bundle *spiffebundle.Bundle
Reattestable bool
}

func (ar *AttestationResult) GetX509SVID() (*x509svid.SVID, error) {
return &x509svid.SVID{
Certificates: ar.SVID,
PrivateKey: ar.Key,
}, nil
}

func (ar *AttestationResult) GetX509BundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*x509bundle.Bundle, error) {
if ar.Bundle.TrustDomain() != trustDomain {
return nil, fmt.Errorf("bundle for trust domain %q not found", trustDomain)
}
return ar.Bundle.X509Bundle(), nil
}
Loading
Loading