github.com/cilium/cilium@v1.16.2/pkg/auth/cell.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package auth
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/cilium/hive/cell"
    10  	"github.com/cilium/hive/job"
    11  	"github.com/cilium/stream"
    12  	"github.com/sirupsen/logrus"
    13  	"github.com/spf13/pflag"
    14  
    15  	"github.com/cilium/cilium/pkg/auth/spire"
    16  	"github.com/cilium/cilium/pkg/datapath/types"
    17  	"github.com/cilium/cilium/pkg/endpointmanager"
    18  	"github.com/cilium/cilium/pkg/identity/cache"
    19  	"github.com/cilium/cilium/pkg/maps/authmap"
    20  	nodeManager "github.com/cilium/cilium/pkg/node/manager"
    21  	"github.com/cilium/cilium/pkg/policy"
    22  	"github.com/cilium/cilium/pkg/signal"
    23  	"github.com/cilium/cilium/pkg/time"
    24  )
    25  
    26  // Cell provides AuthManager which is responsible for request authentication.
    27  // It does this by registering to "auth required" signals from the signal package
    28  // and reacting upon received signal events.
    29  // Actual authentication gets performed by an auth handler which is
    30  // responsible for the configured auth type on the corresponding policy.
    31  var Cell = cell.Module(
    32  	"auth",
    33  	"Authenticates requests as demanded by policy",
    34  
    35  	spire.Cell,
    36  
    37  	// The auth manager is the main entry point which gets registered to signal map and receives auth requests.
    38  	// In addition, it handles re-authentication and auth map garbage collection.
    39  	cell.Provide(registerAuthManager),
    40  	cell.ProvidePrivate(
    41  		// Null auth handler provides support for auth type "null" - which always succeeds.
    42  		newMutualAuthHandler,
    43  		// Always fail auth handler provides support for auth type "always-fail" - which always fails.
    44  		newAlwaysFailAuthHandler,
    45  	),
    46  	cell.Config(config{
    47  		MeshAuthEnabled:               true,
    48  		MeshAuthQueueSize:             1024,
    49  		MeshAuthGCInterval:            5 * time.Minute,
    50  		MeshAuthSignalBackoffDuration: 1 * time.Second, // this default is based on the default TCP retransmission timeout
    51  	}),
    52  	cell.Config(MutualAuthConfig{}),
    53  )
    54  
    55  type config struct {
    56  	MeshAuthEnabled               bool
    57  	MeshAuthQueueSize             int
    58  	MeshAuthGCInterval            time.Duration
    59  	MeshAuthSignalBackoffDuration time.Duration
    60  }
    61  
    62  func (r config) Flags(flags *pflag.FlagSet) {
    63  	flags.Bool("mesh-auth-enabled", r.MeshAuthEnabled, "Enable authentication processing & garbage collection (beta)")
    64  	flags.Int("mesh-auth-queue-size", r.MeshAuthQueueSize, "Queue size for the auth manager")
    65  	flags.Duration("mesh-auth-gc-interval", r.MeshAuthGCInterval, "Interval in which auth entries are attempted to be garbage collected")
    66  	flags.Duration("mesh-auth-signal-backoff-duration", r.MeshAuthSignalBackoffDuration, "Time to wait betweeen two authentication required signals in case of a cache mismatch")
    67  	flags.MarkHidden("mesh-auth-signal-backoff-duration")
    68  }
    69  
    70  type authManagerParams struct {
    71  	cell.In
    72  
    73  	Logger    logrus.FieldLogger
    74  	Lifecycle cell.Lifecycle
    75  	JobGroup  job.Group
    76  	Health    cell.Health
    77  
    78  	Config       config
    79  	AuthMap      authmap.Map
    80  	AuthHandlers []authHandler `group:"authHandlers"`
    81  
    82  	SignalManager   signal.SignalManager
    83  	NodeIDHandler   types.NodeIDHandler
    84  	IdentityChanges stream.Observable[cache.IdentityChange]
    85  	NodeManager     nodeManager.NodeManager
    86  	EndpointManager endpointmanager.EndpointManager
    87  	PolicyRepo      *policy.Repository
    88  }
    89  
    90  func registerAuthManager(params authManagerParams) (*AuthManager, error) {
    91  	if !params.Config.MeshAuthEnabled {
    92  		params.Logger.Info("Authentication processing is disabled")
    93  		return nil, nil
    94  	}
    95  
    96  	// Instantiate & wire auth components
    97  
    98  	mapWriter := newAuthMapWriter(params.Logger, params.AuthMap)
    99  	mapCache := newAuthMapCache(params.Logger, mapWriter)
   100  
   101  	mgr, err := newAuthManager(params.Logger, params.AuthHandlers, mapCache, params.NodeIDHandler, params.Config.MeshAuthSignalBackoffDuration)
   102  	if err != nil {
   103  		return nil, fmt.Errorf("failed to create auth manager: %w", err)
   104  	}
   105  
   106  	mapGC := newAuthMapGC(params.Logger, mapCache, params.NodeIDHandler, params.PolicyRepo)
   107  
   108  	// Register auth components to lifecycle hooks & jobs
   109  
   110  	params.Lifecycle.Append(cell.Hook{
   111  		OnStart: func(hookContext cell.HookContext) error {
   112  			if err := mapCache.restoreCache(); err != nil {
   113  				return fmt.Errorf("failed to restore auth map cache: %w", err)
   114  			}
   115  
   116  			return nil
   117  		},
   118  	})
   119  
   120  	if err := registerSignalAuthenticationJob(params.JobGroup, mgr, params.SignalManager, params.Config); err != nil {
   121  		return nil, fmt.Errorf("failed to register signal authentication job: %w", err)
   122  	}
   123  	registerReAuthenticationJob(params.JobGroup, mgr, params.AuthHandlers)
   124  	registerGCJobs(params.JobGroup, params.Lifecycle, mapGC, params.Config, params.NodeManager, params.EndpointManager, params.IdentityChanges)
   125  
   126  	return mgr, nil
   127  }
   128  
   129  func registerReAuthenticationJob(jobGroup job.Group, mgr *AuthManager, authHandlers []authHandler) {
   130  	for _, ah := range authHandlers {
   131  		if ah != nil && ah.subscribeToRotatedIdentities() != nil {
   132  			jobGroup.Add(job.Observer("auth re-authentication", mgr.handleCertificateRotationEvent, stream.FromChannel(ah.subscribeToRotatedIdentities())))
   133  		}
   134  	}
   135  }
   136  
   137  func registerSignalAuthenticationJob(jobGroup job.Group, mgr *AuthManager, sm signal.SignalManager, config config) error {
   138  	var signalChannel = make(chan signalAuthKey, config.MeshAuthQueueSize)
   139  
   140  	// RegisterHandler registers signalChannel with SignalManager, but flow of events
   141  	// starts later during the OnStart hook of the SignalManager
   142  	if err := sm.RegisterHandler(signal.ChannelHandler(signalChannel), signal.SignalAuthRequired); err != nil {
   143  		return fmt.Errorf("failed to set up signal channel for datapath authentication required events: %w", err)
   144  	}
   145  
   146  	jobGroup.Add(job.Observer("auth request-authentication", mgr.handleAuthRequest, stream.FromChannel(signalChannel)))
   147  
   148  	return nil
   149  }
   150  
   151  func registerGCJobs(jobGroup job.Group, lifecycle cell.Lifecycle, mapGC *authMapGarbageCollector, cfg config, nodeManager nodeManager.NodeManager, endpointManager endpointmanager.EndpointManager, identityChanges stream.Observable[cache.IdentityChange]) {
   152  	lifecycle.Append(cell.Hook{
   153  		OnStart: func(hookContext cell.HookContext) error {
   154  			mapGC.subscribeToNodeEvents(nodeManager)
   155  			mapGC.subscribeToEndpointEvents(endpointManager)
   156  			return nil
   157  		},
   158  		OnStop: func(hookContext cell.HookContext) error {
   159  			nodeManager.Unsubscribe(mapGC)
   160  			endpointManager.Unsubscribe(mapGC)
   161  			return nil
   162  		},
   163  	})
   164  
   165  	jobGroup.Add(job.Observer("auth gc-identity-events", mapGC.handleIdentityChange, identityChanges))
   166  	jobGroup.Add(job.Timer("auth gc-cleanup", mapGC.cleanup, cfg.MeshAuthGCInterval))
   167  }
   168  
   169  type authHandlerResult struct {
   170  	cell.Out
   171  
   172  	AuthHandler authHandler `group:"authHandlers"`
   173  }