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 }