-
Notifications
You must be signed in to change notification settings - Fork 99
/
Copy pathserver-config.go
694 lines (579 loc) · 19.7 KB
/
server-config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
// Copyright 2023 - MinIO, Inc. All rights reserved.
// Use of this source code is governed by the AGPLv3
// license that can be found in the LICENSE file.
package edge
import (
"context"
"errors"
"time"
"github.com/gophercloud/gophercloud"
"github.com/minio/kes-go"
"github.com/minio/kes/internal/keystore/aws"
"github.com/minio/kes/internal/keystore/azure"
"github.com/minio/kes/internal/keystore/fortanix"
"github.com/minio/kes/internal/keystore/fs"
"github.com/minio/kes/internal/keystore/gcp"
"github.com/minio/kes/internal/keystore/gemalto"
kesstore "github.com/minio/kes/internal/keystore/kes"
"github.com/minio/kes/internal/keystore/openstack"
"github.com/minio/kes/internal/keystore/vault"
"github.com/minio/kes/kv"
)
// ServerConfig is a structure that holds configuration
// for a KES edge server.
type ServerConfig struct {
// Addr is the network interface address
// and optional port the KES server will
// listen on and accept HTTP requests.
//
// If only a port number is specified,
// e.g. ":7373", the KES server listens
// on all available network interfaces.
//
// When a specific IP address is specified,
// e.g. "127.0.0.1:7373", then KES server
// listens on only this specific network
// interface.
Addr string
// Admin is the KES server admin identity.
Admin kes.Identity
// TLS contains the KES server TLS configuration.
TLS *TLSConfig
// Cache contains the KES server cache configuration.
Cache *CacheConfig
// Log contains the KES server logging configuration.
Log *LogConfig
API *APIConfig
// Policies contains the KES server policy definitions
// and statical identity assignments.
Policies map[string]Policy
// Keys contains pre-defined keys that the KES server will
// either create, or expect to exist, before accepting requests.
Keys []Key
// KeyStore contains the KES server keystore configuration.
// The KeyStore manages the keys used by the KES server for
// encryption and decryption.
KeyStore KeyStore
_ [0]int // force usage of struct composite literals with field names
}
// TLSConfig is a structure that holds the TLS configuration
// for a KES server.
type TLSConfig struct {
// PrivateKey is the path to the KES server's TLS private key.
PrivateKey string
// Certificate is the path to the KES server's TLS certificate.
Certificate string
// Password is an optional password to decrypt the KES server's
// private key.
Password string
// CAPath is an optional path to a X.509 certificate or directory
// containing X.509 certificates that the KES server uses, in
// addition to the system root certificates, as authorities when
// verify client certificates.
//
// If empty, the KES server will only use the system root
// certificates.
CAPath string
// Proxies contains a list of TLS proxy identities.
// The KES identity of any TLS/HTTPS proxy sitting directly
// in-front of KES has to be included in this list. A KES
// server will only accept forwarded client requests from
// proxies listed here.
Proxies []kes.Identity
// ForwardCertHeader is the HTTP header key used by any
// TLS / HTTPS proxy to forward the actual client certificate
// to KES.
ForwardCertHeader string
_ [0]int
}
// CacheConfig is a structure that holds the Cache configuration
// for a KES server.
type CacheConfig struct {
// Expiry is the time period after which any cache entries in
// the key cache are discarded. It determines how often the KES
// server has to fetch a secret key from the KMS backend.
Expiry time.Duration
// ExpiryUnused is the time period after which all unused
// cache entries in the key cache are discarded. It determines
// how often "not frequently" used secret keys must be fetched from
// the KMS backend.
ExpiryUnused time.Duration
// ExpiryOffline is the time period after which any cache
// entries in the offline cache are discarded.
//
// It determines how long the KES server can serve stateless
// requests when the keystore has become unavailable -
// e.g. due to a network outage.
//
// ExpiryOffline is only used while the keystore backend is not
// available. As long as the keystore is available, the regular
// cache expiry periods apply.
ExpiryOffline time.Duration
_ [0]int
}
// LogConfig is a structure that holds the logging configuration
// for a KES server.
type LogConfig struct {
// Error determines whether the KES server logs error events to STDERR.
// It does not en/disable error logging in general.
Error bool
// Audit determines whether the KES server logs audit events to STDOUT.
// It does not en/disable audit logging in general.
Audit bool
_ [0]int
}
// APIConfig is a structure that holds the API configuration
// for a KES server.
type APIConfig struct {
// Paths contains a set of API paths and there
// API configuration.
Paths map[string]APIPathConfig
_ [0]int
}
// APIPathConfig is a structure that holds the API configuration
// for one particular KES API.
type APIPathConfig struct {
// Timeout is the duration after which the API response
// with a HTTP timeout error response. If Timeout is
// zero the API default is used.
Timeout time.Duration
// InsecureSkipAuth controls whether the API verifies
// client identities. If InsecureSkipAuth is true,
// the API accepts requests from arbitrary identities.
// In this mode, the API can be used by anyone who can
// communicate to the KES server over HTTPS.
// This should only be set for testing or in certain
// cases for APIs that don't expose sensitive information,
// like metrics.
InsecureSkipAuth bool
_ [0]int
}
// Policy is a structure defining a KES policy.
//
// Any request issued by a KES identity is validated
// by the associated allow and deny patterns. A
// request is accepted if and only if no deny pattern
// and at least one allow pattern matches the request.
type Policy struct {
// Allow is the list of API path patterns
// that are explicitly allowed.
Allow []string
// Deny is the list of API path patterns
// that are explicitly denied.
Deny []string
// Identities is a list of KES identities
// that are assigned to this policy.
//
// It must not contain the admin or any
// TLS proxy identity.
Identities []kes.Identity
_ [0]int
}
// Key is a structure defining a cryptographic key
// that the KES server will create or ensure exists
// before startup.
type Key struct {
// Name is the name of the cryptographic key.
Name string
_ [0]int
}
// KeyStore is a KES keystore configuration.
//
// Concrete instances implement Connect to return
// a connection to a concrete keystore.
type KeyStore interface {
// Connect establishes and returns a new connection
// to the keystore.
Connect(ctx context.Context) (kv.Store[string, []byte], error)
}
// FSKeyStore is a structure containing the configuration
// for a simple filesystem keystore.
//
// A FSKeyStore should only be used when testing a KES server.
type FSKeyStore struct {
// Path is the path to the directory that
// contains the keys.
//
// If the directory does not exist, it
// will be created.
Path string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs in a path on the filesystem.
func (s *FSKeyStore) Connect(context.Context) (kv.Store[string, []byte], error) {
return fs.NewStore(s.Path)
}
// KESKeyStore is a structure containing the configuration
// for using a KES server/cluster as key store.
type KESKeyStore struct {
// Endpoints is a set of KES server endpoints.
//
// If multiple endpoints are provided, the requests
// will be automatically balanced across them.
Endpoints []string
// Enclave is an optional enclave name. If empty,
// the default enclave name will be used.
Enclave string
// CertificateFile is a path to a mTLS client
// certificate file used to authenticate to
// the KES server.
CertificateFile string
// PrivateKeyFile is a path to a mTLS private
// key used to authenticate to the KES server.
PrivateKeyFile string
// CAPath is an optional path to the root
// CA certificate(s) for verifying the TLS
// certificate of the KES server.
//
// If empty, the OS default root CA set is
// used.
CAPath string
}
// Connect returns a kv.Store that stores key-value pairs on a KES server.
func (s *KESKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
return kesstore.Connect(ctx, &kesstore.Config{
Endpoints: s.Endpoints,
Enclave: s.Enclave,
Certificate: s.CertificateFile,
PrivateKey: s.PrivateKeyFile,
CAPath: s.CAPath,
})
}
// VaultKeyStore is a structure containing the configuration
// for Hashicorp Vault.
type VaultKeyStore struct {
// Endpoint is the Hashicorp Vault endpoint.
Endpoint string
// Namespace is an optional Hashicorp Vault namespace.
// An empty namespace means no particular namespace
// is used.
Namespace string
// APIVersion is the API version of the Hashicorp Vault
// K/V engine. Valid values are: "v1" and "v2".
// If empty, defaults to "v1".
APIVersion string
// Engine is the Hashicorp Vault K/V engine path.
// If empty, defaults to "kv".
Engine string
// Prefix is an optional prefix / directory within the
// K/V engine.
// If empty, keys will be stored at the K/V engine top
// level.
Prefix string
// AppRole contains the Vault AppRole authentication
// method credentials.
AppRole *VaultAppRoleAuth
// Kubernetes contains the Vault Kubernetes authentication
// method credentials.
Kubernetes *VaultKubernetesAuth
// PrivateKey is an optional path to a
// TLS private key file containing a
// TLS private key for mTLS authentication.
//
// If empty, mTLS authentication is disabled.
PrivateKey string
// Certificate is an optional path to a
// TLS certificate file containing a
// TLS certificate for mTLS authentication.
//
// If empty, mTLS authentication is disabled.
Certificate string
// CAPath is an optional path to the root
// CA certificate(s) for verifying the TLS
// certificate of the Hashicorp Vault server.
//
// If empty, the OS default root CA set is
// used.
CAPath string
// StatusPing controls how often to Vault health status
// is checked.
// If not set, defaults to 10s.
StatusPing time.Duration
_ [0]int
}
// VaultAppRoleAuth is a structure containing the configuration
// for the Hashicorp Vault AppRole authentication method.
type VaultAppRoleAuth struct {
// AppRoleEngine is the AppRole authentication engine path.
// If empty, defaults to "approle".
Engine string
// AppRoleID is the AppRole access ID for authenticating
// to Hashicorp Vault via the AppRole method.
ID string
// AppRoleSecret is the AppRole access secret for authenticating
// to Hashicorp Vault via the AppRole method.
Secret string
}
// VaultKubernetesAuth is a structure containing the configuration
// for the Hashicorp Vault Kubernetes authentication method.
type VaultKubernetesAuth struct {
// KubernetesEngine is the Kubernetes authentication engine path.
// If empty, defaults to "kubernetes".
Engine string
// KubernetesRole is the login role for authenticating via the
// kubernetes authentication method.
Role string
// KubernetesJWT is either the JWT or a path to a file containing
// the JWT for for authenticating via the kubernetes authentication
// method.
JWT string
}
// Connect returns a kv.Store that stores key-value pairs on a Hashicorp Vault server.
func (s *VaultKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
if s.AppRole == nil && s.Kubernetes == nil {
return nil, errors.New("edge: failed to connect to hashicorp vault: no authentication method specified")
}
if s.AppRole != nil && s.Kubernetes != nil {
return nil, errors.New("edge: failed to connect to hashicorp vault: more than one authentication method specified")
}
c := &vault.Config{
Endpoint: s.Endpoint,
Engine: s.Engine,
APIVersion: s.APIVersion,
Namespace: s.Namespace,
Prefix: s.Prefix,
PrivateKey: s.PrivateKey,
Certificate: s.Certificate,
CAPath: s.CAPath,
StatusPingAfter: s.StatusPing,
}
if s.AppRole != nil {
c.AppRole = vault.AppRole{
Engine: s.AppRole.Engine,
ID: s.AppRole.ID,
Secret: s.AppRole.Secret,
}
}
if s.Kubernetes != nil {
c.K8S = vault.Kubernetes{
Engine: s.Kubernetes.Engine,
Role: s.Kubernetes.Role,
JWT: s.Kubernetes.JWT,
}
}
return vault.Connect(ctx, c)
}
// FortanixKeyStore is a structure containing the
// configuration for Fortanix SDKMS.
type FortanixKeyStore struct {
// Endpoint is the endpoint of the Fortanix KMS.
Endpoint string
// GroupID is the ID of the access control group.
GroupID string
// APIKey is the API key for authenticating to
// the Fortanix KMS.
APIKey string
// CAPath is an optional path to the root
// CA certificate(s) for verifying the TLS
// certificate of the Hashicorp Vault server.
//
// If empty, the OS default root CA set is
// used.
CAPath string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs on a Fortanix SDKMS server.
func (s *FortanixKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
return fortanix.Connect(ctx, &fortanix.Config{
Endpoint: s.Endpoint,
GroupID: s.GroupID,
APIKey: fortanix.APIKey(s.APIKey),
CAPath: s.CAPath,
})
}
// KeySecureKeyStore is a structure containing the
// configuration for Gemalto KeySecure / Thales
// CipherTrust Manager.
type KeySecureKeyStore struct {
// Endpoint is the endpoint to the KeySecure server.
Endpoint string
// Token is the refresh authentication token to
// access the KeySecure server.
Token string
// Domain is the isolated namespace within the
// KeySecure server. If empty, defaults to the
// top-level / root domain.
Domain string
// CAPath is an optional path to the root
// CA certificate(s) for verifying the TLS
// certificate of the KeySecure server.
//
// If empty, the OS default root CA set is
// used.
CAPath string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs on a Gemalto KeySecure instance.
func (s *KeySecureKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
return gemalto.Connect(ctx, &gemalto.Config{
Endpoint: s.Endpoint,
CAPath: s.CAPath,
Login: gemalto.Credentials{
Token: s.Token,
Domain: s.Domain,
},
})
}
// GCPSecretManagerKeyStore is a structure containing the
// configuration for GCP SecretManager.
type GCPSecretManagerKeyStore struct {
// ProjectID is the GCP project ID.
ProjectID string
// Endpoint is the GCP project ID. If empty,
// defaults to:
// secretmanager.googleapis.com:443
Endpoint string
// Scopes are GCP OAuth2 scopes for accessing
// GCP APIs. If empty, defaults to the GCP
// default scopes.
Scopes []string
// ClientEmail is the Client email of the
// GCP service account used to access the
// SecretManager.
ClientEmail string
// ClientID is the Client ID of the GCP
// service account used to access the
// SecretManager.
ClientID string
// KeyID is the private key ID of the GCP
// service account used to access the
// SecretManager.
KeyID string
// Key is the private key of the GCP
// service account used to access the
// SecretManager.
Key string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs on GCP SecretManager.
func (s *GCPSecretManagerKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
return gcp.Connect(ctx, &gcp.Config{
Endpoint: s.Endpoint,
ProjectID: s.ProjectID,
Scopes: s.Scopes,
Credentials: gcp.Credentials{
ClientID: s.ClientID,
Client: s.ClientEmail,
KeyID: s.KeyID,
Key: s.Key,
},
})
}
// AWSSecretsManagerKeyStore is a structure containing the
// configuration for AWS SecretsManager.
type AWSSecretsManagerKeyStore struct {
// Endpoint is the AWS SecretsManager endpoint.
// AWS SecretsManager endpoints have the following
// schema:
// secrestmanager[-fips].<region>.amanzonaws.com
Endpoint string
// Region is the AWS region the SecretsManager is
// located.
Region string
// KMSKey is the AWS-KMS key ID (CMK-ID) used to
// to en/decrypt secrets managed by the SecretsManager.
// If empty, the default AWS KMS key is used.
KMSKey string
// AccessKey is the access key for authenticating to AWS.
AccessKey string
// SecretKey is the secret key for authenticating to AWS.
SecretKey string
// SessionToken is an optional session token for authenticating
// to AWS.
SessionToken string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs on AWS SecretsManager.
func (s *AWSSecretsManagerKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
return aws.Connect(ctx, &aws.Config{
Addr: s.Endpoint,
Region: s.Region,
KMSKeyID: s.KMSKey,
Login: aws.Credentials{
AccessKey: s.AccessKey,
SecretKey: s.SecretKey,
SessionToken: s.SessionToken,
},
})
}
// AzureKeyVaultKeyStore is a structure containing the
// configuration for Azure KeyVault.
type AzureKeyVaultKeyStore struct {
// Endpoint is the Azure KeyVault endpoint.
Endpoint string
// TenantID is the ID of the Azure KeyVault tenant.
TenantID string
// ClientID is the ID of the client accessing
// Azure KeyVault.
ClientID string
// ClientSecret is the client secret accessing the
// Azure KeyVault.
ClientSecret string
// ManagedIdentityClientID is the client ID of the
// Azure managed identity that access the KeyVault.
ManagedIdentityClientID string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs on Azure KeyVault.
func (s *AzureKeyVaultKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
if (s.TenantID != "" || s.ClientID != "" || s.ClientSecret != "") && s.ManagedIdentityClientID != "" {
return nil, errors.New("edge: failed to connect to Azure KeyVault: more than one authentication method specified")
}
switch {
case s.TenantID != "" || s.ClientID != "" || s.ClientSecret != "":
creds := azure.Credentials{
TenantID: s.TenantID,
ClientID: s.ClientID,
Secret: s.ClientSecret,
}
return azure.ConnectWithCredentials(ctx, s.Endpoint, creds)
case s.ManagedIdentityClientID != "":
creds := azure.ManagedIdentity{
ClientID: s.ManagedIdentityClientID,
}
return azure.ConnectWithIdentity(ctx, s.Endpoint, creds)
default:
return nil, errors.New("edge: failed to connect to Azure KeyVault: no authentication method specified")
}
}
// OpenStackBarbicanKeyStore is a structure containing the
// configuration for OpenStack Barbican
type OpenStackBarbicanKeyStore struct {
// OpenStack Auth Url
AuthUrl string
// The Domain of the user.
UserDomain string
// The user name. If you do not provide a user name and password, you must provide a token.
Username string
// The password for the user.
Password string
// The project name. Both the Project ID and Project Name are optional.
ProjectName string
// URL of the Barbican instance to connect to
BarbicanUrl string
// ServiceName [optional] is the service name for the client (e.g., "nova") as it
// appears in the service catalog. Services can have the same Type but a
// different Name, which is why both Type and Name are sometimes needed.
ServiceName string
// Region [required] is the geographic region in which the endpoint resides,
// generally specifying which datacenter should house your resources.
// Required only for services that span multiple regions.
Region string
_ [0]int
}
// Connect returns a kv.Store that stores key-value pairs on OpenStack Barbican.
func (s *OpenStackBarbicanKeyStore) Connect(ctx context.Context) (kv.Store[string, []byte], error) {
creds := gophercloud.AuthOptions{
IdentityEndpoint: s.AuthUrl,
Username: s.Username,
Password: s.Password,
DomainID: s.UserDomain,
TenantName: s.ProjectName,
}
endpointOpts := gophercloud.EndpointOpts{
Type: "key-manager",
Name: s.ServiceName,
Region: s.Region,
}
return openstack.Connect(ctx, creds, endpointOpts)
}